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

📄 httpconnection.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                            messageStart =                                (char *)contentLanguagesString.getData();                            // insert the content language line before end                            // of header                            // note: this can be expensive on large payloads                            buffer.insert(                                insertOffset, messageStart, messageLength);                            messageLength = buffer.size();                            // null terminate                            messageStart = (char *) buffer.getData();                            messageStart[messageLength] = 0;                            bytesRemaining = messageLength;                        } // if there were any content languages#ifdef PEGASUS_KERBEROS_AUTHENTICATION                        // The following is processing to wrap (encrypt) the                        // response from the server when using kerberos                        // authentications.                        // If the security association does not exist then                        // kerberos authentication is not being used.                        CIMKerberosSecurityAssociation *sa =                            _authInfo->getSecurityAssociation();                        if (sa)                        {                            // The message needs to be parsed in order to                            // distinguish between the headers and content.                            // When parsing, the code breaks out of the loop                            // as soon as it finds the double separator that                            // terminates the headers so the headers and                            // content can be easily separated.                            Boolean authrecExists = false;                            String authorization = String::EMPTY;                            if (HTTPMessage::lookupHeader(                                    headers, "WWW-Authenticate",                                    authorization, false))                            {                                authrecExists = true;                            }                            // The following is processing to wrap (encrypt)                            // the response from the server when using                            // kerberos authentications.                            sa->wrapResponseMessage(                                buffer, contentLength, authrecExists);                            messageLength = buffer.size();                            // null terminate                            messageStart = (char *) buffer.getData();                            messageStart[messageLength] = 0;                            bytesRemaining = messageLength;                        }  // endif kerberos security assoc exists#endif                    } // if this is the last chunk                    else bytesRemaining = 0;                } // if chunk request is false            } // if this is the first chunk containing the header            else            {                // if chunking was requested, then subsequent messages that are                // received need to turn response chunking on                if (isChunkRequest == true && messageIndex > 0)                {                    isChunkResponse = true;                    bytesToWrite = messageLength;                }            }            // the data is sitting in buffer, but we want to cache it in            // _incomingBuffer because there may be more chunks to append            if (isChunkRequest == false)                _incomingBuffer.swap(buffer);        } // if not a client        SignalHandler::ignore(PEGASUS_SIGPIPE);        // use the next four lines to test the SIGABRT handler        //getSigHandle()->registerHandler(PEGASUS_SIGABRT, sig_act);        //getSigHandle()->activate(PEGASUS_SIGABRT);        //Thread t(sigabrt_generator, NULL, false);        //t.run();        char *sendStart = messageStart;        Sint32 bytesWritten = 0;        if (isFirst == true && isChunkResponse == true && bytesToWrite > 0)        {            // send the header first for chunked reponses.            // dont include header terminator yet            Uint32 headerLength = bytesToWrite;            bytesToWrite -= headerLineTerminatorLength;            bytesWritten = _socket->write(sendStart, bytesToWrite);            if (bytesWritten < 0)                _socketWriteError();            totalBytesWritten += bytesWritten;            bytesRemaining -= bytesWritten;            // put in trailer header.            Buffer trailer;            trailer << headerNameTrailer << headerNameTerminator <<                _mpostPrefix << headerNameCode <<    headerValueSeparator <<                _mpostPrefix << headerNameDescription << headerValueSeparator <<                headerNameContentLanguage << headerLineTerminator;            sendStart = (char *) trailer.getData();            bytesToWrite = trailer.size();            bytesWritten = _socket->write(sendStart, bytesToWrite);            if (bytesWritten < 0)                _socketWriteError();            totalBytesWritten += bytesWritten;            // the trailer is outside the header buffer, so dont include in            // tracking variables            // now send header terminator            bytesToWrite = headerLineTerminatorLength;            sendStart = messageStart + headerLength - bytesToWrite;            bytesWritten = _socket->write(sendStart, bytesToWrite);            if (bytesWritten < 0)                _socketWriteError();            totalBytesWritten += bytesWritten;            bytesRemaining -= bytesWritten;            messageStart += headerLength;            messageLength -= headerLength;            sendStart = messageStart;            bytesWritten = 0;            bytesToWrite = bytesRemaining;        } // if first chunk of chunked response        // room enough for hex string representing chunk length and terminator        char chunkLine[sizeof(Uint32)*2 + chunkLineTerminatorLength+1];        for (; bytesRemaining > 0; )        {            if (isChunkResponse == true)            {                // send chunk line containing hex string and chunk line                // terminator                sprintf(chunkLine, "%x%s", bytesToWrite, chunkLineTerminator);                sendStart = chunkLine;                Sint32 chunkBytesToWrite = strlen(sendStart);                bytesWritten = _socket->write(sendStart, chunkBytesToWrite);                if (bytesWritten < 0)                    _socketWriteError();                totalBytesWritten += bytesWritten;            }            // for chunking, we will send the entire chunk data in one send, but            // for non-chunking, we will send incrementally            else bytesToWrite = _Min(bytesRemaining, bytesToWrite);            // send non-chunked data            //            // Socket writes larger than 64K cause some platforms to return            //  errors. When the socket write can't send the full buffer at            //  one time, subtract the bytes sent and loop until the whole            //  buffer has gone.  Use httpTcpBufferSize for maximum send size.            //            for (; bytesRemaining > 0; )            {              sendStart = messageStart + messageLength - bytesRemaining;              bytesToWrite = _Min(httpTcpBufferSize, bytesRemaining);              bytesWritten = _socket->write(sendStart, bytesToWrite);              if (bytesWritten < 0)                  _socketWriteError();              totalBytesWritten += bytesWritten;              bytesRemaining -= bytesWritten;            }            if (isChunkResponse == true)            {                // send chunk terminator, on the last chunk, it is the chunk                // body terminator                Buffer trailer;                Boolean traceTrailer = false;                trailer << chunkLineTerminator;                // on the last chunk, attach the last chunk termination                // sequence: 0 + last chunk terminator + optional trailer +                // chunkBodyTerminator                if (isLast == true)                {                    if (bytesRemaining > 0)                        _throwEventFailure(httpStatusInternal,                            "more bytes after indicated last chunk");                    trailer << "0" << chunkLineTerminator;                    Uint32 httpStatus = cimException.getCode();                    if (httpStatus != 0)                    {                        char httpStatusP[11];                        sprintf(httpStatusP, "%u",httpStatus);                        traceTrailer = true;                        trailer << _mpostPrefix << headerNameCode <<                            headerNameTerminator << httpStatusP <<                            headerLineTerminator;                        const String& httpDescription =                            cimException.getMessage();                        if (httpDescription.size() != 0)                            trailer << _mpostPrefix << headerNameDescription <<                                headerNameTerminator << httpDescription <<                                headerLineTerminator;                    }                    // Add Content-Language to the trailer if requested                    if (contentLanguages.size() != 0)                    {                        traceTrailer = true;                        trailer << _mpostPrefix                            << headerNameContentLanguage << headerNameTerminator                            << LanguageParser::buildContentLanguageHeader(                                   contentLanguages)                            << headerLineTerminator;                    }                    // now add chunkBodyTerminator                    trailer << chunkBodyTerminator;                } // if isLast                if (traceTrailer)                {                    Tracer::trace(TRC_XML_IO,Tracer::LEVEL2,                        "<!-- Trailer: queue id: %u -->\n%s \n",                        getQueueId(),                        trailer.getData());                }                sendStart = (char *) trailer.getData();                Sint32 chunkBytesToWrite = (Sint32) trailer.size();                bytesWritten = _socket->write(sendStart, chunkBytesToWrite);                if (bytesWritten < 0)                    _socketWriteError();                totalBytesWritten += bytesWritten;            } // isChunkResponse == true        } // for all bytes in message    } // try    catch (Exception &e)    {        httpStatus = e.getMessage();    }    catch (...)    {        httpStatus = HTTP_STATUS_INTERNALSERVERERROR;        String message("Unknown internal error");        Tracer::trace(__FILE__, __LINE__, TRC_HTTP, Tracer::LEVEL2, message);    }    if (isLast == true)    {        _incomingBuffer.clear();        _transferEncodingTEValues.clear();        //        // decrement request count        //        _requestCount--;        if (httpStatus.size() == 0)        {            static const char msg[] =                "A response has been sent (%d of %d bytes have been written).\n"                "There are %d requests pending within the CIM Server.\n"                "A total of %d requests have been processed on this "                    "connection.";            Tracer::trace(TRC_HTTP, Tracer::LEVEL4, msg, totalBytesWritten,                messageLength, _requestCount.get(), _connectionRequestCount);        }        //        // Since we are done writing, update the status of entry to IDLE        // and notify the Monitor.        //        if (_isClient() == false)        {            // Check for message to close            if (message.getCloseConnect()== true)            {                Tracer::trace(                    TRC_HTTP,                    Tracer::LEVEL3,                    "HTTPConnection::_handleWriteEvent - Connection: Close "                        "in client message.");                    _closeConnection();            }            else            {                Tracer::trace (TRC_HTTP, Tracer::LEVEL2,                    "Now setting state to %d", _MonitorEntry::IDLE);                _monitor->setState (_entry_index, _MonitorEntry::IDLE);                _monitor->tickle();            }            _responsePending = false;            cimException = CIMException();        }    }    return httpStatus.size() == 0 ? false : true;}void HTTPConnection::handleEnqueue(){   Message* message = dequeue();    if (!message)        return;    handleEnqueue(message);}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?    // List of request methods which do not have message bodies    const char* METHOD_NAMES[] =    {        "GET",        "HEAD"    };    // List of response codes which the client accepts and which should not

⌨️ 快捷键说明

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