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

File: [Pegasus] / pegasus / src / Pegasus / ExportClient / HTTPExportResponseDecoder.cpp (download)
Revision: 1.5, Tue Mar 27 19:03:17 2007 UTC (17 years, 3 months ago) by kumpf
Branch: MAIN
CVS Tags: TASK-PEP305_VXWORKS-root, TASK-PEP305_VXWORKS-branch-pre-solaris-port, TASK-PEP305_VXWORKS-branch-post-solaris-port, TASK-PEP305_VXWORKS-branch-beta2, TASK-PEP305_VXWORKS-branch, TASK-PEP305_VXWORKS-2008-10-23, TASK-PEP291_IPV6-root, TASK-PEP291_IPV6-branch, TASK-PEP286_PRIVILEGE_SEPARATION-root, TASK-PEP286_PRIVILEGE_SEPARATION-branch, TASK-PEP274_dacim-root, TASK-PEP274_dacim-merged_out_to_branch, TASK-PEP274_dacim-merged_out_from_trunk, TASK-PEP274_dacim-merged_in_to_trunk, TASK-PEP274_dacim-merged_in_from_branch, TASK-PEP274_dacim-branch, TASK-Bug2102Final-root, TASK-Bug2102Final-merged_out_to_branch, TASK-Bug2102Final-merged_out_from_trunk, TASK-Bug2102Final-merged_in_to_trunk, TASK-Bug2102Final-merged_in_from_branch, TASK-Bug2102Final-branch, RELEASE_2_7_0-RC1, RELEASE_2_7_0-BETA, RELEASE_2_7_0, RELEASE_2_7-root
Branch point for: RELEASE_2_7-branch
Changes since 1.4: +6 -6 lines
BUG#: 6294
TITLE: Export files do not meet chksrc requirements
DESCRIPTION: Format according to the coding conventions.

//%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/Constants.h>
#include <Pegasus/Common/XmlReader.h>
#include <Pegasus/Common/System.h>
#include <Pegasus/Common/CIMMessage.h>
#include <Pegasus/Common/MessageLoader.h>
#include <Pegasus/Common/Tracer.h>
#include <Pegasus/Client/CIMClientException.h>
#include "HTTPExportResponseDecoder.h"

PEGASUS_USING_STD;
PEGASUS_NAMESPACE_BEGIN

void HTTPExportResponseDecoder::parseHTTPHeaders(
    HTTPMessage* httpMessage,
    ClientExceptionMessage*& exceptionMessage,
    Array<HTTPHeader>& headers,
    Uint32& contentLength,
    Uint32& statusCode,
    String& reasonPhrase,
    Boolean& cimReconnect,
    Boolean& valid)
{
    PEG_METHOD_ENTER(TRC_EXPORT_CLIENT,
        "HTTPExportResponseDecoder::parseHTTPHeaders()");

    exceptionMessage = 0;
    headers.clear();
    contentLength = 0;
    statusCode = 0;
    reasonPhrase = String::EMPTY;
    cimReconnect = false;
    valid = true;

    String startLine;
    String connectClose;

    //
    //  Check for empty HTTP response message
    //
    if (httpMessage->message.size() == 0)
    {
        MessageLoaderParms mlParms(
            "ExportClient.CIMExportResponseDecoder.EMPTY_RESPONSE",
            "Empty HTTP response message.");
        String mlString(MessageLoader::getMessage(mlParms));
        AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(
            new CIMClientMalformedHTTPException(mlString));
        AutoPtr<ClientExceptionMessage> response(
            new ClientExceptionMessage(malformedHTTPException.get()));
        malformedHTTPException.release();
        exceptionMessage = response.release();
        valid = false;

        PEG_METHOD_EXIT();
        return;
    }

    //
    // Parse the HTTP message headers and get content length
    //
    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;
        }
    }

    PEG_TRACE_CSTRING(TRC_XML_IO, Tracer::LEVEL2,
                      httpMessage->message.getData());

    //
    //  Parse HTTP message status line
    //
    String httpVersion;

    Boolean parsableMessage = HTTPMessage::parseStatusLine(
        startLine, httpVersion, statusCode, reasonPhrase);
    if (!parsableMessage)
    {
        MessageLoaderParms mlParms(
            "ExportClient.CIMExportResponseDecoder.MALFORMED_RESPONSE",
            "Malformed HTTP response message.");
        String mlString(MessageLoader::getMessage(mlParms));
        AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(
            new CIMClientMalformedHTTPException(mlString));
        AutoPtr<ClientExceptionMessage> response(
            new ClientExceptionMessage(malformedHTTPException.get()));
        malformedHTTPException.release();
        response->setCloseConnect(cimReconnect);
        exceptionMessage = response.release();
        valid = false;

        PEG_METHOD_EXIT();
        return;
    }

    PEG_METHOD_EXIT();
}

