⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cimexportrequestdecoder.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//%2006//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation, The Open Group.// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; Symantec Corporation; The Open Group.//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.////==============================================================================////%/////////////////////////////////////////////////////////////////////////////#include <Pegasus/Common/Config.h>#include <Pegasus/Common/Tracer.h>#include <cctype>#include <cstdio>#include <Pegasus/Common/Constants.h>#include <Pegasus/Common/XmlParser.h>#include <Pegasus/Common/XmlReader.h>#include <Pegasus/Common/XmlWriter.h>#include <Pegasus/Common/System.h>#include <Pegasus/Common/Logger.h>#include "CIMExportRequestDecoder.h"#include <Pegasus/Common/CommonUTF.h>#include <Pegasus/Common/MessageLoader.h>#include <Pegasus/Common/LanguageParser.h>PEGASUS_USING_STD;PEGASUS_NAMESPACE_BEGINCIMExportRequestDecoder::CIMExportRequestDecoder(   MessageQueueService* outputQueue,   Uint32 returnQueueId)   :   Base(PEGASUS_QUEUENAME_EXPORTREQDECODER),   _outputQueue(outputQueue),   _returnQueueId(returnQueueId),   _serverTerminating(false){}CIMExportRequestDecoder::~CIMExportRequestDecoder(){}void CIMExportRequestDecoder::sendResponse(    Uint32 queueId,    Buffer& message,    Boolean closeConnect){   MessageQueue* queue = MessageQueue::lookup(queueId);   if (queue)   {      HTTPMessage* httpMessage = new HTTPMessage(message);      httpMessage->setCloseConnect(closeConnect);      queue->enqueue(httpMessage);   }}void CIMExportRequestDecoder::sendEMethodError(   Uint32 queueId,   HttpMethod httpMethod,   const String& messageId,   const String& eMethodName,   const CIMException& cimException,   Boolean closeConnect){    Buffer message;    message = XmlWriter::formatSimpleEMethodErrorRspMessage(        eMethodName,        messageId,        httpMethod,        cimException);    sendResponse(queueId, message,closeConnect);}void CIMExportRequestDecoder::sendHttpError(   Uint32 queueId,   const String& status,   const String& cimError,   const String& messageBody,   Boolean closeConnect){    Buffer message;    message = XmlWriter::formatHttpErrorRspMessage(        status,        cimError,        messageBody);    sendResponse(queueId, message,closeConnect);}void CIMExportRequestDecoder::handleEnqueue(Message *message){   PEGASUS_ASSERT(message != 0);   switch (message->getType())   {      case HTTP_MESSAGE:	 handleHTTPMessage((HTTPMessage*)message);	 break;        default:            PEGASUS_ASSERT(0);            break;   }   delete message;}void CIMExportRequestDecoder::handleEnqueue(){   Message* message = dequeue();   if(message)      handleEnqueue(message);}//------------------------------------------------------------------------------//// From the HTTP/1.1 Specification (RFC 2626)://// Both types of message consist of a start-line, zero or more header fields// (also known as "headers"), an empty line (i.e., a line with nothing// preceding the CRLF) indicating the end of the header fields, and possibly// a message-body.//// Example CIM request:////     M-POST /cimom HTTP/1.1//     HOST: www.erewhon.com//     Content-Type: application/xml; charset="utf-8"//     Content-Length: xxxx//     Man: http://www.dmtf.org/cim/operation ; ns=73//     73-CIMExport: MethodRequest//     73-CIMExportMethod: ExportIndication//     73-CIMObject: root/cimv2////------------------------------------------------------------------------------void CIMExportRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage){   // Save queueId:   Uint32 queueId = httpMessage->queueId;   // Save userName:   String userName;   // Bug #351:   if ( httpMessage->message.size() == 0 )   {	// The message is empty; just drop it. The connection has	// probably closed.	return;   }   // </bug>   if ( httpMessage->authInfo->isAuthenticated() )   {      userName = httpMessage->authInfo->getAuthenticatedUser();   }   Boolean closeConnect = httpMessage->getCloseConnect();   Tracer::trace(       TRC_HTTP,       Tracer::LEVEL3,       "CIMOperationRequestDecoder::handleHTTPMessage()- httpMessage->getCloseConnect() returned %d",httpMessage->getCloseConnect());   // Parse the HTTP message:   String startLine;   Array<HTTPHeader> headers;   char* content;   Uint32 contentLength;   httpMessage->parse(startLine, headers, contentLength);   // Parse the request line:   String methodName;   String requestUri;   String httpVersion;   HttpMethod httpMethod = HTTP_METHOD__POST;   Tracer::trace(TRC_XML_IO, Tracer::LEVEL2, "%s",                 httpMessage->message.getData());   // ATTN-RK-P3-20020404: The requestUri may need to be pruned of the host   // name.  All we care about at this point is the path.   HTTPMessage::parseRequestLine(      startLine, methodName, requestUri, httpVersion);   //   //  Set HTTP method for the request   //   if (methodName == "M-POST")   {       httpMethod = HTTP_METHOD_M_POST;   }   // Unsupported methods are caught in the HTTPAuthenticatorDelegator   //<Bug #351>   //PEGASUS_ASSERT(methodName == "M-POST" || methodName == "POST");   if( methodName != "M-POST" && methodName != "POST" )    {       sendHttpError(           queueId,           HTTP_STATUS_NOTIMPLEMENTED,           "Only POST and M-POST are implemented",           String::EMPTY,           closeConnect);       return;   }   //</bug>   //   // Not true: "Mismatch of method and version is caught in HTTPAuthenticatorDelegator", bug #351 fixes this:   //   //PEGASUS_ASSERT (!((httpMethod == HTTP_METHOD_M_POST) &&   //                  (httpVersion == "HTTP/1.0")));   if( (httpMethod == HTTP_METHOD_M_POST) &&        (httpVersion == "HTTP/1.0") )   {       sendHttpError(           queueId,           HTTP_STATUS_BADREQUEST,           "M-POST method is not valid with version 1.0",           String::EMPTY,           closeConnect);       return;   }   //</bug>   // Process M-POST and POST messages:   String cimContentType;   String cimExport;   String cimExportBatch;   Boolean cimExportBatchFlag;   String cimProtocolVersion;   String cimExportMethod;   if (httpVersion == "HTTP/1.1")   {      // Validate the presence of a "Host" header.  The HTTP/1.1 specification      // says this in section 14.23 regarding the Host header field:      //      //     All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad      //     Request) status code to any HTTP/1.1 request message which lacks      //     a Host header field.      //      // Note:  The Host header value is not validated.      String hostHeader;      Boolean hostHeaderFound = HTTPMessage::lookupHeader(         headers, "Host", hostHeader, false);      if (!hostHeaderFound)      {         MessageLoaderParms parms(            "ExportServer.CIMExportRequestDecoder.MISSING_HOST_HEADER",            "HTTP request message lacks a Host header field.");         String msg(MessageLoader::getMessage(parms));         sendHttpError(             queueId,             HTTP_STATUS_BADREQUEST,             "",             msg,             closeConnect);         return;      }   }   // Validate the "CIMExport" header:   Boolean exportHeaderFound = HTTPMessage::lookupHeader(      headers, "CIMExport", cimExport, true);   // If the CIMExport header was missing, the HTTPAuthenticatorDelegator   // would not have passed the message to us.   // <bug #351>   // PEGASUS_ASSERT(exportHeaderFound);   if (!exportHeaderFound)   {	sendHttpError(            queueId,            HTTP_STATUS_BADREQUEST,            "Export header not found",            String::EMPTY,            closeConnect);        return;   }   // </bug>   if (!String::equalNoCase(cimExport, "MethodRequest"))   {      // The Specification for CIM Operations over HTTP reads:      //     3.3.5. CIMExport      //     If a CIM Listener receives CIM Export request with this      //     header, but with a missing value or a value that is not      //     "MethodRequest", then it MUST fail the request with      //     status "400 Bad Request". The CIM Server MUST include a      //     CIMError header in the response with a value of      //     unsupported-operation.      sendHttpError(          queueId,          HTTP_STATUS_BADREQUEST,          "unsupported-operation",          String::EMPTY,          closeConnect);      return;   }   // Validate the "CIMExportBatch" header:   cimExportBatchFlag = HTTPMessage::lookupHeader(          headers, "CIMExportBatch", cimExportBatch, true);   if (cimExportBatchFlag)   {      // The Specification for CIM Operations over HTTP reads:      //     3.3.10. CIMExportBatch      //     If a CIM Listener receives CIM Export Request for which the      //     CIMExportBatch header is present, but the Listener does not      //     support Multiple Exports, then it MUST fail the request and      //     return a status of "501 Not Implemented".      sendHttpError(          queueId,          HTTP_STATUS_NOTIMPLEMENTED,          "multiple-requests-unsupported",          String::EMPTY,          closeConnect);      return;   }   // Save these headers for later checking   if (!HTTPMessage::lookupHeader(          headers, "CIMProtocolVersion", cimProtocolVersion, true))   {      // Mandated by the Specification for CIM Operations over HTTP      cimProtocolVersion.assign("1.0");   }   if (HTTPMessage::lookupHeader(          headers, "CIMExportMethod", cimExportMethod, true))   {      if (cimExportMethod == String::EMPTY)      {         // This is not a valid value, and we use EMPTY to mean "absent"         sendHttpError(             queueId,             HTTP_STATUS_BADREQUEST,             "header-mismatch",             String::EMPTY,             closeConnect);         return;      }   }// l10n start   AcceptLanguageList acceptLanguages;   ContentLanguageList contentLanguages;   try   {	if(httpMessage->acceptLanguagesDecoded){		acceptLanguages = httpMessage->acceptLanguages;	}else{		// Get and validate the Accept-Language header, if set		String acceptLanguageHeader;		if (HTTPMessage::lookupHeader(		      headers,	    	  "Accept-Language",		      acceptLanguageHeader,	    	  false) == true)	    {	        acceptLanguages = LanguageParser::parseAcceptLanguageHeader(	            acceptLanguageHeader);	    }	}	if(httpMessage->contentLanguagesDecoded){		contentLanguages = httpMessage->contentLanguages;	}else{		// Get and validate the Content-Language header, if set		String contentLanguageHeader;		if (HTTPMessage::lookupHeader(		      headers,	    	  "Content-Language",		      contentLanguageHeader,	    	  false) == true)	    {	        contentLanguages = LanguageParser::parseContentLanguageHeader(	            contentLanguageHeader);	    }	}   }   catch (Exception &e)   {	Thread::clearLanguages();	MessageLoaderParms msgParms("ExportServer.CIMExportRequestDecoder.REQUEST_NOT_VALID","request-not-valid");	String msg(MessageLoader::getMessage(msgParms));	sendHttpError(            queueId,            HTTP_STATUS_BADREQUEST,            msg,            e.getMessage(),            closeConnect);       	return;   }// l10n end   // Zero-terminate the message:   httpMessage->message.append('\0');   // Calculate the beginning of the content from the message size and   // the content length.  Subtract 1 to take into account the null   // character we just added to the end of the message.   content = (char *) httpMessage->message.getData() +      httpMessage->message.size() - contentLength - 1;   // Validate the "Content-Type" header:   Boolean contentTypeHeaderFound = HTTPMessage::lookupHeader(headers,							      "Content-Type",							      cimContentType,							      true);   // ATTN: Bug 5928: Need to validate that the content type is text/xml or   // application/xml, and the encoding is utf-8 (or compatible)   if (!contentTypeHeaderFound)   {       sendHttpError(           queueId,           HTTP_STATUS_BADREQUEST,           "",           "HTTP Content-Type header error.",           closeConnect);       return;   }   else   {       // Validating content falls within UTF8 (required to be complaint       // with section C12 of Unicode 4.0 spec, chapter 3.)       Uint32 count = 0;       while(count<contentLength)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -