cimoperationresponsedecoder.cpp
来自「Pegasus is an open-source implementation」· C++ 代码 · 共 1,785 行 · 第 1/4 页
CPP
1,785 行
//%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 <iostream>#include <Pegasus/Common/Constants.h>#include <Pegasus/Common/XmlParser.h>#include <Pegasus/Common/XmlReader.h>#include <Pegasus/Common/System.h>#include <Pegasus/Common/XmlWriter.h>#include <Pegasus/Common/HTTPMessage.h>#include <Pegasus/Common/CIMMessage.h>#include <Pegasus/Common/Exception.h>#include "CIMOperationResponseDecoder.h"#include <Pegasus/Common/MessageLoader.h>PEGASUS_USING_STD;PEGASUS_NAMESPACE_BEGINCIMOperationResponseDecoder::CIMOperationResponseDecoder( MessageQueue* outputQueue, MessageQueue* encoderQueue, ClientAuthenticator* authenticator, Uint32 showInput) : MessageQueue(PEGASUS_QUEUENAME_OPRESPDECODER), _outputQueue(outputQueue), _encoderQueue(encoderQueue), _authenticator(authenticator), _showInput(showInput){}CIMOperationResponseDecoder::~CIMOperationResponseDecoder(){}void CIMOperationResponseDecoder::setEncoderQueue(MessageQueue* encoderQueue){ _encoderQueue = encoderQueue;}void CIMOperationResponseDecoder::handleEnqueue(){ Message* message = dequeue(); if (!message) return; switch (message->getType()) { case HTTP_MESSAGE: { HTTPMessage* httpMessage = (HTTPMessage*)message; _handleHTTPMessage(httpMessage); break; } default: PEGASUS_ASSERT(0); break; } delete message;}void CIMOperationResponseDecoder::setDataStorePointer( ClientPerfDataStore* perfDataStore_ptr){ dataStore = perfDataStore_ptr;}void CIMOperationResponseDecoder::_handleHTTPMessage(HTTPMessage* httpMessage){ // // Parse the HTTP message: // TimeValue networkEndTime = TimeValue::getCurrentTime(); String connectClose; String startLine; Array<HTTPHeader> headers; char* content; Uint32 contentLength; Boolean cimReconnect=false; if (httpMessage->message.size() == 0) { MessageLoaderParms mlParms( "Client.CIMOperationResponseDecoder.EMPTY_RESPONSE", "Empty HTTP response message."); String mlString(MessageLoader::getMessage(mlParms)); CIMClientMalformedHTTPException* malformedHTTPException = new CIMClientMalformedHTTPException(mlString); ClientExceptionMessage * response = new ClientExceptionMessage(malformedHTTPException); _outputQueue->enqueue(response); return; } httpMessage->parse(startLine, headers, contentLength); // // Check for Connection: Close // if (HTTPMessage::lookupHeader(headers, "Connection", connectClose, false)) { if (String::equalNoCase(connectClose, "Close")) { //reconnect and then resend next request. cimReconnect=true; } } // // Get the status line info // String httpVersion; Uint32 statusCode; String reasonPhrase; Boolean parsableMessage = HTTPMessage::parseStatusLine( startLine, httpVersion, statusCode, reasonPhrase); if (!parsableMessage) { MessageLoaderParms mlParms( "Client.CIMOperationResponseDecoder.MALFORMED_RESPONSE", "Malformed HTTP response message."); String mlString(MessageLoader::getMessage(mlParms)); CIMClientMalformedHTTPException* malformedHTTPException = new CIMClientMalformedHTTPException(mlString); ClientExceptionMessage * response = new ClientExceptionMessage(malformedHTTPException); response->setCloseConnect(cimReconnect); _outputQueue->enqueue(response); return; }#ifdef PEGASUS_CLIENT_TRACE_ENABLE if (_showInput & 1) { cout << "CIMOperatonResponseDecoder"; httpMessage->printAll(cout); } if (_showInput & 2) { Uint32 size = httpMessage->message.size(); char* tmpBuf = new char[size+1]; strncpy( tmpBuf, httpMessage->message.getData(), size ); tmpBuf[size] = '\0'; Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, "CIMOperationRequestDecoder::Response, XML content: $1", tmpBuf); delete []tmpBuf; }#endif try { if (_authenticator->checkResponseHeaderForChallenge(headers)) { // // Get the original request, put that in the encoder's queue for // re-sending with authentication challenge response. // Message* reqMessage = _authenticator->releaseRequestMessage(); if (cimReconnect == true) { reqMessage->setCloseConnect(cimReconnect); _outputQueue->enqueue(reqMessage); } else { _encoderQueue->enqueue(reqMessage); } return; } else { // // Received a valid/error response from the server. // We do not need the original request message anymore, hence // delete the request message by getting the handle from the // ClientAuthenticator. // Message* reqMessage = _authenticator->releaseRequestMessage(); delete reqMessage; } } catch (InvalidAuthHeader& e) { CIMClientMalformedHTTPException* malformedHTTPException = new CIMClientMalformedHTTPException(e.getMessage()); ClientExceptionMessage * response = new ClientExceptionMessage(malformedHTTPException); response->setCloseConnect(cimReconnect); _outputQueue->enqueue(response); return; } // We have the response. If authentication failed, we will generate a // CIMClientHTTPErrorException below with the "401 Unauthorized" status // in the (re-challenge) response. // // Check for a success (200 OK) response // if (statusCode != HTTP_STATUSCODE_OK) { String cimError; String pegasusError; HTTPMessage::lookupHeader(headers, "CIMError", cimError, true); HTTPMessage::lookupHeader( headers, PEGASUS_HTTPHEADERTAG_ERRORDETAIL, pegasusError); try { pegasusError = XmlReader::decodeURICharacters(pegasusError); } catch (ParseError&) { // Ignore this exception. We're more interested in having the // message in encoded form than knowing that the format is invalid. } CIMClientHTTPErrorException* httpError = new CIMClientHTTPErrorException(statusCode, reasonPhrase, cimError, pegasusError); ClientExceptionMessage * response = new ClientExceptionMessage(httpError); response->setCloseConnect(cimReconnect); _outputQueue->enqueue(response); return; } // // Search for "CIMOperation" header: // String cimOperation; if (!HTTPMessage::lookupHeader( headers, "CIMOperation", cimOperation, true)) { MessageLoaderParms mlParms( "Client.CIMOperationResponseDecoder.MISSING_CIMOP_HEADER", "Missing CIMOperation HTTP header"); String mlString(MessageLoader::getMessage(mlParms)); CIMClientMalformedHTTPException* malformedHTTPException = new CIMClientMalformedHTTPException(mlString); ClientExceptionMessage * response = new ClientExceptionMessage(malformedHTTPException); response->setCloseConnect(cimReconnect); _outputQueue->enqueue(response); return; } // // Search for "Content-Type" header: // // BUG 572, Use of Content-Type header and change error msg. // If header exists, test type. If not, ignore. We will find // content type errors in text analysis. // content-type header value format: // type "/" subtype *( ";" parameter ) // ex. text/xml;Charset="utf8" String cimContentType; if (HTTPMessage::lookupHeader( headers, "Content-Type", cimContentType, true)) { Uint32 len; String contentTypeValue; if ((len = cimContentType.find(';')) != PEG_NOT_FOUND) contentTypeValue = cimContentType.subString(0,len); else contentTypeValue = cimContentType; if (!String::equalNoCase(contentTypeValue, "text/xml") && !String::equalNoCase(contentTypeValue, "application/xml")) { CIMClientMalformedHTTPException* malformedHTTPException = new CIMClientMalformedHTTPException ("Bad Content-Type HTTP header; " + contentTypeValue); ClientExceptionMessage * response = new ClientExceptionMessage(malformedHTTPException); response->setCloseConnect(cimReconnect); _outputQueue->enqueue(response); return; } } // comment out the error rejection code if the content-type header does // not exist#ifdef PEGASUS_REJECT_ON_MISSING_CONTENTTYPE_HEADER else { CIMClientMalformedHTTPException* malformedHTTPException = new CIMClientMalformedHTTPException ("Missing Content-Type HTTP header; "); ClientExceptionMessage * response = new ClientExceptionMessage(malformedHTTPException); response->setCloseConnect(cimReconnect); _outputQueue->enqueue(response); return; }#endif // look for any cim status codes. The HTTPConnection level would have // added them here. String cimStatusCodeValue; Boolean found = HTTPMessage::lookupHeader(headers, "CIMStatusCode", cimStatusCodeValue, true); CIMStatusCode cimStatusCodeNumber = CIM_ERR_SUCCESS; if (found == true && (cimStatusCodeNumber = (CIMStatusCode) atoi(cimStatusCodeValue.getCString())) != CIM_ERR_SUCCESS) { String cimStatusCodeDescription; found = HTTPMessage::lookupHeader(headers, "CIMStatusCodeDescription", cimStatusCodeDescription, true); if (found == true && cimStatusCodeDescription.size() > 0) { try { cimStatusCodeDescription = XmlReader::decodeURICharacters(cimStatusCodeDescription); } catch (ParseError&) { } } // if there is a description with the code CIMException* cimStatusException = new CIMException(cimStatusCodeNumber,cimStatusCodeDescription); cimStatusException->setContentLanguages(httpMessage->contentLanguages); ClientExceptionMessage * response = new ClientExceptionMessage(cimStatusException); response->setCloseConnect(cimReconnect); _outputQueue->enqueue(response); return; } String serverTime; if (HTTPMessage::lookupHeader( headers, "WBEMServerResponseTime", serverTime, true)) { Uint32 sTime = (Uint32) atol(serverTime.getCString()); dataStore->setServerTime(sTime); } // // 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; // // If it is a method response, then dispatch it to be handled: // if (!String::equalNoCase(cimOperation, "MethodResponse")) { MessageLoaderParms mlParms( "Client.CIMOperationResponseDecoder.EXPECTED_METHODRESPONSE", "Received CIMOperation HTTP header value \"$1\", expected " "\"MethodResponse\"", cimOperation); String mlString(MessageLoader::getMessage(mlParms)); CIMClientMalformedHTTPException* malformedHTTPException = new CIMClientMalformedHTTPException(mlString); ClientExceptionMessage * response = new ClientExceptionMessage(malformedHTTPException); response->setCloseConnect(cimReconnect); _outputQueue->enqueue(response); return; } dataStore->setResponseSize(contentLength); dataStore->setEndNetworkTime(networkEndTime); _handleMethodResponse(content, httpMessage->contentLanguages,cimReconnect);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?