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

  1 carolann.graves 1.1 //%2006////////////////////////////////////////////////////////////////////////
  2                     //
  3                     // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4                     // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5                     // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6                     // IBM Corp.; EMC Corporation, The Open Group.
  7                     // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8                     // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9                     // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10                     // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11                     // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12                     // EMC Corporation; Symantec Corporation; The Open Group.
 13                     //
 14                     // Permission is hereby granted, free of charge, to any person obtaining a copy
 15                     // of this software and associated documentation files (the "Software"), to
 16                     // deal in the Software without restriction, including without limitation the
 17                     // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18                     // sell copies of the Software, and to permit persons to whom the Software is
 19                     // furnished to do so, subject to the following conditions:
 20                     // 
 21                     // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 carolann.graves 1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23                     // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24                     // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25                     // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26                     // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27                     // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28                     // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29                     //
 30                     //==============================================================================
 31                     //
 32                     //%/////////////////////////////////////////////////////////////////////////////
 33                     
 34                     #include <Pegasus/Common/Config.h>
 35                     #include <Pegasus/Common/Constants.h>
 36                     #include <Pegasus/Common/XmlReader.h>
 37                     #include <Pegasus/Common/System.h>
 38                     #include <Pegasus/Common/CIMMessage.h>
 39                     #include <Pegasus/Common/MessageLoader.h>
 40                     #include <Pegasus/Common/Tracer.h>
 41                     #include <Pegasus/Client/CIMClientException.h>
 42                     #include "HTTPExportResponseDecoder.h"
 43 carolann.graves 1.1 
 44                     PEGASUS_USING_STD;
 45                     PEGASUS_NAMESPACE_BEGIN
 46                     
 47                     void HTTPExportResponseDecoder::parseHTTPHeaders(
 48                         HTTPMessage* httpMessage,
 49                         ClientExceptionMessage*& exceptionMessage,
 50                         Array<HTTPHeader>& headers,
 51                         Uint32& contentLength,
 52                         Uint32& statusCode,
 53                         String& reasonPhrase,
 54                         Boolean& cimReconnect,
 55                         Boolean& valid)
 56                     {
 57                         PEG_METHOD_ENTER(TRC_EXPORT_CLIENT,
 58                             "HTTPExportResponseDecoder::parseHTTPHeaders()");
 59                     
 60                         exceptionMessage = 0;
 61                         headers.clear();
 62                         contentLength = 0;
 63                         statusCode = 0;
 64 carolann.graves 1.1     reasonPhrase = String::EMPTY;
 65                         cimReconnect = false;
 66                         valid = true;
 67                     
 68                         String startLine;
 69                         String connectClose;
 70                     
 71                         //    
 72                         //  Check for empty HTTP response message    
 73                         //    
 74                         if (httpMessage->message.size() == 0)
 75                         {
 76                             MessageLoaderParms mlParms(
 77                                 "ExportClient.CIMExportResponseDecoder.EMPTY_RESPONSE",
 78 dave.sudlik     1.1.18.4             "Connection closed by CIM Server.");
 79 carolann.graves 1.1              String mlString(MessageLoader::getMessage(mlParms));
 80                                  AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(
 81                                      new CIMClientMalformedHTTPException(mlString));
 82                                  AutoPtr<ClientExceptionMessage> response(
 83                                      new ClientExceptionMessage(malformedHTTPException.get()));
 84                                  malformedHTTPException.release();
 85                                  exceptionMessage = response.release();
 86                                  valid = false;
 87                          
 88                                  PEG_METHOD_EXIT();
 89                                  return;
 90                              }
 91                          
 92                              //
 93                              // Parse the HTTP message headers and get content length
 94                              //
 95                              httpMessage->parse(startLine, headers, contentLength);
 96                          
 97                              //
 98                              // Check for Connection: Close
 99                              //
100 carolann.graves 1.1          if (HTTPMessage::lookupHeader(headers, "Connection", connectClose, false))
101                              {
102                                  if (String::equalNoCase(connectClose, "Close"))
103                                  {
104                                      // reconnect and then resend next request.
105                                      cimReconnect=true;
106                                  }
107                              }
108                          
109 marek           1.1.18.3     PEG_TRACE_CSTRING(TRC_XML_IO, Tracer::LEVEL2,
110                                                httpMessage->message.getData());
111 kumpf           1.1.18.1 
112 carolann.graves 1.1          //
113                              //  Parse HTTP message status line
114                              //
115                              String httpVersion;
116                          
117                              Boolean parsableMessage = HTTPMessage::parseStatusLine(
118                                  startLine, httpVersion, statusCode, reasonPhrase);
119                              if (!parsableMessage)
120                              {
121                                  MessageLoaderParms mlParms(
122                                      "ExportClient.CIMExportResponseDecoder.MALFORMED_RESPONSE",
123                                      "Malformed HTTP response message.");
124                                  String mlString(MessageLoader::getMessage(mlParms));
125                                  AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(
126                                      new CIMClientMalformedHTTPException(mlString));
127                                  AutoPtr<ClientExceptionMessage> response(
128                                      new ClientExceptionMessage(malformedHTTPException.get()));
129                                  malformedHTTPException.release();
130                                  response->setCloseConnect(cimReconnect);
131                                  exceptionMessage = response.release();
132                                  valid = false;
133 carolann.graves 1.1      
134                                  PEG_METHOD_EXIT();
135                                  return;
136                              }
137                          
138                              PEG_METHOD_EXIT();
139                          }
140                          
141                          void HTTPExportResponseDecoder::validateHTTPHeaders(
142                              HTTPMessage* httpMessage,
143                              Array<HTTPHeader>& headers,
144                              Uint32 contentLength,
145                              Uint32 statusCode,
146                              Boolean cimReconnect,
147                              const String& reasonPhrase,
148                              char*& content,
149                              ClientExceptionMessage*& exceptionMessage,
150                              Boolean& valid)
151                          {
152                              PEG_METHOD_ENTER(TRC_EXPORT_CLIENT,
153                                  "HTTPExportResponseDecoder::validateHTTPHeaders()");
154 carolann.graves 1.1      
155                              content = 0;
156                              exceptionMessage = 0;
157                              valid = true;
158                          
159                              //
160                              // If authentication failed, a CIMClientHTTPErrorException will be
161                              // generated with the "401 Unauthorized" status in the (re-challenge)
162                              // response
163                              //
164                              // Check for a non-success (200 OK) response
165                              //
166                              if (statusCode != HTTP_STATUSCODE_OK)
167                              {
168                                  String cimError;
169                                  String pegasusError;
170                          
171                                  HTTPMessage::lookupHeader(headers, "CIMError", cimError);
172                                  HTTPMessage::lookupHeader(headers, PEGASUS_HTTPHEADERTAG_ERRORDETAIL,
173                                      pegasusError);
174                                  try
175 carolann.graves 1.1              {
176                                      pegasusError = XmlReader::decodeURICharacters(pegasusError);
177                                  }
178                                  catch (const ParseError&)
179                                  {
180                                      // Ignore this exception.  We're more interested in having the
181                                      // message in encoded form than knowing that the format is invalid.
182                                  }
183                          
184                                  AutoPtr<CIMClientHTTPErrorException> httpError(
185                                      new CIMClientHTTPErrorException(statusCode, reasonPhrase, cimError,
186                                          pegasusError));
187                                  AutoPtr<ClientExceptionMessage> response(
188                                      new ClientExceptionMessage(httpError.get()));
189                          
190                                  httpError.release();
191                                  response->setCloseConnect(cimReconnect);
192                                  exceptionMessage = response.release();
193                                  valid = false;
194                          
195                                  PEG_METHOD_EXIT();
196 carolann.graves 1.1              return;
197                              }
198                          
199                              //
200                              // Check for missing "CIMExport" header
201                              //
202                              String cimExport;
203                              if (!HTTPMessage::lookupHeader(headers, "CIMExport", cimExport, true))
204                              {
205                                  MessageLoaderParms mlParms(
206                                      "ExportClient.CIMExportResponseDecoder.MISSING_CIMEXP_HEADER",
207                                      "Missing CIMExport HTTP header");
208                                  String mlString(MessageLoader::getMessage(mlParms));
209                          
210                                  AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(new
211                                      CIMClientMalformedHTTPException(mlString));
212                          
213                                  AutoPtr<ClientExceptionMessage> response(
214                                      new ClientExceptionMessage(malformedHTTPException.get()));
215                          
216                                  malformedHTTPException.release();
217 carolann.graves 1.1              response->setCloseConnect(cimReconnect);
218                                  exceptionMessage = response.release();
219                                  valid = false;
220                          
221                                  PEG_METHOD_EXIT();
222                                  return;
223                              }
224                          
225                              //
226                              // Check for missing "Content-Type" header
227                              //
228                              String cimContentType;
229                              if (!HTTPMessage::lookupHeader(
230                                  headers, "Content-Type", cimContentType, true))
231                              {
232                                  AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(new
233                                      CIMClientMalformedHTTPException(
234                                          "Missing CIMContentType HTTP header"));
235                                  AutoPtr<ClientExceptionMessage> response(
236                                      new ClientExceptionMessage(malformedHTTPException.get()));
237                          
238 carolann.graves 1.1              malformedHTTPException.release();
239                                  response->setCloseConnect(cimReconnect);
240                                  exceptionMessage = response.release();
241                                  valid = false;
242                          
243                                  PEG_METHOD_EXIT();
244                                  return;
245                              }
246                          
247                              //
248                              // Calculate the beginning of the content from the message size and
249                              // the content length
250                              //
251                              content = (char *) httpMessage->message.getData() +
252                                  httpMessage->message.size() - contentLength;
253                          
254                              //
255                              // Expect CIMExport HTTP header value MethodResponse
256                              //
257                              if (!String::equalNoCase(cimExport, "MethodResponse"))
258                              {
259 carolann.graves 1.1              MessageLoaderParms mlParms(
260                                      "ExportClient.CIMExportResponseDecoder.EXPECTED_METHODRESPONSE",
261                                      "Received CIMExport HTTP header value \"$0\", "
262                                      "expected \"MethodResponse\"", cimExport);
263                                  String mlString(MessageLoader::getMessage(mlParms));
264                          
265                                  AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(
266                                      new CIMClientMalformedHTTPException(mlString));
267                          
268                                  AutoPtr<ClientExceptionMessage> response(
269                                      new ClientExceptionMessage(malformedHTTPException.get()));
270                          
271                                  malformedHTTPException.release();
272                                  response->setCloseConnect(cimReconnect);
273                                  exceptionMessage = response.release();
274                                  valid = false;
275                          
276                                  PEG_METHOD_EXIT();
277                                  return; 
278                              }
279                          
280 carolann.graves 1.1          PEG_METHOD_EXIT();
281                          }
282                          
283                          void HTTPExportResponseDecoder::decodeExportResponse(
284                              char* content,
285                              Boolean cimReconnect,
286                              Message*& responseMessage)
287                          {
288                              PEG_METHOD_ENTER (TRC_EXPORT_CLIENT,
289                                  "HTTPExportResponseDecoder::decodeExportResponse()");
290                          
291                              AutoPtr<Message> response;
292                          
293                              //
294                              // Create and initialize XML parser:
295                              //
296                              XmlParser parser((char*)content);
297                              XmlEntry entry;
298                          
299                              try
300                              {
301 carolann.graves 1.1              //
302                                  // Process <?xml ... >
303                                  //
304                                  const char* xmlVersion = 0;
305                                  const char* xmlEncoding = 0;
306                                  XmlReader::getXmlDeclaration(parser, xmlVersion, xmlEncoding);
307                          
308                                  //
309                                  // Process <CIM ... >
310                                  //
311                                  const char* cimVersion = 0;
312                                  const char* dtdVersion = 0;
313                                  XmlReader::getCimStartTag(parser, cimVersion, dtdVersion);
314                          
315                                  //
316                                  // Expect <MESSAGE ... >
317                                  //
318                                  String messageId;
319                                  String protocolVersion;
320                                  if (!XmlReader::getMessageStartTag(parser, messageId, protocolVersion))
321                                  {
322 carolann.graves 1.1                  MessageLoaderParms mlParms(
323                                          "ExportClient.CIMExportResponseDecoder."
324                                              "EXPECTED_MESSAGE_ELEMENT",
325                                          "expected MESSAGE element");
326                                      String mlString(MessageLoader::getMessage(mlParms));
327                          
328                                      PEG_METHOD_EXIT();
329                                      throw XmlValidationError(parser.getLine(), mlString);
330                                  }
331                          
332                                  //
333                                  // Check for unsupported protocol version
334                                  //
335 karl            1.1.18.2         if (!XmlReader::isSupportedProtocolVersion(protocolVersion))
336 carolann.graves 1.1              {
337                                      MessageLoaderParms mlParms(
338                                          "ExportClient.CIMExportResponseDecoder.UNSUPPORTED_PROTOCOL",
339                                          "Received unsupported protocol version \"$0\", expected \"$1\"",
340                                          protocolVersion, "1.0");
341                                          String mlString(MessageLoader::getMessage(mlParms));
342                          
343                                      AutoPtr<CIMClientResponseException> responseException(
344                                          new CIMClientResponseException(mlString));
345                          
346                                      AutoPtr<ClientExceptionMessage> response(
347                                          new ClientExceptionMessage(responseException.get()));
348                          
349                                      responseException.release();
350                                      response->setCloseConnect(cimReconnect);
351                                      responseMessage = response.release();
352                          
353                                      PEG_METHOD_EXIT();
354                                      return;
355                                  }
356                          
357 carolann.graves 1.1              //
358                                  // Expect <SIMPLEEXPRSP ... >
359                                  //
360                                  XmlReader::expectStartTag(parser, entry, "SIMPLEEXPRSP");
361                          
362                                  //
363                                  // Expect <EXPMETHODRESPONSE ... >
364                                  //
365                                  const char* expMethodResponseName = 0;
366                                  Boolean isEmptyTag = false;
367                          
368                                  if (XmlReader::getEMethodResponseStartTag(
369                                      parser, expMethodResponseName, isEmptyTag))
370                                  {
371                                      if (System::strcasecmp(expMethodResponseName, "ExportIndication")
372                                          == 0)
373                                      {
374                                          response.reset(_decodeExportIndicationResponse(
375                                              parser, messageId, isEmptyTag));
376                                      }
377                                      else
378 carolann.graves 1.1                  {
379                                          //
380                                          //  Unrecognized ExpMethodResponse name attribute
381                                          //
382                                          MessageLoaderParms mlParms(
383                                              "ExportClient.CIMExportResponseDecoder."
384                                                  "UNRECOGNIZED_EXPMETHRSP",
385                                              "Unrecognized ExpMethodResponse name \"$0\"",
386                                              expMethodResponseName);
387                                          String mlString(MessageLoader::getMessage(mlParms));
388                             
389                                          PEG_METHOD_EXIT();
390                                          throw XmlValidationError(parser.getLine(), mlString);
391                                      }
392                          
393                                      //
394                                      // Handle end tag:
395                                      //
396                                      if (!isEmptyTag)
397                                      {
398                                          XmlReader::expectEndTag(parser, "EXPMETHODRESPONSE");
399 carolann.graves 1.1                  }
400                                  }
401                                  else
402                                  {
403                                      //
404                                      //  Expected ExpMethodResponse element
405                                      //
406                                      MessageLoaderParms mlParms(
407                                          "ExportClient.CIMExportResponseDecoder."
408                                              "EXPECTED_EXPMETHODRESPONSE_ELEMENT",
409                                          "expected EXPMETHODRESPONSE element");
410                                      String mlString(MessageLoader::getMessage(mlParms));
411                            
412                                      PEG_METHOD_EXIT();
413                                      throw XmlValidationError(parser.getLine(), mlString);
414                                  }
415                          
416                                  //
417                                  // Handle end tags:
418                                  //
419                                  XmlReader::expectEndTag(parser, "SIMPLEEXPRSP");
420 carolann.graves 1.1              XmlReader::expectEndTag(parser, "MESSAGE");
421                                  XmlReader::expectEndTag(parser, "CIM");
422                              }
423                              catch (XmlException& x)
424                              {
425                                  response.reset(new ClientExceptionMessage(
426                                      new CIMClientXmlException(x.getMessage())));
427                              }
428                              catch (Exception& x)
429                              {
430                                  response.reset(new ClientExceptionMessage(
431                                      new CIMClientResponseException(x.getMessage())));
432                              }
433                          
434                              //
435                              //  Note: Ignore any ContentLanguage set in the export response
436                              //
437                          
438                              response->setCloseConnect(cimReconnect);
439                              responseMessage = response.release();
440                          
441 carolann.graves 1.1          PEG_METHOD_EXIT();
442                          }
443                          
444                          CIMExportIndicationResponseMessage*
445                          HTTPExportResponseDecoder::_decodeExportIndicationResponse(
446                              XmlParser& parser,
447                              const String& messageId,
448                              Boolean isEmptyExpMethodResponseTag)
449                          {
450                              PEG_METHOD_ENTER (TRC_EXPORT_CLIENT,
451                                  "HTTPExportResponseDecoder::_decodeExportIndicationResponse()");
452                              XmlEntry entry;
453                              CIMException cimException;
454                          
455                              if (!isEmptyExpMethodResponseTag)
456                              {
457                                  if (XmlReader::getErrorElement(parser, cimException))
458                                  {
459                                      PEG_METHOD_EXIT();
460                                      return(new CIMExportIndicationResponseMessage(
461                                          messageId,
462 carolann.graves 1.1                      cimException,
463                                          QueueIdStack()));
464                                  }
465                          
466                                  if (XmlReader::testStartTagOrEmptyTag(parser, entry, "IRETURNVALUE"))
467                                  {
468                                      if (entry.type != XmlEntry::EMPTY_TAG)
469                                      {
470                                          XmlReader::expectEndTag(parser, "IRETURNVALUE");
471                                      }
472                                  }
473                              }
474                          
475                              PEG_METHOD_EXIT();
476                              return(new CIMExportIndicationResponseMessage(
477                                  messageId,
478                                  cimException,
479                                  QueueIdStack()));
480                          }
481                          
482                          PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2