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

📄 httpconnection.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//%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 "Network.h"#include <iostream>#include <cctype>#include <cstdlib>#include "Signal.h"#include "Socket.h"#include "TLS.h"#include "HTTPConnection.h"#include "MessageQueue.h"#include "Monitor.h"#include "HTTPMessage.h"#include "Tracer.h"#include "Buffer.h"#include "LanguageParser.h"#ifdef PEGASUS_KERBEROS_AUTHENTICATION#include <Pegasus/Common/CIMKerberosSecurityAssociation.h>#endif#include <Pegasus/Common/XmlWriter.h>PEGASUS_USING_STD;PEGASUS_NAMESPACE_BEGIN// initialize the request countAtomicInt HTTPConnection::_requestCount(0);//////////////////////////////////////////////////////////////////////////////////// Local routines:///////////////////////////////////////////////////////////////////////////////////* * string and number constants for HTTP sending/receiving */// buffer size for sending receivingstatic const Uint32 httpTcpBufferSize = 8192;// string constants for HTTP header. "Name" represents strings on the left// side of headerNameTerminator and "Value" represents strings on the right// side of headerNameTerminator#define headerNameTrailer "Trailer"#undef CRLF#define CRLF "\r\n"static const char headerNameTransferTE[] = "TE";static const char headerNameTransferEncoding[] = "transfer-encoding";static const char headerNameContentLength[] = "content-length";static const char headerValueTransferEncodingChunked[] = "chunked";static const char headerValueTransferEncodingIdentity[] = "identity";static const char headerValueTEchunked[] = "chunked";static const char headerValueTEtrailers[] = "trailers";static const char headerNameError[] = "CIMError";static const char headerNameCode[] = "CIMStatusCode";static const char headerNameDescription[] = "CIMStatusCodeDescription";static const char headerNameOperation[] = "CIMOperation";static const char headerNameContentLanguage[] = "Content-Language";// the names comes from the HTTP specification on chunked transfer encodingstatic const char headerNameTerminator[] = ": ";static const char headerValueSeparator[] = ", ";static const char headerLineTerminator[] = CRLF;static const char headerTerminator[] = CRLF CRLF;static const char chunkLineTerminator[] = CRLF;static const char chunkTerminator[] = CRLF;static const char chunkBodyTerminator[] = CRLF;static const char trailerTerminator[] = CRLF;static const char chunkExtensionTerminator[] = ";";// string sizesstatic const Uint32 headerNameContentLengthLength =    sizeof(headerNameContentLength) - 1;static const Uint32 headerValueTransferEncodingChunkedLength =    sizeof(headerValueTransferEncodingChunked) - 1;static const Uint32 headerNameTransferEncodingLength =    sizeof(headerNameTransferEncoding) - 1;static const Uint32 headerNameTerminatorLength =sizeof(headerNameTerminator)-1;static const Uint32 headerLineTerminatorLength =sizeof(headerLineTerminator)-1;static const Uint32 chunkLineTerminatorLength = sizeof(chunkLineTerminator)-1;static const Uint32 chunkTerminatorLength = sizeof(chunkTerminator)-1;static const Uint32 chunkBodyTerminatorLength = sizeof(chunkBodyTerminator)-1;static const Uint32 trailerTerminatorLength = sizeof(trailerTerminator)-1;static const Uint32 chunkExtensionTerminatorLength =    sizeof(chunkExtensionTerminator) - 1;// the number of bytes it takes to place a Uint32 into a string (minus null)static const Uint32 numberAsStringLength = 10;/* * given an HTTP status code, return the description. not all codes are listed * here. Unmapped codes result in the internal error string. * Add any required future codes here. */static const String httpDetailDelimiter = headerValueSeparator;static const String httpStatusInternal = HTTP_STATUS_INTERNALSERVERERROR;/* * throw given http code with detail, file, line * This is shared client/server code. The caller will decide what to do * with the thrown message */static void _throwEventFailure(const String &status, const String &detail,    const char *func,    const char *file , Uint32 line){    String message = status + httpDetailDelimiter + detail;    Tracer::trace(file, line, TRC_HTTP, Tracer::LEVEL2, message);    if (status == httpStatusInternal)        throw AssertionFailureException(file, line, message);    else throw Exception(message);}// throw a http exception. This is used for both client and server common code.// The macro allows is used for file, line inclusion for debugging#define _throwEventFailure(status, detail) \  _throwEventFailure(status, String(detail), func, __FILE__, __LINE__)#define _socketWriteError()                                                   \    do                                                                        \    {                                                                         \        Tracer::trace(__FILE__, __LINE__, TRC_DISCARDED_DATA, Tracer::LEVEL2, \            "Socket write failed with error %d; could not write response "    \                "to client.  (Client may have timed out.)",                   \            getSocketError());                                                \        throw Exception("socket write error");                                \    }                                                                         \    while (0)static inline Uint32 _Min(Uint32 x, Uint32 y){    return x < y ? x : y;}static char* _FindSeparator(const char* data, Uint32 size){    const char* p = data;    const char* end = p + size;    while (p != end)    {        if (*p == '\r')        {            Uint32 n = end - p;            if (n >= 2 && p[1] == '\n')                return (char*)p;        }        else if (*p == '\n')            return (char*)p;        p++;    }    return 0;}// Used to test signal handlingvoid * sigabrt_generator(void * parm){    abort();    return 0;}//////////////////////////////////////////////////////////////////////////////////// HTTPConnection//////////////////////////////////////////////////////////////////////////////////HTTPConnection::HTTPConnection(    Monitor* monitor,    AutoPtr<MP_Socket>& socket,    const String& ipAddress,    MessageQueue* ownerMessageQueue,    MessageQueue* outputMessageQueue)    :    Base(PEGASUS_QUEUENAME_HTTPCONNECTION),    _monitor(monitor),    _socket(socket),    _ipAddress(ipAddress),    _ownerMessageQueue(ownerMessageQueue),    _outputMessageQueue(outputMessageQueue),    _contentOffset(-1),    _contentLength(-1),    _connectionClosePending(false),    _acceptPending(false){    PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnection::HTTPConnection");    _socket->disableBlocking();    _authInfo.reset(new AuthenticationInfo(true));    // Add SSL verification information to the authentication information    if (_socket->isSecure())    {#ifndef PEGASUS_PLATFORM_ZOS_ZSERIES_IBM        if (_socket->isPeerVerificationEnabled() &&            _socket->isCertificateVerified())        {            _authInfo->setAuthStatus(AuthenticationInfoRep::AUTHENTICATED);            _authInfo->setAuthType(AuthenticationInfoRep::AUTH_TYPE_SSL);            _authInfo->setClientCertificateChain(                _socket->getPeerCertificateChain());        }#else        if (_socket->isClientAuthenticated())        {            _authInfo->setAuthStatus(AuthenticationInfoRep::AUTHENTICATED);            _authInfo->setAuthenticatedUser(_socket->getAuthenticatedUser());        }#endif    }    _responsePending = false;    _connectionRequestCount = 0;    _transferEncodingChunkOffset = 0;    PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,        "Connection IP address = " + _ipAddress);    _authInfo->setIpAddress(_ipAddress);    PEG_METHOD_EXIT();}HTTPConnection::~HTTPConnection(){    PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnection::~HTTPConnection");     _socket->close();    PEG_METHOD_EXIT();}void HTTPConnection::enqueue(Message *message){    handleEnqueue(message);}void HTTPConnection::handleEnqueue(Message *message){    PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnection::handleEnqueue");    if (! message)    {        PEG_METHOD_EXIT();        return;    }    AutoMutex connectionLock(_connection_mut);    switch (message->getType())    {        case SOCKET_MESSAGE:        {            Tracer::trace(TRC_HTTP, Tracer::LEVEL4,                "HTTPConnection::handleEnqueue - SOCKET_MESSAGE");            SocketMessage* socketMessage = (SocketMessage*)message;            if (socketMessage->events & SocketMessage::READ)                _handleReadEvent();            break;        }        case HTTP_MESSAGE:        {            Tracer::trace(TRC_HTTP, Tracer::LEVEL4,                "HTTPConnection::handleEnqueue - HTTP_MESSAGE");            _handleWriteEvent(*message);            break;        }        default:            // ATTN: need unexpected message error!            break;    } // switch    delete message;    PEG_METHOD_EXIT();}/* * handle the message coming down from the above. This is shared client and * server code. If the message is coming in chunks, then validate the chunk * sequence number. If the message is being processed on the server side, * make sure the client has requested transfer encodings and/or trailers before

⌨️ 快捷键说明

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