📄 cimexportrequestdecoder.cpp
字号:
{ if (!(isUTF8((char *)&content[count]))) { sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "request-not-valid", "Invalid UTF-8 character detected.", closeConnect); return; } UTF8_NEXT(content,count); } } // If it is a method call, then dispatch it to be handled:// l10n handleMethodRequest( queueId, httpMethod, content, requestUri, cimProtocolVersion, cimExportMethod, userName, httpMessage->ipAddress, acceptLanguages, contentLanguages, closeConnect);}void CIMExportRequestDecoder::handleMethodRequest( Uint32 queueId, HttpMethod httpMethod, char* content, const String& requestUri, const String& cimProtocolVersionInHeader, const String& cimExportMethodInHeader, const String& userName, const String& ipAddress, const AcceptLanguageList& httpAcceptLanguages, const ContentLanguageList& httpContentLanguages, Boolean closeConnect){// l10n // Set the Accept-Language into the thread for this service. // This will allow all code in this thread to get // the languages for the messages returned to the client. Thread::setLanguages(new AcceptLanguageList(httpAcceptLanguages)); // // If CIM Listener is shutting down, return error response // if (_serverTerminating) { sendHttpError( queueId, HTTP_STATUS_SERVICEUNAVAILABLE, String::EMPTY, "CIM Listener is shutting down.", closeConnect); return; } // Create a parser: XmlParser parser(content); XmlEntry entry; String messageId; const char* cimExportMethodName = ""; AutoPtr<CIMExportIndicationRequestMessage> request; try { // // Process <?xml ... > // // These values are currently unused const char* xmlVersion = 0; const char* xmlEncoding = 0; XmlReader::getXmlDeclaration(parser, xmlVersion, xmlEncoding); // Expect <CIM ...> const char* cimVersion = 0; const char* dtdVersion = 0; XmlReader::getCimStartTag(parser, cimVersion, dtdVersion); // Reject cimVersion not in 2.0 to 2.3 if ((cimVersion[0] != '2') || (cimVersion[1] != '.') || ((cimVersion[2] != '0') && (cimVersion[2] != '1') && (cimVersion[2] != '2') && (cimVersion[2] != '3'))) { sendHttpError( queueId, HTTP_STATUS_NOTIMPLEMENTED, "unsupported-cim-version", String::EMPTY, closeConnect); return; } // We accept DTD version 2.x (see Bugzilla 1556) Boolean dtdVersionAccepted = false; if ((dtdVersion[0] == '2') && (dtdVersion[1] == '.') && (dtdVersion[2] != 0)) { // Verify that all characters after the '.' are digits Uint32 index = 2; while (isdigit(dtdVersion[index])) { index++; } if (dtdVersion[index] == 0) { dtdVersionAccepted = true; } } if (!dtdVersionAccepted) { sendHttpError( queueId, HTTP_STATUS_NOTIMPLEMENTED, "unsupported-dtd-version", String::EMPTY, closeConnect); return; } // Expect <MESSAGE ...> String protocolVersion; if (!XmlReader::getMessageStartTag( parser, messageId, protocolVersion)) { // l10n // throw XmlValidationError( // parser.getLine(), "expected MESSAGE element"); MessageLoaderParms mlParms("ExportServer.CIMExportRequestDecoder.EXPECTED_MESSAGE_ELEMENT", "expected MESSAGE element"); throw XmlValidationError(parser.getLine(), mlParms); } // Validate that the protocol version in the header matches the XML if (!String::equalNoCase(protocolVersion, cimProtocolVersionInHeader)) { sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", String::EMPTY, closeConnect); return; } // We accept protocol version 1.x (see Bugzilla 1556) Boolean protocolVersionAccepted = false; if ((protocolVersion.size() >= 3) && (protocolVersion[0] == '1') && (protocolVersion[1] == '.')) { // Verify that all characters after the '.' are digits Uint32 index = 2; while ((index < protocolVersion.size()) && (protocolVersion[index] >= '0') && (protocolVersion[index] <= '9')) { index++; } if (index == protocolVersion.size()) { protocolVersionAccepted = true; } } if (!protocolVersionAccepted) { // See Specification for CIM Operations over HTTP section 4.3 sendHttpError( queueId, HTTP_STATUS_NOTIMPLEMENTED, "unsupported-protocol-version", String::EMPTY, closeConnect); return; } if (XmlReader::testStartTag(parser, entry, "MULTIEXPREQ")) { // We wouldn't have gotten here if CIMExportBatch header was // specified, so this must be indicative of a header mismatch sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", String::EMPTY, closeConnect); return; // Future: When MULTIEXPREQ is supported, must ensure CIMExportMethod // header is absent, and CIMExportBatch header is present. } // Expect <SIMPLEEXPREQ ...> XmlReader::expectStartTag(parser, entry, "SIMPLEEXPREQ"); // Expect <EXPMETHODCALL ...> if (!XmlReader::getEMethodCallStartTag(parser, cimExportMethodName)) { // l10n // throw XmlValidationError(parser.getLine(), // "expected EXPMETHODCALL element"); MessageLoaderParms mlParms("ExportServer.CIMExportRequestDecoder.EXPECTED_EXPMETHODCALL_ELEMENT", "expected EXPMETHODCALL element"); throw XmlValidationError(parser.getLine(), mlParms); } // The Specification for CIM Operations over HTTP reads: // 3.3.9. CIMExportMethod // // This header MUST be present in any CIM Export Request // message that contains a Simple Export Request. // // It MUST NOT be present in any CIM Export Response message, // nor in any CIM Export Request message that is not a // Simple Export Request. It MUST NOT be present in any CIM // Operation Request or Response message. // // The name of the CIM export method within a Simple Export // Request is defined to be the value of the NAME attribute // of the <EXPMETHODCALL> element. // // If a CIM Listener receives a CIM Export Request for which // either: // // - The CIMExportMethod header is present but has an invalid // value, or; // - The CIMExportMethod header is not present but the Export // Request Message is a Simple Export Request, or; // - The CIMExportMethod header is present but the Export // Request Message is not a Simple Export Request, or; // - The CIMExportMethod header is present, the Export Request // Message is a Simple Export Request, but the CIMIdentifier // value (when unencoded) does not match the unique method // name within the Simple Export Request, // // then it MUST fail the request and return a status of // "400 Bad Request" (and MUST include a CIMError header in the // response with a value of header-mismatch), subject to the // considerations specified in Errors. if (!String::equalNoCase(cimExportMethodName, cimExportMethodInHeader)) { // ATTN-RK-P3-20020404: How to decode cimExportMethodInHeader? sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", String::EMPTY, closeConnect); return; } // This try block only catches CIMExceptions, because they must be // responded to with a proper EMETHODRESPONSE. Other exceptions are // caught in the outer try block. try { // Delegate to appropriate method to handle: if (System::strcasecmp(cimExportMethodName, "ExportIndication") == 0) { request.reset(decodeExportIndicationRequest(queueId, parser, messageId, requestUri)); } else { // l10n // throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, // String("Unrecognized export method: ") + cimExportMethodName); throw PEGASUS_CIM_EXCEPTION_L (CIM_ERR_NOT_SUPPORTED, MessageLoaderParms("ExportServer.CIMExportRequestDecoder.UNRECOGNIZED_EXPORT_METHOD", "Unrecognized export method: $0", cimExportMethodName)); } } catch (CIMException& e) { sendEMethodError( queueId, httpMethod, messageId, cimExportMethodName, e, closeConnect); return; } // Expect </EXPMETHODCALL> XmlReader::expectEndTag(parser, "EXPMETHODCALL"); // Expect </SIMPLEEXPREQ> XmlReader::expectEndTag(parser, "SIMPLEEXPREQ"); // Expect </MESSAGE> XmlReader::expectEndTag(parser, "MESSAGE"); // Expect </CIM> XmlReader::expectEndTag(parser, "CIM"); } catch (XmlValidationError& e) { Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::TRACE, "CIMExportRequestDecoder::handleMethodRequest - XmlValidationError exception has occurred. Message: $0",e.getMessage()); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "request-not-valid", e.getMessage(), closeConnect); return; } catch (XmlSemanticError& e) { Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::TRACE, "CIMExportRequestDecoder::handleMethodRequest - XmlSemanticError exception has occurred. Message: $0",e.getMessage()); // ATTN-RK-P2-20020404: Is this the correct response for these errors? sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "request-not-valid", e.getMessage(), closeConnect); return; } catch (XmlException& e) { Logger::put(Logger::ERROR_LOG, System::CIMSERVER, Logger::TRACE, "CIMExportRequestDecoder::handleMethodRequest - XmlException has occurred. Message: $0",e.getMessage()); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "request-not-well-formed", e.getMessage(), closeConnect); return; } catch (Exception& e) { // Don't know why I got this exception. Seems like a bad thing. // Any exceptions we're expecting should be caught separately and // dealt with appropriately. This is a last resort. sendHttpError( queueId, HTTP_STATUS_INTERNALSERVERERROR, String::EMPTY, e.getMessage(), closeConnect); return; } catch (...) { // Don't know why I got whatever this is. Seems like a bad thing. // Any exceptions we're expecting should be caught separately and // dealt with appropriately. This is a last resort. sendHttpError( queueId, HTTP_STATUS_INTERNALSERVERERROR, String::EMPTY, String::EMPTY, closeConnect); return; }//l10n start// l10n TODO - might want to move A-L and C-L to Message// to make this more maintainable // Add the language headers to the request. // Note: Since the text of an export error response will be ignored // by the export client, ignore Accept-Language in the export request. // This will cause any export error response message to be sent in the // default language. request->operationContext.insert(IdentityContainer(userName)); request->operationContext.set(ContentLanguageListContainer(httpContentLanguages)); request->operationContext.set(AcceptLanguageListContainer(AcceptLanguageList()));// l10n end request->ipAddress = ipAddress; request->setCloseConnect(closeConnect); _outputQueue->enqueue(request.release());}CIMExportIndicationRequestMessage* CIMExportRequestDecoder::decodeExportIndicationRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const String& requestUri){ CIMInstance instanceName; String destStr = requestUri.subString(requestUri.find ("/CIMListener") + 12, PEG_NOT_FOUND); for (const char* name; XmlReader::getEParamValueTag(parser, name);) { if (System::strcasecmp(name, "NewIndication") == 0) { XmlReader::getInstanceElement(parser, instanceName); } else { MessageLoaderParms mlParms( "ExportServer.CIMExportRequestDecoder." "UNRECOGNIZED_EXPPARAMVALUE_NAME", "Unrecognized EXPPARAMVALUE Name $0", name); throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, mlParms); } XmlReader::expectEndTag(parser, "EXPPARAMVALUE"); } CIMExportIndicationRequestMessage* request = new CIMExportIndicationRequestMessage( messageId, destStr, instanceName, QueueIdStack(queueId, _returnQueueId)); return(request);}void CIMExportRequestDecoder::setServerTerminating(Boolean flag){ _serverTerminating = flag;}PEGASUS_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -