GIOP_Message_Generator_Parser_10.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #include "tao/GIOP_Message_Generator_Parser_10.h"
00004 #include "tao/GIOP_Utils.h"
00005 #include "tao/GIOP_Message_Locate_Header.h"
00006 #include "tao/operation_details.h"
00007 #include "tao/debug.h"
00008 #include "tao/Pluggable_Messaging_Utils.h"
00009 #include "tao/TAO_Server_Request.h"
00010 #include "tao/ORB_Constants.h"
00011 #include "tao/CDR.h"
00012 #include "tao/SystemException.h"
00013 
00014 #include "ace/Log_Msg.h"
00015 
00016 ACE_RCSID (tao,
00017            GIOP_Message_Generator_Parser_10,
00018            "$Id: GIOP_Message_Generator_Parser_10.cpp 78165 2007-04-24 09:25:23Z johnnyw $")
00019 
00020 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 bool
00023 TAO_GIOP_Message_Generator_Parser_10::write_request_header (
00024     const TAO_Operation_Details &opdetails,
00025     TAO_Target_Specification &spec,
00026     TAO_OutputCDR &msg)
00027 {
00028   // Write the service context list
00029   msg << opdetails.request_service_info ();
00030 
00031   // The request ID
00032   msg << opdetails.request_id ();
00033 
00034   CORBA::Octet const response_flags = opdetails.response_flags ();
00035 
00036   // Write the response flags
00037   if (response_flags == TAO_TWOWAY_RESPONSE_FLAG)
00038     {
00039       msg << ACE_OutputCDR::from_octet (1);
00040     }
00041   else
00042     {
00043       msg << ACE_OutputCDR::from_octet (0);
00044     }
00045 
00046   // In this case we cannot recognise anything other than the Object
00047   // key as the address disposition variable. But we do a sanity check
00048   // anyway.
00049   const TAO::ObjectKey *key = spec.object_key ();
00050 
00051   if (key)
00052     {
00053       // Put in the object key
00054       msg << *key;
00055     }
00056   else
00057     {
00058       if (TAO_debug_level)
00059         {
00060           ACE_ERROR ((LM_ERROR,
00061                       ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00062         }
00063       return false;
00064     }
00065 
00066   msg.write_string (opdetails.opname_len (), opdetails.opname ());
00067 
00068   // Last element of request header is the principal; no portable way
00069   // to get it, we just pass empty principal (convention: indicates
00070   // "anybody").  Steps upward in security include passing an
00071   // unverified user ID, and then verifying the message (i.e. a dummy
00072   // service context entry is set up to hold a digital signature for
00073   // this message, then patched shortly before it's sent).
00074 
00075   /***** This has been deprecated in the 2.4 spec ******/
00076 
00077 #if defined (TAO_PEER_REQUIRES_PRINCIPAL)
00078 
00079   char username[BUFSIZ];
00080   char *result =
00081     ACE_OS::cuserid (username,
00082                      BUFSIZ);
00083 
00084   if (result != 0)
00085     {
00086       const CORBA::ULong username_size =
00087         static_cast<CORBA::ULong> (ACE_OS::strlen (username));
00088 
00089       CORBA::Octet *buffer =
00090         CORBA::OctetSeq::allocbuf (username_size + 1);
00091 
00092       ACE_OS::memcpy (buffer,
00093                       username,
00094                       username_size + 1);
00095 
00096       req_principal.replace (username_size + 1,
00097                              username_size + 1,
00098                              buffer,
00099                              1);
00100     }
00101 
00102 #else
00103 
00104   CORBA::OctetSeq req_principal (0);
00105   req_principal.length (0);
00106 
00107 #endif /* TAO_PEER_REQUIRES_PRINCIPAL */
00108 
00109   msg << req_principal;
00110 
00111   return true;
00112 }
00113 
00114 bool
00115 TAO_GIOP_Message_Generator_Parser_10::write_locate_request_header (
00116     CORBA::ULong request_id,
00117     TAO_Target_Specification  &spec,
00118     TAO_OutputCDR &msg)
00119 {
00120   msg << request_id;
00121 
00122   // In this case we cannot recognise anything other than the Object
00123   // key as the address disposition variable. But we do a sanity check
00124   // anyway.
00125   const TAO::ObjectKey *key = spec.object_key ();
00126 
00127   if (key)
00128     {
00129       // Everything is fine
00130       msg << *key;
00131     }
00132   else
00133     {
00134       if (TAO_debug_level)
00135         {
00136           ACE_ERROR ((LM_ERROR,
00137                       ACE_TEXT ("(%N | %l) Unable to handle this request\n")));
00138         }
00139       return false;
00140     }
00141 
00142   return true;
00143 }
00144 
00145 bool
00146 TAO_GIOP_Message_Generator_Parser_10::write_reply_header (
00147     TAO_OutputCDR &output,
00148     TAO_Pluggable_Reply_Params_Base &reply)
00149 {
00150   // Write the service context list.
00151 #if (TAO_HAS_MINIMUM_CORBA == 1)
00152   output << reply.service_context_notowned ();
00153 #else
00154   if (reply.is_dsi_ == false)
00155     {
00156       output << reply.service_context_notowned ();
00157     }
00158   else
00159     {
00160       // If lazy evaluation is enabled then we are going to insert an
00161       // extra node at the end of the service context list, just to
00162       // force the appropriate padding.
00163       // But first we take it out any of them..
00164       CORBA::ULong count = 0;
00165       IOP::ServiceContextList &svc_ctx =
00166         reply.service_context_notowned ();
00167       CORBA::ULong const l = svc_ctx.length ();
00168       CORBA::ULong i;
00169 
00170       for (i = 0; i != l; ++i)
00171         {
00172           if (svc_ctx[i].context_id == TAO_SVC_CONTEXT_ALIGN)
00173             {
00174               continue;
00175             }
00176 
00177           ++count;
00178         }
00179 
00180       // Now increment it to account for the last dummy one...
00181       ++count;
00182 
00183       // Now marshal the rest of the service context objects
00184       output << count;
00185       for (i = 0; i != l; ++i)
00186         {
00187           if (svc_ctx[i].context_id == TAO_SVC_CONTEXT_ALIGN)
00188             {
00189               continue;
00190             }
00191 
00192           output << svc_ctx[i];
00193         }
00194 
00195     }
00196 
00197   if (reply.is_dsi_ == true)
00198     {
00199       // @@ Much of this code is GIOP 1.1 specific and should be
00200       ptrdiff_t target = reply.dsi_nvlist_align_;
00201 
00202       ptrdiff_t const current =
00203         ptrdiff_t (output.current_alignment ()) % ACE_CDR::MAX_ALIGNMENT;
00204 
00205       CORBA::ULong pad = 0;
00206 
00207       if (target == 0)
00208         {
00209           // We want to generate adequate padding to start the request
00210           // id on a 8 byte boundary, two cases:
00211           // - If the dummy tag starts on a 4 byte boundary and the
00212           //   dummy sequence has 0 elements then we have:
00213           //   4:tag 8:sequence_length 4:sequence_body 4:request_id
00214           //   8:payload
00215           // - If the dummy tag starts on an 8 byte boundary, with 4
00216           //   elements we get:
00217           //   8:tag 4:sequence_length 8:sequence_body 4:request_id
00218           //   8:payload
00219           if (current != 0 && current <= ACE_CDR::LONG_ALIGN)
00220             {
00221               pad = 4;
00222             }
00223         }
00224       else if (target != ACE_CDR::LONG_ALIGN)
00225         {
00226           // The situation reverses, we want to generate adequate
00227           // padding to start the request id on a 4 byte boundary, two
00228           // cases:
00229           // - If the dummy tag starts on a 4 byte boundary and the
00230           //   dummy sequence has 4 elements then we have:
00231           //   4:tag 8:sequence_length 4:sequence_body 8:request_id
00232           //   4:payload
00233           // - If the dummy tag starts on an 8 byte boundary, with 0
00234           //   elements we get:
00235           //   8:tag 4:sequence_length 8:sequence_body 8:request_id
00236           //   4:payload
00237           if (current > ACE_CDR::LONG_ALIGN)
00238             {
00239               pad = 4;
00240             }
00241         }
00242       else if (target == ACE_CDR::MAX_ALIGNMENT)
00243         {
00244           pad = 0;
00245         }
00246       else
00247         {
00248           // <target> can only have the values above
00249           throw ::CORBA::MARSHAL ();
00250         }
00251 
00252       output << CORBA::ULong (TAO_SVC_CONTEXT_ALIGN);
00253       output << pad;
00254 
00255       for (CORBA::ULong j = 0; j != pad; ++j)
00256         {
00257           output << ACE_OutputCDR::from_octet(0);
00258         }
00259     }
00260 #endif /* TAO_HAS_MINIMUM_CORBA */
00261 
00262   // Write the request ID
00263   output.write_ulong (reply.request_id_);
00264 
00265   // Write the reply status
00266   this->marshal_reply_status (output,
00267                               reply);
00268 
00269   return true;
00270 }
00271 
00272 
00273 bool
00274 TAO_GIOP_Message_Generator_Parser_10::write_locate_reply_mesg (
00275     TAO_OutputCDR &output,
00276     CORBA::ULong request_id,
00277     TAO_GIOP_Locate_Status_Msg &status_info)
00278 {
00279   // Make the header for the locate request
00280   output.write_ulong (request_id);
00281   output.write_ulong (status_info.status);
00282 
00283   if (status_info.status == TAO_GIOP_OBJECT_FORWARD)
00284     {
00285       CORBA::Object_ptr object_ptr =
00286         status_info.forward_location_var.in ();
00287 
00288       if ((output << object_ptr) == false)
00289         {
00290           if (TAO_debug_level > 0)
00291             {
00292               ACE_ERROR ((
00293                   LM_ERROR,
00294                   ACE_TEXT ("TAO (%P|%t|%N|%l) write_locate_reply_mesg-")
00295                   ACE_TEXT (" cannot marshal object reference\n")
00296                 ));
00297             }
00298           return false;
00299         }
00300     }
00301 
00302   return true;
00303 }
00304 
00305 bool
00306 TAO_GIOP_Message_Generator_Parser_10::write_fragment_header (
00307   TAO_OutputCDR & /* cdr */,
00308   CORBA::ULong /* request_id */)
00309 {
00310   // GIOP fragments are not supported in GIOP 1.0.
00311   return false;
00312 }
00313 
00314 
00315 int
00316 TAO_GIOP_Message_Generator_Parser_10::parse_request_header (
00317     TAO_ServerRequest &request)
00318 {
00319   // Tear out the service context ... we currently ignore it, but it
00320   // should probably be passed to each ORB service as appropriate
00321   // (e.g. transactions, security).
00322   //
00323   // NOTE: As security support kicks in, this is a good place to
00324   // verify a digital signature, if that is required in this security
00325   // environment.  It may be required even when using IPSEC security
00326   // infrastructure.
00327 
00328   // Get the input CDR in the request class
00329   TAO_InputCDR & input = *request.incoming ();
00330 
00331   IOP::ServiceContextList &service_info =
00332     request.request_service_info ();
00333 
00334   if ( ! (input >> service_info))
00335     return -1;
00336 
00337   CORBA::Boolean hdr_status =
00338     (CORBA::Boolean) input.good_bit ();
00339 
00340   CORBA::ULong req_id = 0;
00341 
00342   // Get the rest of the request header ...
00343   hdr_status = hdr_status && input.read_ulong (req_id);
00344 
00345   request.request_id (req_id);
00346 
00347   CORBA::Octet response_flags = CORBA::Octet();
00348   hdr_status = hdr_status && input.read_octet (response_flags);
00349   request.response_expected ((response_flags != 0));
00350 
00351   // This is not supported now in GIOP 1.1
00352   request.sync_with_server (0);
00353 
00354   // We use ad-hoc demarshalling here: there is no need to increase
00355   // the reference count on the CDR message block, because this key
00356   // will not outlive the request (or the message block).
00357 
00358   hdr_status =
00359     hdr_status && request.profile ().unmarshall_object_key (input);
00360 
00361   // According to the CORBA 2.6.1 (and older) specification, the operation
00362   // name is an IDL Identifier. Identifiers must be composed of ASCII letters,
00363   // numbers, and underscores, starting with a letter. Based on this, and
00364   // the fact that I could find no text explicitly requiring operation name
00365   // translation, nor could others in the CORBA community, the operation name
00366   // will not be translated regardless of the translation of other strings.
00367   //
00368   CORBA::ULong length = 0;
00369   hdr_status = hdr_status && input.read_ulong (length);
00370 
00371   if (hdr_status)
00372     {
00373       // Do not include NULL character at the end.
00374       // @@ This is not getting demarshaled using the codeset
00375       //    translators!
00376 
00377       // Notice that there are no memory allocations involved
00378       // here!
00379       request.operation (input.rd_ptr (),
00380                          length - 1,
00381                          0 /* TAO_ServerRequest does NOT own string */);
00382       hdr_status = input.skip_bytes (length);
00383     }
00384 
00385   if (hdr_status)
00386     {
00387       /**** This has been deprecated in 2.4 ****/
00388       /*CORBA::Principal_var principal;
00389 
00390       input >> principal.out ();
00391 
00392       request.requesting_principal (principal.in ()); */
00393 
00394       CORBA::OctetSeq oct_seq;
00395       input >> oct_seq;
00396       request.requesting_principal (oct_seq);
00397       hdr_status = (CORBA::Boolean) input.good_bit ();
00398     }
00399 
00400 
00401   return hdr_status ? 0 : -1;
00402 }
00403 
00404 
00405 
00406 int
00407 TAO_GIOP_Message_Generator_Parser_10::parse_locate_header (
00408     TAO_GIOP_Locate_Request_Header &request)
00409 {
00410   // Get the stream
00411   TAO_InputCDR &msg = request.incoming_stream ();
00412 
00413   CORBA::Boolean hdr_status = true;
00414 
00415   // Get the request id
00416   CORBA::ULong req_id = 0;
00417   hdr_status = msg.read_ulong (req_id);
00418 
00419   // Store it in the Locate request classes
00420   request.request_id (req_id);
00421 
00422   // Get the object key
00423   hdr_status = hdr_status && request.profile ().unmarshall_object_key (msg);
00424 
00425   return hdr_status ? 0 : -1;
00426 }
00427 
00428 
00429 
00430 int
00431 TAO_GIOP_Message_Generator_Parser_10::parse_reply (
00432     TAO_InputCDR &cdr,
00433     TAO_Pluggable_Reply_Params &params)
00434 {
00435   // Read the service context list first
00436   if ( ! (cdr >> params.svc_ctx_))
00437     {
00438       if (TAO_debug_level > 0)
00439         {
00440           ACE_ERROR ((LM_ERROR,
00441                       ACE_TEXT ("TAO (%P|%t) parse_reply, ")
00442                       ACE_TEXT ("extracting context\n")));
00443         }
00444       return -1;
00445     }
00446 
00447   // Call the base class for further processing
00448   if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr,
00449                                                       params) == -1)
00450     return -1;
00451 
00452   return 0;
00453 }
00454 
00455 
00456 int
00457 TAO_GIOP_Message_Generator_Parser_10::parse_locate_reply (
00458     TAO_InputCDR &cdr,
00459     TAO_Pluggable_Reply_Params &params)
00460 {
00461   if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr,
00462                                                              params) == -1)
00463 
00464     return -1;
00465 
00466   return 0;
00467 }
00468 
00469 CORBA::Octet
00470 TAO_GIOP_Message_Generator_Parser_10::major_version (void) const
00471 {
00472   // Any harm in hardcoding??
00473   return static_cast<CORBA::Octet> (1);
00474 }
00475 
00476 CORBA::Octet
00477 TAO_GIOP_Message_Generator_Parser_10::minor_version (void) const
00478 {
00479   // Any harm in hardcoding??
00480   return 0;
00481 }
00482 
00483 size_t
00484 TAO_GIOP_Message_Generator_Parser_10::fragment_header_length (void) const
00485 {
00486   return 0;
00487 }
00488 
00489 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:07:32 2008 for TAO by doxygen 1.3.6