Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
current (nightly)
-
None
-
MS Windows XP + MS ISA Proxy server + IIS
Description
HTTPTransport can not properly handle several HTTP headers in one server response.
Error in HTTPTransport.cpp in void HTTPTransport::readHTTPHeader() method:
void HTTPTransport::readHTTPHeader()
{
m_pActiveChannel->closeQuietly( false);
// The parser is expecting a SOAP message. Thus, the HTTP header must have
// been read and processed before control is returned to the parser. It can
// not be assumed that the HTTP header will be read in one block, thus there
// must be processing that first identifies the beginning of the HTTP header
// block (i.e. looks for 'HTTP') and then additional processing that identifies
// the end of the HTTP header block (i.e. looks for CR LF CR LF).
// Note that for HTTP 100 responses, we consume it and restart the process.
int numberOfBytesRead;
string::size_type iHTTPStart;
string::size_type iHTTPEnd;
do
{
resetInputStateMachine(); // <--- here
while (m_strReceived.find( ASCII_S_HTTP) == std::string::npos
m_strReceived.find( ASCII_S_CRLFCRLF) == std::string::npos) { numberOfBytesRead = m_pActiveChannel->readBytes(m_pszRxBuffer, BUF_SIZE); |
---|
if (numberOfBytesRead > 0)
{ m_strReceived += m_pszRxBuffer; m_iBytesLeft = m_strReceived.length(); }else
{ m_bReopenConnection = true; throw HTTPTransportException( SERVER_TRANSPORT_INPUT_STREAMING_ERROR, "Socket connection has been closed."); }
}
// At this point the HTTP header has been found. Seperate the response headers
// from the payload (i.e. SOAP message).
iHTTPStart = m_strReceived.find( ASCII_S_HTTP);
iHTTPEnd = m_strReceived.find( ASCII_S_CRLFCRLF, iHTTPStart);
m_strResponseHTTPHeaders = m_strReceived.substr( iHTTPStart, iHTTPEnd + 4 - iHTTPStart);
// Process the HTTP header
processHTTPHeader();
}
while( m_iResponseHTTPStatusCode == 100);
// rest of code
Proposed resolution:
void HTTPTransport::readHTTPHeader()
{
m_pActiveChannel->closeQuietly( false);
// The parser is expecting a SOAP message. Thus, the HTTP header must have
// been read and processed before control is returned to the parser. It can
// not be assumed that the HTTP header will be read in one block, thus there
// must be processing that first identifies the beginning of the HTTP header
// block (i.e. looks for 'HTTP') and then additional processing that identifies
// the end of the HTTP header block (i.e. looks for CR LF CR LF).
// Note that for HTTP 100 responses, we consume it and restart the process.
int numberOfBytesRead;
string::size_type iHTTPStart;
string::size_type iHTTPEnd;
// Initialize our state
resetInputStateMachine(); //!!! note
do
{
while (m_strReceived.find( ASCII_S_HTTP) == std::string::npos
|| m_strReceived.find( ASCII_S_CRLFCRLF) == std::string::npos)
{
numberOfBytesRead = m_pActiveChannel->readBytes(m_pszRxBuffer, BUF_SIZE);
if (numberOfBytesRead > 0)
{ m_strReceived += m_pszRxBuffer; m_iBytesLeft = m_strReceived.length(); }
else
{ m_bReopenConnection = true; throw HTTPTransportException( SERVER_TRANSPORT_INPUT_STREAMING_ERROR, "Socket connection has been closed."); }}
// At this point the HTTP header has been found. Seperate the response headers
// from the payload (i.e. SOAP message).
iHTTPStart = m_strReceived.find( ASCII_S_HTTP);
iHTTPEnd = m_strReceived.find( ASCII_S_CRLFCRLF, iHTTPStart);
m_strResponseHTTPHeaders = m_strReceived.substr( iHTTPStart, iHTTPEnd + 4 - iHTTPStart);
// Process the HTTP header
processHTTPHeader();
// trunk header and try get another
// I`m not sure that all needed info stored
m_strReceived = m_strReceived.substr(iHTTPEnd + 4); //
}
while( m_iResponseHTTPStatusCode == 100);