void HTTPExportResponseDecoder::validateHTTPHeaders(
    HTTPMessage* httpMessage,
    Array<HTTPHeader>& headers,
    Uint32 contentLength,
    Uint32 statusCode,
    Boolean cimReconnect,
    const String& reasonPhrase,
    char*& content,
    ClientExceptionMessage*& exceptionMessage,
    Boolean& valid)
{
    PEG_METHOD_ENTER(TRC_EXPORT_CLIENT,
        "HTTPExportResponseDecoder::validateHTTPHeaders()");

    content = 0;
    exceptionMessage = 0;
    valid = true;

    //
    // If authentication failed, a CIMClientHTTPErrorException will be
    // generated with the "401 Unauthorized" status in the (re-challenge)
    // response
    //
    // Check for a non-success (200 OK) response
    //
    if (statusCode != HTTP_STATUSCODE_OK)
    {
        String cimError;
        String pegasusError;

        HTTPMessage::lookupHeader(headers, "CIMError", cimError);
        HTTPMessage::lookupHeader(headers, PEGASUS_HTTPHEADERTAG_ERRORDETAIL,
            pegasusError);
        try
        {
            pegasusError = XmlReader::decodeURICharacters(pegasusError);
        }
        catch (const ParseError&)
        {
            // Ignore this exception.  We're more interested in having the
            // message in encoded form than knowing that the format is invalid.
        }

        AutoPtr<CIMClientHTTPErrorException> httpError(
            new CIMClientHTTPErrorException(statusCode, reasonPhrase, cimError,
                pegasusError));
        AutoPtr<ClientExceptionMessage> response(
            new ClientExceptionMessage(httpError.get()));

        httpError.release();
        response->setCloseConnect(cimReconnect);
        exceptionMessage = response.release();
        valid = false;

        PEG_METHOD_EXIT();
        return;
    }

    //
    // Check for missing "CIMExport" header
    //
    String cimExport;
    if (!HTTPMessage::lookupHeader(headers, "CIMExport", cimExport, true))
    {
        MessageLoaderParms mlParms(
            "ExportClient.CIMExportResponseDecoder.MISSING_CIMEXP_HEADER",
            "Missing CIMExport HTTP header");
        String mlString(MessageLoader::getMessage(mlParms));

        AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(new
            CIMClientMalformedHTTPException(mlString));

        AutoPtr<ClientExceptionMessage> response(
            new ClientExceptionMessage(malformedHTTPException.get()));

        malformedHTTPException.release();
        response->setCloseConnect(cimReconnect);
        exceptionMessage = response.release();
        valid = false;

        PEG_METHOD_EXIT();
        return;
    }

    //
    // Check for missing "Content-Type" header
    //
    String cimContentType;
    if (!HTTPMessage::lookupHeader(
        headers, "Content-Type", cimContentType, true))
    {
        AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(new
            CIMClientMalformedHTTPException(
                "Missing CIMContentType HTTP header"));
        AutoPtr<ClientExceptionMessage> response(
            new ClientExceptionMessage(malformedHTTPException.get()));

        malformedHTTPException.release();
        response->setCloseConnect(cimReconnect);
        exceptionMessage = response.release();
        valid = false;

        PEG_METHOD_EXIT();
        return;
    }

    //
    // Calculate the beginning of the content from the message size and
    // the content length
    //
    content = (char *) httpMessage->message.getData() +
        httpMessage->message.size() - contentLength;

    //
    // Expect CIMExport HTTP header value MethodResponse
    //
    if (!String::equalNoCase(cimExport, "MethodResponse"))
    {
        MessageLoaderParms mlParms(
            "ExportClient.CIMExportResponseDecoder.EXPECTED_METHODRESPONSE",
            "Received CIMExport HTTP header value \"$0\", "
            "expected \"MethodResponse\"", cimExport);
        String mlString(MessageLoader::getMessage(mlParms));

        AutoPtr<CIMClientMalformedHTTPException> malformedHTTPException(
            new CIMClientMalformedHTTPException(mlString));

        AutoPtr<ClientExceptionMessage> response(
            new ClientExceptionMessage(malformedHTTPException.get()));

        malformedHTTPException.release();
        response->setCloseConnect(cimReconnect);
        exceptionMessage = response.release();
        valid = false;

        PEG_METHOD_EXIT();
        return;
    }

    PEG_METHOD_EXIT();
}

