(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                                 "Empty HTTP response message.");
 79                             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 carolann.graves 1.1         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                         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 carolann.graves 1.1         }
107                     
108                             Tracer::trace(TRC_XML_IO, Tracer::LEVEL2, "%s",
109                                 httpMessage->message.getData());
110                         }
111                     
112                         //
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 carolann.graves 1.1         AutoPtr<ClientExceptionMessage> response(
128                                 new ClientExceptionMessage(malformedHTTPException.get()));
129                             malformedHTTPException.release();
130                             response->setCloseConnect(cimReconnect);
131                             exceptionMessage = response.release();
132                             valid = false;
133                     
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 carolann.graves 1.1     char*& content,
149                         ClientExceptionMessage*& exceptionMessage,
150                         Boolean& valid)
151                     {
152                         PEG_METHOD_ENTER(TRC_EXPORT_CLIENT,
153                             "HTTPExportResponseDecoder::validateHTTPHeaders()");
154                     
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 carolann.graves 1.1         String pegasusError;
170                     
171                             HTTPMessage::lookupHeader(headers, "CIMError", cimError);
172                             HTTPMessage::lookupHeader(headers, PEGASUS_HTTPHEADERTAG_ERRORDETAIL,
173                                 pegasusError);
174                             try
175                             {
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 carolann.graves 1.1         httpError.release();
191                             response->setCloseConnect(cimReconnect);
192                             exceptionMessage = response.release();
193                             valid = false;
194                     
195                             PEG_METHOD_EXIT();
196                             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 carolann.graves 1.1             CIMClientMalformedHTTPException(mlString));
212                     
213                             AutoPtr<ClientExceptionMessage> response(
214                                 new ClientExceptionMessage(malformedHTTPException.get()));
215                     
216                             malformedHTTPException.release();
217                             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 carolann.graves 1.1         AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(new
233                                 CIMClientMalformedHTTPException(
234                                     "Missing CIMContentType HTTP header"));
235                             AutoPtr<ClientExceptionMessage> response(
236                                 new ClientExceptionMessage(malformedHTTPException.get()));
237                     
238                             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 carolann.graves 1.1 
254                         //
255                         // Expect CIMExport HTTP header value MethodResponse
256                         //
257                         if (!String::equalNoCase(cimExport, "MethodResponse"))
258                         {
259                             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 carolann.graves 1.1         valid = false;
275                     
276                             PEG_METHOD_EXIT();
277                             return; 
278                         }
279                     
280                         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 carolann.graves 1.1     //
296                         XmlParser parser((char*)content);
297                         XmlEntry entry;
298                     
299                         try
300                         {
301                             //
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 carolann.graves 1.1         // Expect <MESSAGE ... >
317                             //
318                             String messageId;
319                             String protocolVersion;
320                             if (!XmlReader::getMessageStartTag(parser, messageId, protocolVersion))
321                             {
322                                 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                             if (!String::equalNoCase(protocolVersion, "1.0"))
336                             {
337 carolann.graves 1.1             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                             //
358 carolann.graves 1.1         // 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                                 {
379 carolann.graves 1.1                 //
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                                 }
400 carolann.graves 1.1         }
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                             XmlReader::expectEndTag(parser, "MESSAGE");
421 carolann.graves 1.1         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                         PEG_METHOD_EXIT();
442 carolann.graves 1.1 }
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                                     cimException,
463 carolann.graves 1.1                 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