(file) Return to WsmRequestDecoder.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / WsmServer

   1 martin 1.5 //%LICENSE////////////////////////////////////////////////////////////////
   2 martin 1.6 //
   3 martin 1.5 // Licensed to The Open Group (TOG) under one or more contributor license
   4            // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
   5            // this work for additional information regarding copyright ownership.
   6            // Each contributor licenses this file to you under the OpenPegasus Open
   7            // Source License; you may not use this file except in compliance with the
   8            // License.
   9 martin 1.6 //
  10 martin 1.5 // Permission is hereby granted, free of charge, to any person obtaining a
  11            // copy of this software and associated documentation files (the "Software"),
  12            // to deal in the Software without restriction, including without limitation
  13            // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  14            // and/or sell copies of the Software, and to permit persons to whom the
  15            // Software is furnished to do so, subject to the following conditions:
  16 martin 1.6 //
  17 martin 1.5 // The above copyright notice and this permission notice shall be included
  18            // in all copies or substantial portions of the Software.
  19 martin 1.6 //
  20 martin 1.5 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21 martin 1.6 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22 martin 1.5 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  23            // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  24            // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25            // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26            // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27 martin 1.6 //
  28 martin 1.5 //////////////////////////////////////////////////////////////////////////
  29 kumpf  1.2 //
  30            //%////////////////////////////////////////////////////////////////////////////
  31            
  32            #include <cctype>
  33            #include <cstdio>
  34            #include <Pegasus/Common/Config.h>
  35            #include <Pegasus/Common/XmlParser.h>
  36            #include <Pegasus/Common/Tracer.h>
  37            #include <Pegasus/Common/CommonUTF.h>
  38            #include <Pegasus/Common/MessageLoader.h>
  39            #include <Pegasus/Common/AutoPtr.h>
  40 mike   1.12 #include <Pegasus/Common/SharedPtr.h>
  41 rohini.deshpande 1.15 #include <Pegasus/IndicationService/IndicationConstants.h>
  42 kumpf            1.2  
  43                       #include "WsmConstants.h"
  44                       #include "WsmReader.h"
  45                       #include "WsmWriter.h"
  46                       #include "WsmProcessor.h"
  47                       #include "WsmRequestDecoder.h"
  48                       
  49                       PEGASUS_NAMESPACE_BEGIN
  50                       
  51 mike             1.12 static bool _parseInvokeAction(
  52                           const String& action,
  53                           String& className,
  54                           String& methodName)
  55                       {
  56                           // Parse the action as though it is a method invocation. If so, set
  57                           // className and methodName and return true. Else return false. Invoke
  58                           // actions have the following form:
  59                           //
  60                           //     http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/<CLASS>/<METHOD>
  61                       
  62                           // Expect "http://" prefix.
  63                       
  64                           CString cstr = action.getCString();
  65                           const char* p = cstr;
  66                       
  67                           if (strncmp(p, "http://", 7) != 0)
  68                               return false;
  69                       
  70                           p += 7;
  71                       
  72 mike             1.12     // Find slash that terminates the host name.
  73                       
  74                           if (!(p = strchr(p, '/')))
  75                               return false;
  76                       
  77                           p++;
  78                       
  79                           // Expect "wbem/wscim/1/cim-schema/2/" sequence.
  80                       
  81                           if (strncmp(p, "wbem/wscim/1/cim-schema/2/", 26) != 0)
  82                               return false;
  83                       
  84                           p += 26;
  85                       
  86                           // Get classname:
  87                       
  88                           char* slash = strchr(const_cast<char*>(p), '/');
  89                       
  90                           if (!slash)
  91                               return false;
  92                       
  93 mike             1.12     *slash = '\0';
  94                           className = p;
  95                           *slash = '/';
  96                           p = slash + 1;
  97                       
  98                           // Get methodname:
  99                       
 100                           methodName = p;
 101                       
 102                           // If we got this far, then action refers to a method.
 103                           return true;
 104                       }
 105                       
 106 kumpf            1.2  WsmRequestDecoder::WsmRequestDecoder(WsmProcessor* wsmProcessor)
 107 sahana.prabhakar 1.11     : MessageQueue(PEGASUS_QUEUENAME_WSMREQDECODER),
 108 kumpf            1.2        _wsmProcessor(wsmProcessor),
 109                             _serverTerminating(false)
 110                       {
 111                       }
 112                       
 113                       WsmRequestDecoder::~WsmRequestDecoder()
 114                       {
 115                       }
 116                       
 117                       void WsmRequestDecoder::sendResponse(
 118                           Uint32 queueId,
 119                           Buffer& message,
 120                           Boolean httpCloseConnect)
 121                       {
 122                           MessageQueue* queue = MessageQueue::lookup(queueId);
 123                       
 124                           if (queue)
 125                           {
 126                               AutoPtr<HTTPMessage> httpMessage(new HTTPMessage(message));
 127                               httpMessage->setCloseConnect(httpCloseConnect);
 128                               queue->enqueue(httpMessage.release());
 129 kumpf            1.2      }
 130                       }
 131                       
 132                       void WsmRequestDecoder::sendHttpError(
 133                           Uint32 queueId,
 134                           const String& status,
 135                           const String& cimError,
 136                           const String& pegasusError,
 137                           Boolean httpCloseConnect)
 138                       {
 139                           Buffer message;
 140                           message = WsmWriter::formatHttpErrorRspMessage(
 141                               status,
 142                               cimError,
 143                               pegasusError);
 144                       
 145                           sendResponse(queueId, message, httpCloseConnect);
 146                       }
 147                       
 148                       void WsmRequestDecoder::handleEnqueue(Message* message)
 149                       {
 150 kumpf            1.2      PEGASUS_ASSERT(message);
 151                           PEGASUS_ASSERT(message->getType() == HTTP_MESSAGE);
 152                       
 153                           handleHTTPMessage((HTTPMessage*)message);
 154                       
 155                           delete message;
 156                       }
 157                       
 158                       void WsmRequestDecoder::handleEnqueue()
 159                       {
 160                           Message* message = dequeue();
 161                           if (message)
 162                               handleEnqueue(message);
 163                       }
 164                       
 165                       //-----------------------------------------------------------------------------
 166                       //
 167                       // From the HTTP/1.1 Specification (RFC 2626):
 168                       //
 169                       // Both types of message consist of a start-line, zero or more header fields
 170                       // (also known as "headers"), an empty line (i.e., a line with nothing
 171 kumpf            1.2  // preceding the CRLF) indicating the end of the header fields, and possibly
 172                       // a message-body.
 173                       //
 174                       //-----------------------------------------------------------------------------
 175                       void WsmRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
 176                       {
 177                           PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmRequestDecoder::handleHTTPMessage()");
 178                       
 179                           // Set the Accept-Language into the thread for this service.
 180                           // This will allow all code in this thread to get
 181                           // the languages for the messages returned to the client.
 182                           Thread::setLanguages(httpMessage->acceptLanguages);
 183                       
 184                           // Save queueId:
 185                           Uint32 queueId = httpMessage->queueId;
 186                       
 187                           // Save userName and authType:
 188                           String userName;
 189                           String authType;
 190                           Boolean httpCloseConnect = httpMessage->getCloseConnect();
 191                       
 192 marek            1.3      PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL4,
 193 kumpf            1.2          "WsmRequestDecoder::handleHTTPMessage()- "
 194                                   "httpMessage->getCloseConnect() returned %d",
 195                               httpCloseConnect));
 196                       
 197                           userName = httpMessage->authInfo->getAuthenticatedUser();
 198                           authType = httpMessage->authInfo->getAuthType();
 199                       
 200                           // Parse the HTTP message:
 201                           String startLine;
 202                           Array<HTTPHeader> headers;
 203                           char* content;
 204                           Uint32 contentLength;
 205                       
 206                           httpMessage->parse(startLine, headers, contentLength);
 207                       
 208                           // Parse the request line:
 209                           String methodName;
 210                           String requestUri;
 211                           String httpVersion;
 212                           HttpMethod httpMethod = HTTP_METHOD__POST;
 213                       
 214 kumpf            1.2      HTTPMessage::parseRequestLine(
 215                               startLine, methodName, requestUri, httpVersion);
 216                       
 217                           //  Set HTTP method for the request
 218                           if (methodName == "M-POST")
 219                           {
 220                               httpMethod = HTTP_METHOD_M_POST;
 221                           }
 222                       
 223                           // Unsupported methods are caught in the HTTPAuthenticatorDelegator
 224                           PEGASUS_ASSERT(methodName == "M-POST" || methodName == "POST");
 225                       
 226                           //  Mismatch of method and version is caught in HTTPAuthenticatorDelegator
 227                           PEGASUS_ASSERT(!((httpMethod == HTTP_METHOD_M_POST) &&
 228                                            (httpVersion == "HTTP/1.0")));
 229                       
 230                           // Process M-POST and POST messages:
 231                           if (httpVersion == "HTTP/1.1")
 232                           {
 233                               // Validate the presence of a "Host" header.  The HTTP/1.1
 234                               // specification says this in section 14.23 regarding the Host
 235 kumpf            1.2          // header field:
 236                               //
 237                               //     All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad
 238                               //     Request) status code to any HTTP/1.1 request message which lacks
 239                               //     a Host header field.
 240                               //
 241                               // Note:  The Host header value is not validated.
 242                       
 243 kumpf            1.8          const char* hostHeader;
 244 kumpf            1.2          Boolean hostHeaderFound = HTTPMessage::lookupHeader(
 245                                   headers, "Host", hostHeader, false);
 246                       
 247                               if (!hostHeaderFound)
 248                               {
 249                                   MessageLoaderParms parms(
 250                                       "Server.WsmRequestDecoder.MISSING_HOST_HEADER",
 251                                       "HTTP request message lacks a Host header field.");
 252                                   sendHttpError(
 253                                       queueId,
 254                                       HTTP_STATUS_BADREQUEST,
 255                                       "",
 256                                       MessageLoader::getMessage(parms),
 257                                       httpCloseConnect);
 258                                   PEG_METHOD_EXIT();
 259                                   return;
 260                               }
 261                           }
 262                       
 263                           // Calculate the beginning of the content from the message size and
 264                           // the content length.
 265 kumpf            1.2      content = (char*) httpMessage->message.getData() +
 266                               httpMessage->message.size() - contentLength;
 267                       
 268 mike             1.12     // Lookup HTTP "User-Agent" header. For example:
 269                           //
 270                           //     User-Agent: Microsoft WinRM Client
 271                           //
 272                           // If it contains "WinRM", then omit the XML processing instruction from
 273                           // the response (first line of XML response). A typical XML processing
 274                           // instruction looks like this:
 275                           //
 276                           //     <?xml version="1.0" encoding="utf-8"?>
 277                           //
 278                           // The WinRM user agent should never receive this line.
 279                       
 280                           Boolean omitXMLProcessingInstruction;
 281                           {
 282                               String value;
 283                       
 284                               if (HTTPMessage::lookupHeader(headers, "User-Agent", value, true) &&
 285                                   value.find("WinRM") != Uint32(-1))
 286                               {
 287                                   omitXMLProcessingInstruction = true;
 288                               }
 289 mike             1.12         else
 290                               {
 291                                   omitXMLProcessingInstruction = false;
 292                               }
 293                           }
 294                       
 295 kumpf            1.2      // Validate the "Content-Type" header:
 296 kumpf            1.8      const char* contentType;
 297 kumpf            1.2      Boolean contentTypeHeaderFound = HTTPMessage::lookupHeader(
 298                               headers, "Content-Type", contentType, true);
 299                           String type;
 300                           String charset;
 301                       
 302                           if (!contentTypeHeaderFound ||
 303                               !HTTPMessage::parseContentTypeHeader(contentType, type, charset) ||
 304                               (!String::equalNoCase(type, "application/soap+xml") &&
 305                                !String::equalNoCase(type, "text/xml")))
 306                           {
 307                               MessageLoaderParms parms(
 308                                   "Server.WsmRequestDecoder.CONTENTTYPE_SYNTAX_ERROR",
 309                                   "HTTP Content-Type header error.");
 310                               sendHttpError(
 311                                   queueId,
 312                                   HTTP_STATUS_BADREQUEST,
 313                                   "",
 314                                   MessageLoader::getMessage(parms),
 315                                   httpCloseConnect);
 316                               PEG_METHOD_EXIT();
 317                               return;
 318 kumpf            1.2      }
 319                       
 320 mike             1.12     if (String::equalNoCase(charset, "utf-16"))
 321                           {
 322                               // Reject utf-16 requests.
 323                               WsmFault fault(
 324                                   WsmFault::wsman_EncodingLimit,
 325                                   "UTF-16 is not supported; Please use UTF-8",
 326                                   ContentLanguageList(),
 327                                   WSMAN_FAULTDETAIL_CHARACTERSET);
 328                                _wsmProcessor->sendResponse(new WsmFaultResponse(
 329                                    String::EMPTY, queueId, httpMethod, httpCloseConnect,
 330                                       omitXMLProcessingInstruction, fault));
 331                                PEG_METHOD_EXIT();
 332                                return;
 333                           }
 334                       
 335 kumpf            1.2      if (!String::equalNoCase(charset, "utf-8"))
 336                           {
 337                               // DSP0226 R13.1-5:  A service shall emit Responses using the same
 338                               // encoding as the original request. If the service does not support
 339                               // the requested encoding or cannot determine the encoding, it should
 340                               // use UTF-8 encoding to return a wsman:EncodingLimit fault with the
 341                               // following detail code:
 342                               // http://schemas.dmtf.org/wbem/wsman/1/wsman/faultDetail/CharacterSet
 343                       
 344                               WsmFault fault(
 345                                   WsmFault::wsman_EncodingLimit,
 346                                   String::EMPTY,
 347                                   ContentLanguageList(),
 348                                   WSMAN_FAULTDETAIL_CHARACTERSET);
 349                                _wsmProcessor->sendResponse(new WsmFaultResponse(
 350 mike             1.12               String::EMPTY, queueId, httpMethod, httpCloseConnect,
 351                                     omitXMLProcessingInstruction, fault));
 352 kumpf            1.2           PEG_METHOD_EXIT();
 353                                return;
 354                           }
 355                       
 356                           // SoapAction header is optional, but if present, it must match
 357                           // the content of <wsa:Action>
 358                           String soapAction;
 359                           HTTPMessage::lookupHeader(headers, "SOAPAction", soapAction, true);
 360                       
 361                           // Remove the quotes around the SOAPAction value
 362                           if ((soapAction.size() > 1) &&
 363                               (soapAction[0] == '\"') &&
 364                               (soapAction[soapAction.size()-1] == '\"'))
 365                           {
 366                               soapAction = soapAction.subString(1, soapAction.size() - 2);
 367                           }
 368                       
 369                           // Validating content falls within UTF8
 370                           // (required to be compliant with section C12 of Unicode 4.0 spec,
 371                           // chapter 3.)
 372                           Uint32 count = 0;
 373 kumpf            1.2      while (count < contentLength)
 374                           {
 375                               if (!(isUTF8((char*) &content[count])))
 376                               {
 377                                   MessageLoaderParms parms(
 378                                       "Server.WsmRequestDecoder.INVALID_UTF8_CHARACTER",
 379                                       "Invalid UTF-8 character detected.");
 380                                   sendHttpError(
 381                                       queueId,
 382                                       HTTP_STATUS_BADREQUEST,
 383                                       "request-not-valid",
 384                                       MessageLoader::getMessage(parms),
 385                                       httpCloseConnect);
 386                       
 387                                   PEG_METHOD_EXIT();
 388                                   return;
 389                               }
 390                               UTF8_NEXT(content, count);
 391                           }
 392                       
 393                           handleWsmMessage(
 394 kumpf            1.2          queueId,
 395                               httpMethod,
 396                               content,
 397                               contentLength,
 398                               soapAction,
 399                               authType,
 400                               userName,
 401                               httpMessage->ipAddress,
 402                               httpMessage->acceptLanguages,
 403                               httpMessage->contentLanguages,
 404 mike             1.12         httpCloseConnect,
 405                               omitXMLProcessingInstruction);
 406 kumpf            1.2  
 407                           PEG_METHOD_EXIT();
 408                       }
 409                       
 410                       void WsmRequestDecoder::handleWsmMessage(
 411                           Uint32 queueId,
 412                           HttpMethod httpMethod,
 413                           char* content,
 414                           Uint32 contentLength,
 415                           String& soapAction,
 416                           const String& authType,
 417                           const String& userName,
 418                           const String& ipAddress,
 419                           const AcceptLanguageList& httpAcceptLanguages,
 420                           const ContentLanguageList& httpContentLanguages,
 421 mike             1.12     Boolean httpCloseConnect,
 422                           Boolean omitXMLProcessingInstruction)
 423 kumpf            1.2  {
 424                           PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmRequestDecoder::handleWsmMessage()");
 425                       
 426 mike             1.12 
 427 kumpf            1.2      // If CIMOM is shutting down, return "Service Unavailable" response
 428                           if (_serverTerminating)
 429                           {
 430                               MessageLoaderParms parms(
 431                                   "Server.WsmRequestDecoder.CIMSERVER_SHUTTING_DOWN",
 432                                   "CIM Server is shutting down.");
 433                               sendHttpError(
 434                                   queueId,
 435                                   HTTP_STATUS_SERVICEUNAVAILABLE,
 436                                   String::EMPTY,
 437                                   MessageLoader::getMessage(parms),
 438                                   httpCloseConnect);
 439                               PEG_METHOD_EXIT();
 440                               return;
 441                           }
 442                       
 443                           WsmReader wsmReader(content);
 444                           XmlEntry entry;
 445                           AutoPtr<WsmRequest> request;
 446 rohini.deshpande 1.15     AutoPtr<WsmRequest> createFilterRequest;
 447                           AutoPtr<WsmRequest> createSubRequest;
 448                           AutoPtr<WsmRequest> deleteFilterRequest;
 449                           AutoPtr<WsmRequest> deleteHandlerRequest;
 450                           // Whether to include the filter request while processing
 451                           // Subscribe and Unsubscribe requests.
 452                           Boolean includeFilter=true;
 453 kumpf            1.2      String wsaMessageId;
 454 rohini.deshpande 1.15     String wsaAction;
 455 kumpf            1.2      // Process <?xml ... >
 456                           try
 457                           {
 458                               // These values are currently unused
 459                               const char* xmlVersion = 0;
 460                               const char* xmlEncoding = 0;
 461                       
 462                               // Note: WinRM does not send an XML declaration in its requests.
 463                               // This return value is ignored.
 464                               wsmReader.getXmlDeclaration(xmlVersion, xmlEncoding);
 465                       
 466                               // Decode the SOAP envelope
 467                       
 468                               wsmReader.expectStartTag(
 469                                   entry, WsmNamespaces::SOAP_ENVELOPE, "Envelope");
 470                       
 471                               String wsaFrom;
 472                               String wsaReplyTo;
 473                               String wsaFaultTo;
 474                               Uint32 wsmMaxEnvelopeSize = 0;
 475                               AcceptLanguageList wsmLocale;
 476 kumpf            1.2          Boolean wsmRequestEpr = false;
 477 rohini.deshpande 1.15         String wseIdentifier;
 478                               WsmEndpointReference epr;
 479 kumpf            1.4          Boolean wsmRequestItemCount = false;
 480 kumpf            1.2  
 481                               try
 482                               {
 483                                   wsmReader.decodeRequestSoapHeaders(
 484                                       wsaMessageId,
 485                                       epr.address,
 486                                       wsaAction,
 487                                       wsaFrom,
 488                                       wsaReplyTo,
 489                                       wsaFaultTo,
 490                                       epr.resourceUri,
 491                                       *epr.selectorSet,
 492                                       wsmMaxEnvelopeSize,
 493                                       wsmLocale,
 494 kumpf            1.4                  wsmRequestEpr,
 495 rohini.deshpande 1.15                 wsmRequestItemCount,
 496                                       wseIdentifier);
 497 kumpf            1.2          }
 498                               catch (XmlException&)
 499                               {
 500                                   // Do not treat this as an InvalidMessageInformationHeader fault.
 501                                   throw;
 502                               }
 503                               catch (Exception& e)
 504                               {
 505                                   throw WsmFault(
 506                                       WsmFault::wsa_InvalidMessageInformationHeader,
 507                                       e.getMessage(),
 508                                       e.getContentLanguages());
 509                               }
 510                       
 511 mike             1.12         // If no "Action" header was found, then this might still be a legal
 512                               // identify request.
 513                       
 514                               if (wsaAction.size() == 0 && _isIdentifyRequest(wsmReader))
 515                               {
 516                                   _sendIdentifyResponse(queueId);
 517                                   return;
 518                               }
 519                       
 520 kumpf            1.2          // Set the Locale language into the thread for processing this request.
 521                               Thread::setLanguages(wsmLocale);
 522                       
 523                               _checkRequiredHeader("wsa:To", epr.address.size());
 524                               _checkRequiredHeader("wsa:MessageID", wsaMessageId.size());
 525                               _checkRequiredHeader("wsa:Action", wsaAction.size());
 526                       
 527                               if (soapAction.size() && (soapAction != wsaAction))
 528                               {
 529                                   throw WsmFault(
 530                                       WsmFault::wsa_MessageInformationHeaderRequired,
 531                                       MessageLoaderParms(
 532                                           "WsmServer.WsmRequestDecoder.SOAPACTION_HEADER_MISMATCH",
 533                                           "The HTTP SOAPAction header value \"$0\" does not match "
 534                                               "the wsa:Action value \"$1\".",
 535                                           soapAction,
 536                                           wsaAction));
 537                               }
 538                       
 539                               // Note: The wsa:To header is not validated.  DSP0226 section 5.3
 540                               // indicates that this header is primarily useful for routing through
 541 kumpf            1.2          // intermediaries.  The HTTPAuthenticatorDelegator examines the path
 542                               // specified in the HTTP start line.
 543                       
 544                               // DSP0226 R5.3-1: The wsa:To header shall be present in all messages,
 545                               // whether requests, responses, or events. In the absence of other
 546                               // requirements, it is recommended that the network address for
 547                               // resources that require authentication be suffixed by the token
 548                               // sequence /wsman. If /wsman is used, unauthenticated access should
 549                               // not be allowed.
 550                               //     (1) <wsa:To> http://123.15.166.67/wsman </wsa:To>
 551                       
 552                               // DSP0226 R5.3-2: In the absence of other requirements, it is
 553                               // recommended that the network address for resources that do not
 554                               // require authentication be suffixed by the token sequence
 555                               // /wsman-anon. If /wsman-anon is used, authenticated access shall
 556                               // not be required.
 557                               //     (1) <wsa:To> http://123.15.166.67/wsman-anon </wsa:To>
 558                       
 559                               if (wsaReplyTo != WSM_ADDRESS_ANONYMOUS)
 560                               {
 561                                   // DSP0226 R5.4.2-2: A conformant service may require that all
 562 kumpf            1.2              // responses be delivered over the same connection on which the
 563                                   // request arrives.
 564                                   throw WsmFault(
 565                                       WsmFault::wsman_UnsupportedFeature,
 566                                       MessageLoaderParms(
 567                                           "WsmServer.WsmRequestDecoder.REPLYTO_ADDRESS_NOT_ANONYMOUS",
 568                                           "Responses may only be delivered over the same connection "
 569                                               "on which the request arrives."),
 570                                       WSMAN_FAULTDETAIL_ADDRESSINGMODE);
 571                               }
 572                       
 573                               if (wsaFaultTo.size() && (wsaFaultTo != WSM_ADDRESS_ANONYMOUS))
 574                               {
 575                                   // DSP0226 R5.4.3-3: A conformant service may require that all
 576                                   // faults be delivered to the client over the same transport or
 577                                   // connection on which the request arrives.
 578                                   throw WsmFault(
 579                                       WsmFault::wsman_UnsupportedFeature,
 580                                       MessageLoaderParms(
 581                                           "WsmServer.WsmRequestDecoder.FAULTTO_ADDRESS_NOT_ANONYMOUS",
 582                                           "Responses may only be delivered over the same connection "
 583 kumpf            1.2                          "on which the request arrives."),
 584                                       WSMAN_FAULTDETAIL_ADDRESSINGMODE);
 585                               }
 586                       
 587                               //
 588                               // Parse the SOAP Body while decoding each action
 589                               //
 590                       
 591 mike             1.12         String className;
 592                               String methodName;
 593                       
 594 kumpf            1.2          if (wsaAction == WSM_ACTION_GET)
 595                               {
 596                                   request.reset(_decodeWSTransferGet(
 597                                       wsmReader,
 598                                       wsaMessageId,
 599                                       epr));
 600                               }
 601                               else if (wsaAction == WSM_ACTION_PUT)
 602                               {
 603                                   request.reset(_decodeWSTransferPut(
 604                                       wsmReader,
 605                                       wsaMessageId,
 606                                       epr));
 607                               }
 608                               else if (wsaAction == WSM_ACTION_CREATE)
 609                               {
 610                                   request.reset(_decodeWSTransferCreate(
 611                                       wsmReader,
 612                                       wsaMessageId,
 613                                       epr));
 614                               }
 615 kumpf            1.2          else if (wsaAction == WSM_ACTION_DELETE)
 616                               {
 617                                   request.reset(_decodeWSTransferDelete(
 618                                       wsmReader,
 619                                       wsaMessageId,
 620                                       epr));
 621                               }
 622 kumpf            1.4          else if (wsaAction == WSM_ACTION_ENUMERATE)
 623                               {
 624                                   request.reset(_decodeWSEnumerationEnumerate(
 625                                       wsmReader,
 626                                       wsaMessageId,
 627                                       epr,
 628                                       wsmRequestItemCount));
 629                               }
 630                               else if (wsaAction == WSM_ACTION_PULL)
 631                               {
 632                                   request.reset(_decodeWSEnumerationPull(
 633                                       wsmReader,
 634                                       wsaMessageId,
 635                                       epr,
 636                                       wsmRequestItemCount));
 637                               }
 638                               else if (wsaAction == WSM_ACTION_RELEASE)
 639                               {
 640                                   request.reset(_decodeWSEnumerationRelease(
 641                                       wsmReader,
 642                                       wsaMessageId,
 643 kumpf            1.4                  epr));
 644                               }
 645 mike             1.12         else if (_parseInvokeAction(wsaAction, className, methodName))
 646                               {
 647                                   request.reset(_decodeWSInvoke(
 648                                       wsmReader,
 649                                       wsaMessageId,
 650                                       epr,
 651                                       className,
 652                                       methodName));
 653                               }
 654 rohini.deshpande 1.15         else if(wsaAction == WSM_ACTION_WSMAN_SUBSCRIBE)
 655                               {
 656                                   request.reset(_decodeWSSubscriptionRequest(
 657                                   wsmReader,
 658                                   wsaMessageId,
 659                                   epr,
 660                                   createFilterRequest,
 661                                   createSubRequest,
 662                                   includeFilter));
 663                               }
 664                               else if(wsaAction == WSM_ACTION_WSMAN_UNSUBSCRIBE)
 665                               {
 666                                   request.reset(_decodeWSUnsubscribeRequest(
 667                                   wsmReader,
 668                                   wsaMessageId,
 669                                   epr,
 670                                   wseIdentifier,
 671                                   includeFilter,
 672                                   deleteFilterRequest,
 673                                   deleteHandlerRequest));
 674                               }
 675 rohini.deshpande 1.15         else if(wsaAction == WSM_ACTION_SUBSCRIBE_RENEW)
 676                               {
 677                                   throw WsmFault(
 678                                       WsmFault::wse_UnableToRenew,
 679                                       MessageLoaderParms(
 680                                           "WsmServer.WsmRequestDecoder.UNABLE_TO_RENEW",
 681                                           "The subscription could not be renewed."));
 682                               }
 683 kumpf            1.2          else
 684                               {
 685                                   throw WsmFault(
 686                                       WsmFault::wsa_ActionNotSupported,
 687                                       MessageLoaderParms(
 688                                           "WsmServer.WsmRequestDecoder.ACTION_NOT_SUPPORTED",
 689                                           "The wsa:Action value \"$0\" is not supported.",
 690                                           wsaAction));
 691                               }
 692                       
 693                               wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Envelope");
 694                       
 695                               request->authType = authType;
 696                               request->userName = userName;
 697                               request->ipAddress = ipAddress;
 698                               request->httpMethod = httpMethod;
 699                               // Note:  The HTTP Accept-Languages header is ignored
 700                               request->acceptLanguages = wsmLocale;
 701                               request->contentLanguages = httpContentLanguages;
 702                               request->httpCloseConnect = httpCloseConnect;
 703 mike             1.12         request->omitXMLProcessingInstruction = omitXMLProcessingInstruction;
 704 kumpf            1.2          request->queueId = queueId;
 705                               request->requestEpr = wsmRequestEpr;
 706                               request->maxEnvelopeSize = wsmMaxEnvelopeSize;
 707                           }
 708                           catch (WsmFault& fault)
 709                           {
 710                               _wsmProcessor->sendResponse(new WsmFaultResponse(
 711 mike             1.12             wsaMessageId, queueId, httpMethod, httpCloseConnect,
 712                                   omitXMLProcessingInstruction, fault));
 713 kumpf            1.2          PEG_METHOD_EXIT();
 714                               return;
 715                           }
 716                           catch (SoapNotUnderstoodFault& fault)
 717                           {
 718                               _wsmProcessor->sendResponse(new SoapFaultResponse(
 719 mike             1.12             wsaMessageId, queueId, httpMethod, httpCloseConnect,
 720                                   omitXMLProcessingInstruction, fault));
 721 kumpf            1.2          PEG_METHOD_EXIT();
 722                               return;
 723                           }
 724                           catch (XmlException& e)
 725                           {
 726                               WsmFault fault(
 727                                   WsmFault::wsman_SchemaValidationError,
 728                                   e.getMessage(),
 729                                   e.getContentLanguages());
 730                               _wsmProcessor->sendResponse(new WsmFaultResponse(
 731 mike             1.12             wsaMessageId, queueId, httpMethod, httpCloseConnect,
 732                                   omitXMLProcessingInstruction, fault));
 733 kumpf            1.2          PEG_METHOD_EXIT();
 734                               return;
 735                           }
 736 marek            1.16     catch (TooManyElementsException& e)
 737                           {
 738                               WsmFault fault(
 739                                   WsmFault::wsman_EncodingLimit,
 740                                   e.getMessage(),
 741                                   e.getContentLanguages(),
 742 marek            1.17             WSMAN_FAULTDETAIL_OPTION_LIMIT);
 743 marek            1.16         _wsmProcessor->sendResponse(new WsmFaultResponse(
 744                                   wsaMessageId, queueId, httpMethod, httpCloseConnect,
 745                                   omitXMLProcessingInstruction, fault));
 746                               PEG_METHOD_EXIT();
 747                               return;
 748                           }
 749 kumpf            1.2      catch (Exception& e)
 750                           {
 751                               WsmFault fault(
 752                                   WsmFault::wsman_InternalError,
 753                                   e.getMessage(),
 754                                   e.getContentLanguages());
 755                               _wsmProcessor->sendResponse(new WsmFaultResponse(
 756 mike             1.12             wsaMessageId, queueId, httpMethod, httpCloseConnect,
 757                                   omitXMLProcessingInstruction, fault));
 758 kumpf            1.2          PEG_METHOD_EXIT();
 759                               return;
 760                           }
 761                           catch (const PEGASUS_STD(exception)& e)
 762                           {
 763                               WsmFault fault(WsmFault::wsman_InternalError, e.what());
 764                               _wsmProcessor->sendResponse(new WsmFaultResponse(
 765 mike             1.12             wsaMessageId, queueId, httpMethod, httpCloseConnect,
 766                                   omitXMLProcessingInstruction, fault));
 767 kumpf            1.2          PEG_METHOD_EXIT();
 768                               return;
 769                           }
 770                           catch (...)
 771                           {
 772                               WsmFault fault(WsmFault::wsman_InternalError);
 773                               _wsmProcessor->sendResponse(new WsmFaultResponse(
 774 mike             1.12             wsaMessageId, queueId, httpMethod, httpCloseConnect,
 775                                   omitXMLProcessingInstruction, fault));
 776 kumpf            1.2          PEG_METHOD_EXIT();
 777                               return;
 778                           }
 779 rohini.deshpande 1.15     if(wsaAction == WSM_ACTION_WSMAN_SUBSCRIBE)
 780                           {
 781                               // If a filter has to be created during subscription,
 782                               // add the filter request.
 783                               if(includeFilter)
 784                               {
 785                                   createFilterRequest.get()->copyRequestProperties(request); 
 786                                   _wsmProcessor->addReqToSubContext(createFilterRequest.release(),
 787                                       true);
 788                               }
 789                               createSubRequest.get()->copyRequestProperties(request);
 790                               _wsmProcessor->addReqToSubContext(request.get(), true);
 791                               _wsmProcessor->addReqToSubContext(createSubRequest.release(), true);
 792                           }
 793                           else if(wsaAction == WSM_ACTION_WSMAN_UNSUBSCRIBE)
 794                           {
 795                               // If the filter has to be deleted during unsubscribe,
 796                               // add the filter request.
 797                               if(includeFilter)
 798                               {
 799                                   deleteFilterRequest.get()->copyRequestProperties(request);
 800 rohini.deshpande 1.15             _wsmProcessor->addReqToSubContext(deleteFilterRequest.release(),
 801                                        false);
 802                               }   
 803                               deleteHandlerRequest.get()->copyRequestProperties(request); 
 804                               _wsmProcessor->addReqToSubContext(deleteHandlerRequest.release(), 
 805                                   false);
 806                           }
 807 kumpf            1.2      _wsmProcessor->handleRequest(request.release());
 808                       
 809                           PEG_METHOD_EXIT();
 810                       }
 811                       
 812                       void WsmRequestDecoder::_checkRequiredHeader(
 813                           const char* headerName,
 814                           Boolean headerSpecified)
 815                       {
 816                           if (!headerSpecified)
 817                           {
 818                               throw WsmFault(
 819                                   WsmFault::wsa_MessageInformationHeaderRequired,
 820                                   MessageLoaderParms(
 821                                       "WsmServer.WsmRequestDecoder.MISSING_HEADER",
 822                                       "Required SOAP header \"$0\" was not specified.",
 823                                       headerName));
 824                           }
 825                       }
 826                       
 827 kumpf            1.4  void WsmRequestDecoder::_checkNoSelectorsEPR(const WsmEndpointReference& epr)
 828                       {
 829 kumpf            1.9      // Make sure that at most __cimnamespace selector is present
 830                           if (epr.selectorSet->selectors.size())
 831 kumpf            1.4      {
 832                               if (epr.selectorSet->selectors.size() > 1 ||
 833                                   epr.selectorSet->selectors[0].type != WsmSelector::VALUE ||
 834                                   epr.selectorSet->selectors[0].name != "__cimnamespace")
 835                               {
 836                                   throw WsmFault(
 837                                       WsmFault::wsman_InvalidSelectors,
 838                                       MessageLoaderParms(
 839                                           "WsmServer.WsmRequestDecoder.UNEXPECTED_SELECTORS",
 840 kumpf            1.9                      "The operation allows only the __cimnamespace selector to "
 841 kumpf            1.4                      "be present."),
 842                                       WSMAN_FAULTDETAIL_UNEXPECTEDSELECTORS);
 843                               }
 844                           }
 845                       }
 846                       
 847                       WxfGetRequest* WsmRequestDecoder::_decodeWSTransferGet(
 848 kumpf            1.2      WsmReader& wsmReader,
 849                           const String& messageId,
 850                           const WsmEndpointReference& epr)
 851                       {
 852                           _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
 853                       
 854                           XmlEntry entry;
 855                           wsmReader.expectStartOrEmptyTag(
 856                               entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
 857                           if (entry.type != XmlEntry::EMPTY_TAG)
 858                           {
 859                               wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
 860                           }
 861                       
 862 kumpf            1.4      return new WxfGetRequest(messageId, epr);
 863 kumpf            1.2  }
 864                       
 865 kumpf            1.4  WxfPutRequest* WsmRequestDecoder::_decodeWSTransferPut(
 866 kumpf            1.2      WsmReader& wsmReader,
 867                           const String& messageId,
 868                           const WsmEndpointReference& epr)
 869                       {
 870                           _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
 871                       
 872                           XmlEntry entry;
 873                           wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
 874                       
 875                           // The soap body must contain an XML representation of the updated instance
 876                           WsmInstance instance;
 877                           wsmReader.getInstanceElement(instance);
 878                       
 879                           wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
 880                       
 881 kumpf            1.4      return new WxfPutRequest(messageId, epr, instance);
 882 kumpf            1.2  }
 883                       
 884 kumpf            1.4  WxfCreateRequest* WsmRequestDecoder::_decodeWSTransferCreate(
 885 kumpf            1.2      WsmReader& wsmReader,
 886                           const String& messageId,
 887                           const WsmEndpointReference& epr)
 888                       {
 889                           _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
 890 kumpf            1.4      _checkNoSelectorsEPR(epr);
 891 kumpf            1.2  
 892                           XmlEntry entry;
 893                           wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
 894                       
 895                           // The soap body must contain an XML representation of the new instance
 896                           WsmInstance instance;
 897                           wsmReader.getInstanceElement(instance);
 898                       
 899                           wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
 900                       
 901 kumpf            1.4      return new WxfCreateRequest(messageId, epr, instance);
 902 kumpf            1.2  }
 903                       
 904 kumpf            1.4  WxfDeleteRequest* WsmRequestDecoder::_decodeWSTransferDelete(
 905 kumpf            1.2      WsmReader& wsmReader,
 906                           const String& messageId,
 907                           const WsmEndpointReference& epr)
 908                       {
 909                           _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
 910                       
 911                           XmlEntry entry;
 912                           wsmReader.expectStartOrEmptyTag(
 913                               entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
 914                           if (entry.type != XmlEntry::EMPTY_TAG)
 915                           {
 916                               wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
 917                           }
 918                       
 919 kumpf            1.4      return new WxfDeleteRequest(messageId, epr);
 920                       }
 921                       
 922                       WsenEnumerateRequest* WsmRequestDecoder::_decodeWSEnumerationEnumerate(
 923                           WsmReader& wsmReader,
 924                           const String& messageId,
 925                           const WsmEndpointReference& epr,
 926                           Boolean requestItemCount)
 927                       {
 928 karl             1.13     PEG_METHOD_ENTER(TRC_WSMSERVER,
 929                               "WsmRequestDecoder::_decodeWSEnumerationEnumerate()");
 930                       
 931 kumpf            1.4      _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
 932                           _checkNoSelectorsEPR(epr);
 933                       
 934                           String expiration;
 935                           WsmbPolymorphismMode polymorphismMode = WSMB_PM_UNKNOWN;
 936                           WsenEnumerationMode enumerationMode = WSEN_EM_UNKNOWN;
 937                           Boolean optimized = false;
 938                           Uint32 maxElements = 0;
 939 karl             1.13     WsmFilter wsmFilter;
 940 kumpf            1.4  
 941                           XmlEntry entry;
 942                           wsmReader.expectStartOrEmptyTag(
 943                               entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
 944                           if (entry.type != XmlEntry::EMPTY_TAG)
 945                           {
 946 kumpf            1.7          wsmReader.decodeEnumerateBody(expiration, polymorphismMode,
 947 karl             1.13             enumerationMode, optimized, maxElements, wsmFilter);
 948                       
 949 kumpf            1.4          wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
 950                           }
 951                       
 952                           // If PolymorphismMode header is not specified, set it to default
 953                           if (polymorphismMode == WSMB_PM_UNKNOWN)
 954                           {
 955 kumpf            1.7          // DSP0227, R8.1-4: A service MAY optionally support the
 956                               // wsmb:PolymorphismMode modifier element with a value of
 957                               // IncludeSubClassProperties, which returns instances of the base
 958                               // class and derived classes using the actual classs GED and XSD
 959 kumpf            1.4          // type. This is the same as not specifying the polymorphism mode.
 960                               polymorphismMode = WSMB_PM_INCLUDE_SUBCLASS_PROPERTIES;
 961                           }
 962                           else
 963                           {
 964 kumpf            1.7          // DSP0227, R8.1-6: The service SHOULD also return a
 965                               // wsmb:PolymorphismModeNotSupported fault for requests using the
 966                               // all classes ResourceURI if the PolymorphismMode is present and
 967 kumpf            1.4          // does not equal IncludeSubClassProperties.
 968 mike             1.12 
 969                               CString tmp(epr.resourceUri.getCString());
 970                               const char* suffix = WsmUtils::skipHostUri(tmp);
 971                       
 972                               if (strcmp(suffix, WSM_RESOURCEURI_ALLCLASSES_SUFFIX) == 0 &&
 973 kumpf            1.4              polymorphismMode != WSMB_PM_INCLUDE_SUBCLASS_PROPERTIES)
 974                               {
 975 karl             1.13             PEG_METHOD_EXIT();
 976 kumpf            1.4              throw WsmFault(
 977                                       WsmFault::wsmb_PolymorphismModeNotSupported,
 978                                       MessageLoaderParms(
 979                                           "WsmServer.WsmReader.ENUMERATE_"
 980                                               "POLYMORPHISM_INCLUDE_SUBCLASS",
 981                                           "\"All classes\" resource URI requires "
 982                                               "IncludeSubClassProperties polymorphism mode."));
 983                               }
 984                           }
 985                       
 986                           // If EnumerationMode header is not specified, set it to default
 987                           if (enumerationMode == WSEN_EM_UNKNOWN)
 988                           {
 989                               enumerationMode = WSEN_EM_OBJECT;
 990                           }
 991                       
 992                           // If optimized enumeration is requested but maxElements is not specified,
 993                           // set it to default value of 1.
 994                           if (optimized && maxElements == 0)
 995                           {
 996                               maxElements = 1;
 997 kumpf            1.4      }
 998                       
 999 karl             1.14     PEG_METHOD_EXIT();
1000                       
1001 kumpf            1.4      return new WsenEnumerateRequest(
1002 kumpf            1.7          messageId,
1003                               epr,
1004                               expiration,
1005                               requestItemCount,
1006                               optimized,
1007                               maxElements,
1008                               enumerationMode,
1009 mike             1.12         polymorphismMode,
1010 karl             1.13         wsmFilter);
1011 kumpf            1.4  }
1012                       
1013                       WsenPullRequest* WsmRequestDecoder::_decodeWSEnumerationPull(
1014                           WsmReader& wsmReader,
1015                           const String& messageId,
1016                           const WsmEndpointReference& epr,
1017                           Boolean requestItemCount)
1018                       {
1019                           _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
1020                           _checkNoSelectorsEPR(epr);
1021                       
1022 kumpf            1.10     Uint64 enumerationContext = 0;
1023 kumpf            1.4      String maxTime;
1024                           Uint32 maxElements = 0;
1025                           Uint32 maxCharacters = 0;
1026                       
1027                           XmlEntry entry;
1028 kumpf            1.10     wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1029                           wsmReader.decodePullBody(
1030                               enumerationContext, maxTime, maxElements, maxCharacters);
1031                           wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1032 kumpf            1.4  
1033                           // If maxElements is not specified, set it to default value of 1.
1034                           if (maxElements == 0)
1035                           {
1036                               maxElements = 1;
1037                           }
1038                       
1039                           return new WsenPullRequest(
1040 kumpf            1.7          messageId,
1041                               epr,
1042 kumpf            1.4          enumerationContext,
1043                               maxTime,
1044 kumpf            1.7          requestItemCount,
1045 kumpf            1.4          maxElements,
1046                               maxCharacters);
1047                       }
1048                       
1049                       WsenReleaseRequest* WsmRequestDecoder::_decodeWSEnumerationRelease(
1050                           WsmReader& wsmReader,
1051                           const String& messageId,
1052                           const WsmEndpointReference& epr)
1053                       {
1054                           _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
1055                           _checkNoSelectorsEPR(epr);
1056                       
1057 kumpf            1.10     Uint64 enumerationContext = 0;
1058 kumpf            1.4  
1059                           XmlEntry entry;
1060 kumpf            1.10     wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1061                           wsmReader.decodeReleaseBody(enumerationContext);
1062                           wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1063 kumpf            1.4  
1064                           return new WsenReleaseRequest(
1065 kumpf            1.7          messageId,
1066                               epr,
1067 kumpf            1.4          enumerationContext);
1068 kumpf            1.2  }
1069                       
1070 mike             1.12 WsmRequest* WsmRequestDecoder::_decodeWSInvoke(
1071                           WsmReader& wsmReader,
1072                           const String& messageId,
1073                           const WsmEndpointReference& epr,
1074                           const String& className,
1075                           const String& methodName)
1076                       {
1077                           XmlEntry entry;
1078                       
1079                           //
1080                           // Parse the <s:Body> element. Here is an example:
1081                           //
1082                           //   <s:Body>
1083                           //     <p:Foo_INPUT xmlns:p=
1084                           //       "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SomeClass">
1085                           //       <p:Arg1>
1086                           //         1234
1087                           //       </p:Arg1>
1088                           //       <p:Arg2>
1089                           //         Hello!
1090                           //       </p:Arg2>
1091 mike             1.12     //     </p:Foo_INPUT>
1092                           //   </s:Body>
1093                           //
1094                       
1095                           WsmInstance instance;
1096                           wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1097                           wsmReader.decodeInvokeInputBody(className, methodName, instance);
1098                           wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1099                       
1100                           return new WsInvokeRequest(messageId, epr, className, methodName, instance);
1101                       }
1102                       
1103 rohini.deshpande 1.15 WsmRequest* WsmRequestDecoder::_decodeWSUnsubscribeRequest(
1104                           WsmReader& wsmReader,
1105                           const String& messageId,
1106                           WsmEndpointReference& epr,
1107                           const String& identifier,
1108                           Boolean & includeFilter, 
1109                           AutoPtr<WsmRequest> &deleteFilterRequest,
1110                           AutoPtr<WsmRequest> &deleteHandlerRequest)
1111                       {
1112                           PEG_METHOD_ENTER(TRC_WSMSERVER,
1113                               "WsmRequestDecoder::_decodeWSUnsubscribeRequest()");
1114                           _checkRequiredHeader("wse:Identifier", identifier.size());
1115                           XmlEntry entry;
1116                           wsmReader.expectStartOrEmptyTag(
1117                               entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1118                           if (entry.type != XmlEntry::EMPTY_TAG)
1119                           {
1120                               wsmReader.expectStartOrEmptyTag(
1121                                   entry, WsmNamespaces::WS_EVENTING, "Unsubscribe");
1122                               wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1123                           }
1124 rohini.deshpande 1.15 
1125                           WsmEndpointReference filterEPR;
1126                           String filterName;
1127                           // If existing filter is used in Subscription, do not delete the filter
1128                           if(_wsmProcessor->isSubCreatedWithExistingFilter(identifier, filterName))
1129                           {
1130                               getFilterOrHandlerEPR(filterEPR,
1131                                   epr.address,
1132                                   filterName,
1133                                   PEGASUS_CLASSNAME_INDFILTER.getString());
1134                               includeFilter = false;
1135                           }
1136                           else
1137                           {
1138                               getFilterOrHandlerEPR(filterEPR,
1139                                   epr.address,
1140                                   identifier,
1141                                   PEGASUS_CLASSNAME_INDFILTER.getString());
1142                           }
1143                       
1144                           WsmEndpointReference handlerEPR;
1145 rohini.deshpande 1.15     getFilterOrHandlerEPR(handlerEPR,
1146                               epr.address,
1147                               identifier, PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString());
1148                       
1149                           WsmEndpointReference subscriptionEPR;
1150                           subscriptionEPR.address = epr.address;
1151                           subscriptionEPR.resourceUri = String(WSM_RESOURCEURI_CIMSCHEMAV2) +
1152                               "/" + PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString();
1153                           subscriptionEPR.selectorSet->selectors.append(WsmSelector
1154 dl.meetei        1.18         (String(PEGASUS_WS_CIMNAMESPACE),
1155 rohini.deshpande 1.15         PEGASUS_NAMESPACENAME_INTEROP.getString()));
1156                           subscriptionEPR.selectorSet->selectors.append(WsmSelector
1157                               (PEGASUS_PROPERTYNAME_FILTER.getString(), filterEPR));
1158                           subscriptionEPR.selectorSet->selectors.append(WsmSelector
1159                               (PEGASUS_PROPERTYNAME_HANDLER.getString(), handlerEPR));
1160                           // DSP0227:R10.6-4 :If a service created CIM indication-related instances
1161                           // as described in 10.5, then the service shall delete those instances 
1162                           // when the subscription is canceled for any reason.
1163                           if(includeFilter)
1164                           { 
1165                               deleteFilterRequest.reset(new WxfSubDeleteRequest( messageId, 
1166                                   filterEPR, 
1167                                   PEGASUS_CLASSNAME_INDFILTER.getString()));
1168                           }
1169                           deleteHandlerRequest.reset(new WxfSubDeleteRequest( messageId, 
1170                               handlerEPR, 
1171                               PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString()));
1172                           PEG_METHOD_EXIT();
1173                           return new WxfSubDeleteRequest(messageId, 
1174                               subscriptionEPR, 
1175                               PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString());
1176 rohini.deshpande 1.15 }
1177                       
1178                       WsmRequest* WsmRequestDecoder::_decodeWSSubscriptionRequest(
1179                           WsmReader& wsmReader,
1180                           const String& messageId,
1181                           WsmEndpointReference& epr,
1182                           AutoPtr<WsmRequest> &createFilterRequest,
1183                           AutoPtr<WsmRequest> &createSubRequest,
1184                           Boolean &includeFilter)
1185                       {
1186                           PEG_METHOD_ENTER(TRC_WSMSERVER,
1187                               "WsmRequestDecoder::_decodeWSSubscriptionRequest()");
1188                           _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
1189                       
1190                           String filterName;
1191                           String deliveryMode;
1192                           String notifyTo;
1193                           String subExpiration;
1194                           XmlEntry entry;
1195                           WsmFilter wsmFilter;
1196                           // Remove the "uuid:" from messageId
1197 rohini.deshpande 1.15     String msgId = messageId.subString(PEGASUS_WS_UUID_LENGTH);
1198                       
1199                           wsmReader.expectStartOrEmptyTag(
1200                               entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1201                           if (entry.type != XmlEntry::EMPTY_TAG)
1202                           {
1203                               wsmReader.decodeSubscribeBody(
1204                                   deliveryMode,
1205                                   notifyTo,
1206                                   subExpiration,
1207                                   wsmFilter);
1208                               wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1209                           }
1210                       
1211                           // DSP0227: 10.2.1.1 - Subscribing to CIM server. 
1212                           // Resource URI is all classes
1213                           if( epr.resourceUri == WSM_RESOURCEURI_ALLCLASSES )
1214                           {
1215                               if(!wsmFilter.WQLFilter.query.size())
1216                               {
1217                                       MessageLoaderParms parms(
1218 rohini.deshpande 1.15                     "WsmServer.WsmRequestDecoder.INVALID_MESSAGE ",
1219                                           "The request message has unknown or invalid content"
1220                                           " and cannot be processed. ");
1221                                       throw WsmFault( WsmFault::wse_InvalidMessage, parms);
1222                               }
1223                           }
1224                           //DSP0227: 10.2.1.3 Subscribing to an existing filter
1225                           //Resource URI specifies existing filter
1226                           else if ( epr.resourceUri == WSM_RESOURCEURI_INDICATION_FILTER) 
1227                           {
1228                               // DSP0227:R10.2.2-2 - If a service supports filtering using an 
1229                               // existing filter expression, the service message shall return the 
1230                               // wsman:InvalidParameter fault if the wse:Subscribe request includes 
1231                               // a filter expression
1232                               if(wsmFilter.WQLFilter.query.size())
1233                               {
1234                                   throw WsmFault(
1235                                           WsmFault::wsman_InvalidParameter,
1236                                           MessageLoaderParms(
1237                                               "WsmServer.WsmRequestDecoder.INVALID_PARAMETER ",
1238                                               "An operation parameter is not valid."));
1239 rohini.deshpande 1.15         }
1240                               else
1241                               {
1242                                  for (Uint32 i = 0; i < epr.selectorSet->selectors.size(); i++)
1243                                  {
1244                                      if(String::equalNoCase(epr.selectorSet->selectors[i].name, 
1245                                             "Name"))
1246                                      {
1247                                          filterName = epr.selectorSet->selectors[i].value;
1248                                          includeFilter = false;
1249                                          break;
1250                                      }
1251                                  }
1252                               }
1253                           }
1254                           //DSP0227: 10.2.1.2 Subscribing to an indication class
1255                           else 
1256                           { 
1257                               CIMName className = WsmToCimRequestMapper::
1258                                   convertResourceUriToClassName(epr.resourceUri);
1259                               if(wsmFilter.filterDialect == WsmFilter::NONE)
1260 rohini.deshpande 1.15         {
1261                                   //If no filter query is specified, form a filter query.
1262                                   wsmFilter.filterDialect = WsmFilter::WQL;
1263                                   String query("SELECT * FROM ");
1264                                   query.append(className.getString());
1265                                   wsmFilter.WQLFilter.query = query;
1266                                   try
1267                                   {
1268                                       wsmFilter.WQLFilter.selectStatement.reset(
1269                                           new WQLSelectStatement);
1270                                       WQLParser::parse(wsmFilter.WQLFilter.query,
1271                                           *wsmFilter.WQLFilter.selectStatement.get());
1272                                   }
1273                                   catch (ParseError& e)
1274                                   {
1275                                       MessageLoaderParms parms(
1276                                           "WsmServer.WsmRequestDecoder."
1277                                           "INVALID_FILTER_QUERY_EXPRESSION",
1278                                           "Invalid filter query expression: \"$0\".",
1279                                           entry.text);
1280                                       throw WsmFault(WsmFault::wsen_CannotProcessFilter, parms);
1281 rohini.deshpande 1.15             }
1282                                   wsmFilter.WQLFilter.queryLanguage = "WQL";
1283                               }
1284                               else if(wsmFilter.filterDialect == WsmFilter::WQL)
1285                               {
1286                                   // DSP0227 - R8.1-9 : If class name in resource URI does not
1287                                   // match the class name in the filter query, then throw 
1288                                   // wse:EventSourceUnableToProcess fault.
1289                                   WQLSelectStatement *st = wsmFilter.WQLFilter.selectStatement.get();
1290                                   if(className.getString() != st->getClassName().getString())
1291                                   {
1292                                       throw WsmFault(
1293                                           WsmFault::wse_EventSourceUnableToProcess,
1294                                           MessageLoaderParms(
1295                                               "WsmServer.WsmRequestDecoder.UNABLE_TO_PROCESS ",
1296                                               "The event source cannot process the subscription."));
1297                                   }
1298                               }
1299                           }
1300                           WsmEndpointReference filterEPR;
1301                           const String creClassName(PEGASUS_PROPERTYNAME_CREATIONCLASSNAME.
1302 rohini.deshpande 1.15         getString());
1303                           const String propertyName(PEGASUS_PROPERTYNAME_NAME.getString());
1304                           WsmValue sysNameValue(System::getFullyQualifiedHostName());
1305                           WsmProperty sysNameProp("SystemName", sysNameValue);
1306                           WsmValue sysCreClassNameValue(System::getSystemCreationClassName ());
1307                           WsmProperty sysCreClassNameProp(
1308                               "SystemCreationClassName", 
1309                               sysCreClassNameValue);
1310                       
1311                           //Creating filterInstance and forming createInstace request for filter.
1312                           if ( includeFilter == true)
1313                           {
1314                               WsmInstance filterInstance;
1315                               filterInstance.setClassName(PEGASUS_CLASSNAME_INDFILTER.getString());
1316                       
1317                               filterInstance.addProperty(sysCreClassNameProp);
1318                               filterInstance.addProperty(sysNameProp);
1319                       
1320                               WsmValue filCreClassNameValue(PEGASUS_CLASSNAME_INDFILTER.getString());
1321                               WsmProperty filCreClassNameProp(creClassName, filCreClassNameValue);
1322                               filterInstance.addProperty(filCreClassNameProp);
1323 rohini.deshpande 1.15 
1324                               WsmValue filNameValue(msgId);
1325                               WsmProperty filNameProp(propertyName, filNameValue);
1326                               filterInstance.addProperty(filNameProp);
1327                               filterName = msgId;
1328                       
1329                               WsmValue queryValue(wsmFilter.WQLFilter.query);
1330                               WsmProperty queryProp(PEGASUS_PROPERTYNAME_QUERY.getString(),
1331                                   queryValue);
1332                               filterInstance.addProperty(queryProp);
1333                       
1334                               WsmValue queryLangValue(wsmFilter.WQLFilter.queryLanguage);
1335                               WsmProperty queryLangProp(PEGASUS_PROPERTYNAME_QUERYLANGUAGE.
1336                                   getString(), 
1337                                   queryLangValue);
1338                               filterInstance.addProperty(queryLangProp);
1339                       
1340                               WsmValue srcNamespaceValue(( const char *)epr.getNamespace().
1341                                   getCString() );
1342                               WsmProperty srcNamespaceProp("SourceNamespaces", srcNamespaceValue);
1343                               filterInstance.addProperty(srcNamespaceProp);
1344 rohini.deshpande 1.15         getFilterOrHandlerEPR(filterEPR, 
1345                                   epr.address, 
1346                                   filterName, 
1347                                   PEGASUS_CLASSNAME_INDFILTER.getString());
1348                               createFilterRequest.reset(new WxfSubCreateRequest(messageId, 
1349                                   filterEPR, 
1350                                   filterInstance));
1351                           }
1352                           else
1353                           {
1354                               getFilterOrHandlerEPR(filterEPR, 
1355                                   epr.address, 
1356                                   filterName, 
1357                                   PEGASUS_CLASSNAME_INDFILTER.getString());
1358                           }
1359                       
1360                           //Creating Handler Instance.
1361                           WsmInstance handlerInstance;
1362                           handlerInstance.setClassName(PEGASUS_CLASSNAME_INDHANDLER_WSMAN.
1363                               getString());
1364                           handlerInstance.addProperty(sysCreClassNameProp);
1365 rohini.deshpande 1.15     handlerInstance.addProperty(sysNameProp);
1366                           WsmValue hanCreClassNameValue(PEGASUS_CLASSNAME_INDHANDLER_WSMAN.
1367                               getString());
1368                           WsmProperty hanCreClassNameProp(creClassName, hanCreClassNameValue);
1369                           handlerInstance.addProperty(hanCreClassNameProp);
1370                       
1371                           WsmValue handlerNameValue(msgId);
1372                           WsmProperty handlerNameProp(propertyName,handlerNameValue);
1373                           handlerInstance.addProperty(handlerNameProp);
1374                       
1375                           WsmValue deliveryModeValue(deliveryMode);
1376                           WsmProperty deliveryModeProp(
1377                               PEGASUS_PROPERTYNAME_WSM_DELIVERY_MODE.getString(),
1378                               deliveryModeValue);
1379                           handlerInstance.addProperty(deliveryModeProp);
1380                       
1381                           WsmValue destValue(notifyTo);
1382                           WsmProperty destProp(PEGASUS_PROPERTYNAME_LSTNRDST_DESTINATION.getString(),
1383                               destValue);
1384                           handlerInstance.addProperty(destProp);    
1385                       
1386 rohini.deshpande 1.15     WsmEndpointReference handlerEPR;
1387                           getFilterOrHandlerEPR(handlerEPR, 
1388                               epr.address, 
1389                               msgId, 
1390                               PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString());
1391                       
1392                           //Creating Subscription Instance.
1393                           WsmInstance subscriptionInstance; 
1394                           subscriptionInstance.setClassName(
1395                               PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString());
1396                       
1397                           WsmValue subCreClassNameValue(
1398                               PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString());
1399                           WsmProperty subCreClassNameProp(creClassName, subCreClassNameValue);
1400                       
1401                           WsmValue subInfoVal(msgId);
1402                           WsmProperty subscriptionInfo(_PROPERTY_SUBSCRIPTION_INFO.getString(),
1403                                   subInfoVal);
1404                           subscriptionInstance.addProperty(subscriptionInfo); 
1405                       
1406                           WsmValue subFilterValue(filterEPR);
1407 rohini.deshpande 1.15     WsmProperty subFilterProp(PEGASUS_PROPERTYNAME_FILTER.getString(), 
1408                               subFilterValue);
1409                           subscriptionInstance.addProperty(subFilterProp);
1410                       
1411                           WsmValue subHandlerValue(handlerEPR);
1412                           WsmProperty subHandlerProp(PEGASUS_PROPERTYNAME_HANDLER.getString(), 
1413                               subHandlerValue);
1414                           subscriptionInstance.addProperty(subHandlerProp);
1415                       
1416                           if(subExpiration.size())
1417                           {
1418                               WsmValue subDurationval(subExpiration);
1419                               WsmProperty subDurationProp(PEGASUS_WS_SUB_DURATION,
1420                                   subDurationval);
1421                               subscriptionInstance.addProperty(subDurationProp);
1422                           }
1423                       
1424                           WsmEndpointReference subscriptionEPR;
1425                           subscriptionEPR.address = epr.address;
1426                           subscriptionEPR.resourceUri = String(WSM_RESOURCEURI_CIMSCHEMAV2) +
1427                               "/" + PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString();
1428 rohini.deshpande 1.15     subscriptionEPR.selectorSet->selectors.append(WsmSelector
1429 dl.meetei        1.18         (String(PEGASUS_WS_CIMNAMESPACE),
1430 rohini.deshpande 1.15         PEGASUS_NAMESPACENAME_INTEROP.getString()));
1431                           createSubRequest.reset(new WxfSubCreateRequest(messageId, 
1432                               subscriptionEPR, 
1433                               subscriptionInstance));
1434                           PEG_METHOD_EXIT();
1435                           return(new WxfSubCreateRequest(messageId, 
1436                               handlerEPR, 
1437                               handlerInstance));
1438                       }
1439                       
1440                       void WsmRequestDecoder::getFilterOrHandlerEPR(
1441                           WsmEndpointReference& instanceEPR,
1442                           const String address,
1443                           const String name,
1444                           const String className)
1445                       {
1446                           instanceEPR.address = address;
1447                           instanceEPR.resourceUri = String(WSM_RESOURCEURI_CIMSCHEMAV2) 
1448                               + "/" + className;
1449                           instanceEPR.selectorSet->selectors.append(WsmSelector
1450 dl.meetei        1.18         (String(PEGASUS_WS_CIMNAMESPACE),
1451 rohini.deshpande 1.15         PEGASUS_NAMESPACENAME_INTEROP.getString()));
1452                           instanceEPR.selectorSet->selectors.append(WsmSelector(
1453                               "SystemCreationClassName",
1454                               System::getSystemCreationClassName()));
1455                           instanceEPR.selectorSet->selectors.append(WsmSelector(
1456                               "SystemName",
1457                               System::getFullyQualifiedHostName()));
1458                           instanceEPR.selectorSet->selectors.append(WsmSelector(
1459                               PEGASUS_PROPERTYNAME_CREATIONCLASSNAME.getString(),
1460                               className));
1461                           instanceEPR.selectorSet->selectors.append(WsmSelector(
1462                               PEGASUS_PROPERTYNAME_NAME.getString(), 
1463                               name));
1464                       }
1465                       
1466 mike             1.12 bool WsmRequestDecoder::_isIdentifyRequest(WsmReader& wsmReader)
1467                       {
1468                           // Parse the <s:Body> element. Here is an example:
1469                           //
1470                           //   <s:Body>
1471                           //     <wsmid:Identify>
1472                           //   </s:Body>
1473                       
1474                           XmlEntry entry;
1475                           wsmReader.setHideEmptyTags(true);
1476                           wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1477                       
1478                           try
1479                           {
1480                               // Expect an identify element. Ignore the namespace to be more
1481                               // tolerant.
1482                               int nsType = wsmReader.expectStartTag(entry, "Identify");
1483                               wsmReader.expectEndTag(nsType, "Identify");
1484                           }
1485                           catch (...)
1486                           {
1487 mike             1.12         wsmReader.setHideEmptyTags(false);
1488                               return false;
1489                           }
1490                       
1491                           wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1492                           wsmReader.setHideEmptyTags(false);
1493                       
1494                           return true;
1495                       }
1496                       
1497                       void WsmRequestDecoder::_sendIdentifyResponse(Uint32 queueId)
1498                       {
1499                           const char HTTP[] =
1500                               "HTTP/1.1 200 OK\r\n"
1501                               "Content-Type: application/soap+xml;charset=UTF-8\r\n"
1502                               "Content-Length: ";
1503                       
1504                           const char XML[] =
1505                               "<s:Envelope xmlns:s=\""
1506                               "http://www.w3.org/2003/05/soap-envelope"
1507                               "\" xmlns:wsmid=\""
1508 mike             1.12         "http://schemas.dmtf.org/wbem/wsman/identify/1/wsmanidentity.xsd"
1509                               "\">"
1510                               "<s:Header>"
1511                               "</s:Header>"
1512                               "<s:Body>"
1513                               "<wsmid:IdentifyResponse>"
1514                               "<wsmid:ProtocolVersion>"
1515                               WSMAN_PROTOCOL_VERSION
1516                               "</wsmid:ProtocolVersion>"
1517                               "<wsmid:ProductVendor>"
1518                               WSMAN_PRODUCT_VENDOR
1519                               "</wsmid:ProductVendor>"
1520                               "<wsmid:ProductVersion>"
1521                               WSMAN_PRODUCT_VERSION
1522                               "</wsmid:ProductVersion>"
1523                               "</wsmid:IdentifyResponse>"
1524                               "</s:Body>"
1525                               "</s:Envelope>";
1526                       
1527                           Buffer message;
1528                           message.append(HTTP, sizeof(HTTP) - 1);
1529 mike             1.12 
1530                           char buf[32];
1531                           int n = sprintf(buf, "%d\r\n\r\n", int(sizeof(XML) - 1));
1532                           message.append(buf, n);
1533                       
1534                           message.append(XML, sizeof(XML) - 1);
1535                       
1536                           sendResponse(queueId, message, false);
1537                       }
1538                       
1539 kumpf            1.2  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2