void HTTPExportResponseDecoder::decodeExportResponse(
    char* content,
    Boolean cimReconnect,
    Message*& responseMessage)
{
    PEG_METHOD_ENTER (TRC_EXPORT_CLIENT,
        "HTTPExportResponseDecoder::decodeExportResponse()");

    AutoPtr<Message> response;

    //
    // Create and initialize XML parser:
    //
    XmlParser parser((char*)content);
    XmlEntry entry;

    try
    {
        //
        // Process <?xml ... >
        //
        const char* xmlVersion = 0;
        const char* xmlEncoding = 0;
        XmlReader::getXmlDeclaration(parser, xmlVersion, xmlEncoding);

        //
        // Process <CIM ... >
        //
        const char* cimVersion = 0;
        const char* dtdVersion = 0;
        XmlReader::getCimStartTag(parser, cimVersion, dtdVersion);

        //
        // Expect <MESSAGE ... >
        //
        String messageId;
        String protocolVersion;
        if (!XmlReader::getMessageStartTag(parser, messageId, protocolVersion))
        {
            MessageLoaderParms mlParms(
                "ExportClient.CIMExportResponseDecoder."
                    "EXPECTED_MESSAGE_ELEMENT",
                "expected MESSAGE element");
            String mlString(MessageLoader::getMessage(mlParms));

            PEG_METHOD_EXIT();
            throw XmlValidationError(parser.getLine(), mlString);
        }

        //
        // Check for unsupported protocol version
        //

        if (!XmlReader::isSupportedProtocolVersion(protocolVersion))
        {
            MessageLoaderParms mlParms(
                "ExportClient.CIMExportResponseDecoder.UNSUPPORTED_PROTOCOL",
                "Received unsupported protocol version \"$0\", expected \"$1\"",
                protocolVersion, "1.0");
                String mlString(MessageLoader::getMessage(mlParms));

            AutoPtr<CIMClientResponseException> responseException(
                new CIMClientResponseException(mlString));

            AutoPtr<ClientExceptionMessage> response(
                new ClientExceptionMessage(responseException.get()));

            responseException.release();
            response->setCloseConnect(cimReconnect);
            responseMessage = response.release();

            PEG_METHOD_EXIT();
            return;
        }

        //
        // Expect <SIMPLEEXPRSP ... >
        //
        XmlReader::expectStartTag(parser, entry, "SIMPLEEXPRSP");

        //
        // Expect <EXPMETHODRESPONSE ... >
        //
        const char* expMethodResponseName = 0;
        Boolean isEmptyTag = false;

        if (XmlReader::getEMethodResponseStartTag(
            parser, expMethodResponseName, isEmptyTag))
        {
            if (System::strcasecmp(expMethodResponseName, "ExportIndication")
                == 0)
            {
                response.reset(_decodeExportIndicationResponse(
                    parser, messageId, isEmptyTag));
            }
            else
            {
                //
                //  Unrecognized ExpMethodResponse name attribute
                //
                MessageLoaderParms mlParms(
                    "ExportClient.CIMExportResponseDecoder."
                        "UNRECOGNIZED_EXPMETHRSP",
                    "Unrecognized ExpMethodResponse name \"$0\"",
                    expMethodResponseName);
                String mlString(MessageLoader::getMessage(mlParms));

                PEG_METHOD_EXIT();
                throw XmlValidationError(parser.getLine(), mlString);
            }

            //
            // Handle end tag:
            //
            if (!isEmptyTag)
            {
                XmlReader::expectEndTag(parser, "EXPMETHODRESPONSE");
            }
        }
        else
        {
            //
            //  Expected ExpMethodResponse element
            //
            MessageLoaderParms mlParms(
                "ExportClient.CIMExportResponseDecoder."
                    "EXPECTED_EXPMETHODRESPONSE_ELEMENT",
                "expected EXPMETHODRESPONSE element");
            String mlString(MessageLoader::getMessage(mlParms));

            PEG_METHOD_EXIT();
            throw XmlValidationError(parser.getLine(), mlString);
        }

        //
        // Handle end tags:
        //
        XmlReader::expectEndTag(parser, "SIMPLEEXPRSP");
        XmlReader::expectEndTag(parser, "MESSAGE");
        XmlReader::expectEndTag(parser, "CIM");
    }
    catch (XmlException& x)
    {
        response.reset(new ClientExceptionMessage(
            new CIMClientXmlException(x.getMessage())));
    }
    catch (Exception& x)
    {
        response.reset(new ClientExceptionMessage(
            new CIMClientResponseException(x.getMessage())));
    }

    //
    //  Note: Ignore any ContentLanguage set in the export response
    //

    response->setCloseConnect(cimReconnect);
    responseMessage = response.release();

    PEG_METHOD_EXIT();
}

CIMExportIndicationResponseMessage*
HTTPExportResponseDecoder::_decodeExportIndicationResponse(
    XmlParser& parser,
    const String& messageId,
    Boolean isEmptyExpMethodResponseTag)
{
    PEG_METHOD_ENTER (TRC_EXPORT_CLIENT,
        "HTTPExportResponseDecoder::_decodeExportIndicationResponse()");
    XmlEntry entry;
    CIMException cimException;

    if (!isEmptyExpMethodResponseTag)
    {
        if (XmlReader::getErrorElement(parser, cimException))
        {
            PEG_METHOD_EXIT();
            return(new CIMExportIndicationResponseMessage(
                messageId,
                cimException,
                QueueIdStack()));
        }

        if (XmlReader::testStartTagOrEmptyTag(parser, entry, "IRETURNVALUE"))
        {
            if (entry.type != XmlEntry::EMPTY_TAG)
            {
                XmlReader::expectEndTag(parser, "IRETURNVALUE");
            }
        }
    }

    PEG_METHOD_EXIT();
    return(new CIMExportIndicationResponseMessage(
        messageId,
        cimException,
        QueueIdStack()));
}

PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2