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

📄 httpconnection.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    _connectionClosePending = true;    // NOTE: if there is a response pending while a close connection request    // occurs, then this indicates potential activity on this connection apart    // from this thread of execution (although this code here is locked, other    // threads may be waiting on this one.)    // The caller MUST check this value before attempting a delete of this    // connnection, otherwise the delete may occur while other chunked responses    // are waiting to be delivered through this connection.    // This condition may happen on a client error/timeout/interrupt/disconnect    if (_isClient() == false)    {        if (_responsePending == true)        {            Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,                "HTTPConnection::_closeConnection - Close connection "                    "requested while responses are still expected on this "                    "connection. connection=0x%p, socket=%d\n",                (void*)this, getSocket());        }        // still set to DYING        Tracer::trace(TRC_HTTP, Tracer::LEVEL2,            "Now setting state to %d", _MonitorEntry::DYING);        _monitor->setState (_entry_index, _MonitorEntry::DYING);        _monitor->tickle();    }    if (_connectionRequestCount == 0)    {        Tracer::trace(TRC_HTTP, Tracer::LEVEL4,            "HTTPConnection::_closeConnection - Connection being closed "                "without receiving any requests.");    }    PEG_METHOD_EXIT();//    Message* message= new CloseConnectionMessage(_socket->getSocket));//    message->dest = _ownerMessageQueue->getQueueId();//    SendForget(message);//    _ownerMessageQueue->enqueue(message);}Boolean HTTPConnection::isChunkRequested(){    Boolean answer = false;    if (_transferEncodingTEValues.size() > 0 &&        (Contains(_transferEncodingTEValues, String(headerValueTEchunked)) ||         Contains(_transferEncodingTEValues, String(headerValueTEtrailers))))        answer = true;#ifdef PEGASUS_KERBEROS_AUTHENTICATION    CIMKerberosSecurityAssociation *sa = _authInfo->getSecurityAssociation();    if (sa)    {        answer = false;    }#endif    return answer;}void HTTPConnection::setSocketWriteTimeout(Uint32 socketWriteTimeout){        _socket->setSocketWriteTimeout(socketWriteTimeout);}// determine if the current code being executed is on the client sideBoolean HTTPConnection::_isClient(){    return strcmp(get_owner().getQueueName(),        PEGASUS_QUEUENAME_HTTPCONNECTOR) == 0 ? true : false;}/* * determine if the data read in should be treated as transfer encoded data. * If so, proceed to strip out the transfer encoded meta data within the body * but the headers relating to transfer encoding will remain unchanged. * One should refer to the transfer encoding section of the HTTP protocol * specification to understand the parsing semantics below. * NOTE: this function is coded as a syncronous read! The entire message will * be read in before the message leaves this class and is passed up to the * client application. */void HTTPConnection::_handleReadEventTransferEncoding(){    static const char func[] =        "HTTPConnection::_handleReadEventTransferEncoding";    PEG_METHOD_ENTER(TRC_HTTP, func);    Uint32 messageLength = _incomingBuffer.size();    Uint32 headerLength = (Uint32) _contentOffset;    // return immediately under these conditions:    // - Header terminator has not been reached yet (_contentOffset < 0)    // - This is a non-transfer encoded message because the content length    //   has been set from the given header value (_contentLength > 0)    //   (_contentLength == 0 means bodyless, so return too - section 4.3)    // - The message read in so far is <= to the header length    // - No transfer encoding has been declared in the header.    if (_contentOffset < 0 || _contentLength >= 0 ||        messageLength <= headerLength || _transferEncodingValues.size() == 0)    {        PEG_METHOD_EXIT();        return;    }    // on the first chunk in the message, set the encoding offset to the content    // offset    if (_transferEncodingChunkOffset == 0)        _transferEncodingChunkOffset = (Uint32) _contentOffset;    char *headerStart = (char *) _incomingBuffer.getData();    char *messageStart = headerStart;    // loop thru the received data (so far) and strip out all chunked meta data.    // this logic assumes that the data read in may be only partial at any point    // during the parsing. the variable _transferEncodingChunkOffset represents    // the byte offset (from the start of the message) of the last NON completed    // chunk parsed within the message. Remember that the tcp reader has padded    // the buffer with a terminating null for easy string parsing.    for (;;)    {        // we have parsed the length, but not all bytes of chunk have been read        // in yet        if (_transferEncodingChunkOffset >= messageLength)            break;        // this is the length from _transferEncodingChunkOffset to the end        // of the message (so far). It represents the bytes that have not been        // processed yet        Uint32 remainderLength = messageLength - _transferEncodingChunkOffset;        // the start of the first fully non-parsed chunk of this interation        char *chunkLineStart = messageStart + _transferEncodingChunkOffset;        char *chunkLineEnd = chunkLineStart;        // Find the end of the hex string representing the data portion        // length of the current chunk. Note that we must hit at least one        // non-hexdigit (except null) to know we have read in the complete        // number        while (isxdigit(*chunkLineEnd))            chunkLineEnd++;        if (! *chunkLineEnd)            break;        // This is the parsed chunk length in hex. From here on, this many bytes        // plus the chunk terminator (AFTER this chunk line is done) must be        // read in to constitute a complete chunk in which        // _transferEncodingChunkOffset can be incremented to the next chunk        Uint32 chunkLengthParsed =            (Uint32) strtoul((const char *)chunkLineStart, 0, 16);        // this also covers strings stated even larger        if (chunkLengthParsed == PEG_NOT_FOUND)            _throwEventFailure(HTTP_STATUS_REQUEST_TOO_LARGE,                "stated chunk length too large");        char *chunkExtensionStart = chunkLineEnd;        chunkLineEnd = strstr(chunkLineEnd, chunkLineTerminator);        // If we have not received the chunk line terminator yet, then        // return and wait for the next iteration. This is done because the        // hex length given only represents the non-meta data, not the chunk        // line itself.        if (!chunkLineEnd)            break;        // the token after the hex digit must be either the chunk line        // terminator or the chunk extension terminator. If not, the sender        // has sent an illegal chunked encoding syntax.        if (strncmp(chunkExtensionStart, chunkExtensionTerminator,                chunkExtensionTerminatorLength) != 0 &&            strncmp(chunkExtensionStart, chunkLineTerminator,                chunkLineTerminatorLength) != 0)        {            _throwEventFailure(                HTTP_STATUS_BADREQUEST, "missing chunk extension");        }        chunkLineEnd += chunkLineTerminatorLength;        Uint32 chunkLineLength = chunkLineEnd - chunkLineStart;        Uint32 chunkMetaLength = chunkLineLength;        if (chunkLengthParsed > 0)            chunkMetaLength += chunkTerminatorLength;        Uint32 chunkTerminatorOffset = _transferEncodingChunkOffset +            chunkLineLength + chunkLengthParsed;        // The parsed length represents the non-meta data bytes which starts        // after the chunk line terminator has been received.        // If we dont have enough remainder bytes to process from the length        // parsed then return and wait for the next iteration.        //        // Also, if this is the last chunk, then we have to know if there        // is enough data in here to be able to verify that meta crlf for        // the end of the whole chunked message is present.        // If chunkLengthParsed + chunkMetaLenght == reminderLength, it        // means that there is a space only for meta crlf of the last chunk.        // Therefore go back and re-read socket until you get enough data        // for at least 2 crlfs.  One for the end of the last chunk or        // the end of the optional trailer, and one for the end of whole        // message.        if (chunkLengthParsed + chunkMetaLength >= remainderLength)            break;        // at this point we have a complete chunk. proceed and strip out        // meta-data        // NOTE: any time "remove" is called on the buffer, many variables        // must be recomputed to reflect the data removed.        // remove the chunk length line        _incomingBuffer.remove(_transferEncodingChunkOffset, chunkLineLength);        messageLength = _incomingBuffer.size();        // always keep the byte after the last data byte null for easy string        // processing.        messageStart[messageLength] = 0;        // recalculate since we just removed the chunk length line        chunkTerminatorOffset -= chunkLineLength;        // is this the last chunk ?        if (chunkLengthParsed == 0)        {            // We are at the last chunk. The only remaining data should be:            // 1. optional trailer first            // 2. message terminator (will remain on incoming buffer and            //    passed up)            remainderLength -= chunkLineLength;            CIMStatusCode cimStatusCode = CIM_ERR_SUCCESS;            Uint32 httpStatusCode = HTTP_STATUSCODE_OK;            String httpStatus;            String cimErrorValue;            // is there an optional trailer ?            if (remainderLength > chunkBodyTerminatorLength)            {                Uint32 trailerLength =                    remainderLength - chunkBodyTerminatorLength;                Uint32 trailerOffset = _transferEncodingChunkOffset;                char *trailerStart = messageStart + trailerOffset;                char *trailerTerminatorStart = trailerStart + trailerLength -                    trailerTerminatorLength;                // no trailer terminator before end of chunk body ?                if (strncmp(trailerTerminatorStart, trailerTerminator,                        trailerTerminatorLength) != 0)                    _throwEventFailure(HTTP_STATUS_BADREQUEST,                        "No chunk trailer terminator received");                Buffer trailer;                // add a dummy startLine so that the parser works                trailer << " " << headerLineTerminator;                char save = trailerStart[trailerLength];                trailerStart[trailerLength] = 0;                trailer << trailerStart;                trailerStart[trailerLength] = save;                _incomingBuffer.remove(trailerOffset, trailerLength);                messageLength = _incomingBuffer.size();                messageStart[messageLength] = 0;                remainderLength -= trailerLength;                // parse the trailer looking for the code and description                String startLine;                Array<HTTPHeader> headers;                Uint32 contentLength = 0;                HTTPMessage httpTrailer(trailer);                httpTrailer.parse(startLine, headers, contentLength);                String cimErrorName = headerNameError;                // first look for cim error. this is an http level error                Boolean found = false;                found = httpTrailer.lookupHeader(                    headers, cimErrorName, cimErrorValue, true);                if (found == true)                {                    // we have a cim error. parse the header to get the                    // original http level error if any, otherwise, we have                    // to make one up.                    Buffer header(messageStart, headerLength);                    String startLine;                    Array<HTTPHeader> headers;                    Uint32 contentLength = 0;                    HTTPMessage httpHeader(header);                    httpHeader.parse(startLine, headers, contentLength);                    String httpVersion;                    Boolean isValid = httpHeader.parseStatusLine(                        startLine, httpVersion, httpStatusCode,httpStatus);                    if (isValid == false || httpStatusCode == 0 ||                            httpStatusCode == HTTP_STATUSCODE_OK)                    {                        // ATTN: make up our own http code if not given ?                        httpStatusCode = (Uint32) HTTP_STATUSCODE_BADREQUEST;                        httpStatus = HTTP_STATUS_BADREQUEST;                    }                }                else                {                    String codeName = headerNameCode;                    String codeValue;                    found = httpTrailer.lookupHeader(                        headers, codeName, codeValue, true);                    if (found == true && codeValue.size() > 0 &&                        (cimStatusCode = (CIMStatusCode)atoi(                             codeValue.getCString())) > 0)                    {                        HTTPM

⌨️ 快捷键说明

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