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

📄 httpconnection.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // (normally) have message bodies.  The RFC is vague regarding which    // response codes support or require bodies.  These are being reported by    // class (4xx, 5xx, etc) because the CIM client should be able to handle    // any status code, including those not explicitly defined in RFC 2616.    // Therefore, listing codes individually will not work because the client    // socket will hang on a code not in this list if no content length is    // specified.    // See bugzilla 1586    const char* RESPONSE_CODES[] =    {        "HTTP/1.1 3XX",        "HTTP/1.0 3XX",        "HTTP/1.1 4XX",        "HTTP/1.0 4XX",        "HTTP/1.1 5XX",        "HTTP/1.0 5XX"    };    // Check for bodyless HTTP request method    const Uint32 METHOD_NAMES_SIZE = sizeof(METHOD_NAMES) / sizeof(char*);    for (Uint32 i = 0; i < METHOD_NAMES_SIZE; i++)    {        Uint32 n = strlen(METHOD_NAMES[i]);        if (strncmp(line, METHOD_NAMES[i], n) == 0 && isspace(line[n]))            return true;    }    // Check for bodyless HTTP status code    const Uint32 RESPONSE_CODES_SIZE = sizeof(RESPONSE_CODES) / sizeof(char*);    for (Uint32 i = 0; i < RESPONSE_CODES_SIZE; i++)    {        Uint32 n = strlen(RESPONSE_CODES[i]);        if (strncmp(line, RESPONSE_CODES[i], n - 2) == 0 && isspace(line[n]))                return true;            }    return false;}/*Boolean _IsBodylessMessage(const char* line){    //ATTN: Make sure this is the right place to check for HTTP/1.1 and    //      HTTP/1.0 that is part of the authentication challenge header.    // ATTN-RK-P2-20020305: How do we make sure we have the complete list?    const char* METHOD_NAMES[] =    {        "GET",        "HTTP/1.1 400",        "HTTP/1.0 400",        "HTTP/1.1 401",        "HTTP/1.0 401",        "HTTP/1.1 413",        "HTTP/1.0 413",        "HTTP/1.1 500",        "HTTP/1.0 500",        "HTTP/1.1 501",        "HTTP/1.0 501",        "HTTP/1.1 503",        "HTTP/1.0 503"    };    const Uint32 METHOD_NAMES_SIZE = sizeof(METHOD_NAMES) / sizeof(char*);    for (Uint32 i = 0; i < METHOD_NAMES_SIZE; i++)    {        Uint32 n = strlen(METHOD_NAMES[i]);        if (strncmp(line, METHOD_NAMES[i], n) == 0 && isspace(line[n]))            return true;    }    return false;}*/void HTTPConnection::_getContentLengthAndContentOffset(){    static const char func[] =    "HTTPConnection::_getContentLengthAndContentOffset";    Uint32 size = _incomingBuffer.size();    if (size == 0)        return;    char* data = (char*)_incomingBuffer.getData();    char* line = (char*)data;    char* sep;    Uint32 lineNum = 0;    Boolean bodylessMessage = false;    Boolean gotContentLength = false;    Boolean gotTransferEncoding = false;    Boolean gotContentLanguage = false;    Boolean gotTransferTE = false;    while ((sep = _FindSeparator(line, size - (line - data))))    {        char save = *sep;        *sep = '\0';        // Did we find the double separator which terminates the headers?        if (line == sep)        {            *sep = save;            line = sep + ((save == '\r') ? 2 : 1);            _contentOffset = line - _incomingBuffer.getData();            // reserve space for entire non-chunked message            if (_contentLength > 0)            {                try                {                    Uint32 capacity = (Uint32)(_contentLength +                        _contentOffset + 1);                    _incomingBuffer.reserveCapacity(capacity);                    data = (char *)_incomingBuffer.getData();                    data[capacity-1] = 0;                }                catch (const PEGASUS_STD(bad_alloc)&)                {                    _throwEventFailure(HTTP_STATUS_REQUEST_TOO_LARGE,                        "Error reserving space for non-chunked message");                }                catch (...)                {                    _throwEventFailure(                        httpStatusInternal, "unexpected exception");                }            }            break;        }        // If this is one of the bodyless methods, then we can assume the        // message is complete when the "\r\n\r\n" is encountered.        if (lineNum == 0 && _IsBodylessMessage(line))            bodylessMessage = true;        // Look for the content-length if not already found:        char* colon = strchr(line, ':');        if (colon)        {            *colon  = '\0';            // remove whitespace after colon before value            char *valueStart = colon + 1;            while (*valueStart == ' ' || *valueStart == '\t')                valueStart++;            // we found some non-whitespace token            if (valueStart != sep)            {                char *valueEnd = sep - 1;                // now remove whitespace from end of line back to last byte                // of value                while (*valueEnd == ' ' || *valueEnd == '\t')                    valueEnd--;                char valueSave = *(valueEnd+1);                if (System::strcasecmp(line, headerNameContentLength) == 0)                {                    if (gotContentLength)                    {                        _throwEventFailure(HTTP_STATUS_BADREQUEST,                            "Duplicate Content-Length header detected");                    }                    gotContentLength = true;                    if (_transferEncodingValues.size() == 0)                    {                        // Use a dummy character conversion to catch an                        // invalid character in the value.                        char dummy;                        if (sscanf(valueStart, "%d%c",                                &_contentLength, &dummy) != 1)                        {                            _throwEventFailure(HTTP_STATUS_BADREQUEST,                                "Invalid Content-Length header detected");                        }                    }                    else                    {                        _contentLength = -1;                    }                }                else if (System::strcasecmp(                             line, headerNameTransferEncoding) == 0)                {                    if (gotTransferEncoding)                    {                        _throwEventFailure(HTTP_STATUS_BADREQUEST,                            "Duplicate Transfer-Encoding header detected");                    }                    gotTransferEncoding = true;                    _transferEncodingValues.clear();                    if (strcmp(valueStart,                            headerValueTransferEncodingChunked) == 0)                        _transferEncodingValues.append(                            headerValueTransferEncodingChunked);                    else if (strcmp(valueStart,                                 headerValueTransferEncodingIdentity) == 0)                        ; // do nothing                    else _throwEventFailure(HTTP_STATUS_NOTIMPLEMENTED,                             "unimplemented transfer-encoding value");                    _contentLength = -1;                }                else if (System::strcasecmp(                             line, headerNameContentLanguage) == 0)                {                    // note: if this is a chunked header, then this will be                    // ignored later                    String contentLanguagesString(                        valueStart, valueEnd - valueStart + 1);                    try                    {                        ContentLanguageList contentLanguagesValue =                            LanguageParser::parseContentLanguageHeader(                                contentLanguagesString);                        if (gotContentLanguage)                        {                            // Append these content languages to the existing                            // list.                            for (Uint32 i = 0;                                 i < contentLanguagesValue.size(); i++)                            {                                contentLanguages.append(                                    contentLanguagesValue.getLanguageTag(i));                            }                        }                        else                        {                            contentLanguages = contentLanguagesValue;                            gotContentLanguage = true;                        }                    }                    catch (...)                    {                        Tracer::trace(TRC_HTTP, Tracer::LEVEL2,                            "HTTPConnection: ERROR: contentLanguages had "                                "parsing failure. clearing languages. error "                                "data=%s",                            (const char *)contentLanguagesString.getCString());                        contentLanguages.clear();                    }                }                else if (System::strcasecmp(line, headerNameTransferTE) == 0)                {                    if (gotTransferTE)                    {                        _throwEventFailure(HTTP_STATUS_BADREQUEST,                            "Duplicate TE header detected");                    }                    gotTransferTE = true;                    _transferEncodingTEValues.clear();                    static const char valueDelimiter = ',';                    char *valuesStart = valueStart;                    // now tokenize the values                    while (*valuesStart)                    {                        // strip off whitepsace from the front                        while (*valuesStart == ' ' || *valuesStart == '\t')                            valuesStart++;                        if (valuesStart == valueEnd)                            break;                        char *v = strchr(valuesStart, valueDelimiter);                        if (v)                        {                            if (v == valuesStart)                            {                                valuesStart++;                                continue;                            }                            v--;                            // strip off whitespace from the end                            while (*v == ' ' || *v == '\t')                                v--;                            v++;                            *v = 0;                        }                        _transferEncodingTEValues.append(valuesStart);                        if (v)                        {                            *v = valueDelimiter;                            valuesStart = v+1;                        }                        else break;                    }                }                *(valueEnd+1) = valueSave;            } // if some value tokens            *colon = ':';        }        *sep = save;        line = sep + ((save == '\r') ? 2 : 1);        lineNum++;    }    if (_contentOffset != -1 && bodylessMessage)        _contentLength = 0;}void HTTPConnection::_clearIncoming(){    _contentOffset = -1;    _contentLength = -1;    _incomingBuffer.clear();    _mpostPrefix.clear();    contentLanguages.clear();}void HTTPConnection::_closeConnection(){    // return - don't send the close connection message.    // let the monitor dispatch function do the cleanup.    PEG_METHOD_ENTER(TRC_HTTP, "HTTPConnection::_closeConnection");

⌨️ 快捷键说明

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