axis-c-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Fred Preston (JIRA)" <axis-c-...@ws.apache.org>
Subject [jira] Commented: (AXISCPP-930) Chunked encoding is not implemented correctly
Date Thu, 23 Feb 2006 10:49:39 GMT
    [ http://issues.apache.org/jira/browse/AXISCPP-930?page=comments#action_12367489 ] 

Fred Preston commented on AXISCPP-930:
--------------------------------------

Hi Michael,
Just looking at this JIRA.  The getBytes method is basically a switch statement that has three
distinct states.  These are defined as follows:-
eWaitingForHTTPHeader :- Waiting for a 'valid' HTTP header.  A header is valid when a 'HTTP'
string is found that is subsequently followed by a CRLFCRLF sequence.  The HTTP header is
then read and if the message number is incorrect an exception is thrown.  The header also
contains information on whether the accompanying message is or is not chunked.
eSOAPMessageIsChunked :- When a message is chunked, it has been broken into a number of blocks.
 Each block is preceeded by a hex number.  The number is the chunk length.  A zero length
chunk represents the end of the message.  NB: because AXIS uses a 'pull' parser, the last
chunk size should never be read as the parser will return once it has encountered '</envelope>'.
 If it does read the last '0', this could indicate that there is a problem in the message.
eSOAPMessageIsNotChunked :- The message is read until the number of message bytes read equals
the HTTP header content length value.

State 'eWaitingForHTTPHeader' calls readHTTPHeader() which waits for a valid HTTP header.
 The buffer m_strReceived is emptied and then m_pActiveChannel is called to copy any Rx'ed
data into a temporary buffer (m_pszRxBuffer).  This buffer is then appended to the m_strReceived
buffer.  This process continues until a HTTP header is detected or timeout.  If we assume
that a HTTP header is deteted before the timeout, then whatever data has been captured will
be held in m_strReceived.  The method will then calls the method processHTTPHeader, which
does just that. Depending on the header information it will change the state (m_GetBytesState)
to be either chunked (eSOAPMessageIsChunked) or non-chunked (eSOAPMessageIsNotChunked).  Or,
if after further processing the HTTP header is not recognised as valid, it will change the
state back to eWaitingForHTTPHeader and throw an exception.  If all is still well, then the
method calls checkHTTPStatusCode which checks the HTTP status code.  After that the HTTP header
is removed from the buffer (m_strReceived) leaving it pointing to the first character after
the HTTP header (m_iBytesLeft contains the length of this remaining string).  If the message
is valid the method will drop out of the bottom of the 'eWaitingForHTTPHeader' state and into
the 'eSOAPMessageIsChunked' state.

State 'eSOAPMessageIsChunked' first checks that the state is infact 'eSOAPMessageIsChunked'
and if it is, it begins to process the data in the buffer (m_strReceived).  If the buffer
is empty (m_iBytesLeft = 0), the first method to be called is getNextDataPacket which will
wait for more data to be Rx'ed (if data is recieved, it will be appended to the buffer (m_strReceived)
and the length (m_iBytesLeft) will be updated) or timeout and throw an exception.  The method
will then call getChunkSize to read the hex digits that should be the first characters of
the buffer and puts the decimal equivalent into m_iContentLength.  The method will then enter
a loop, that can only be exited when either enough data is recieved or there is a timeout
(causing an exception to be thrown).  If the length of the buffer is greater than the expected
chunk length, then save the data past the chunk size in a temporary buffer (nextChunk). Then,
set the buffer (m_strReceived) to the size of the chunk (m_iContentLength).

State 'eSOAPMessageIsNotChunked' uses m_iContentLength to countdown the remaining size of
data that is expected.  While m_iContentLength is greater than 0, it will call getNextDataPacket
to get any Rx'ed data and append that to the buffer (m_strReceived).

At then end of the switch statement is a section of 'common' code that call copyDataToParserBuffer
that copies m_iBytesLeft of the buffer (m_strReceived) into the XMLParser buffer (pcBuffer)
and then removes the first m_iBytesLeft from the buffer (m_strReceived).  Finally, then temporary
buffer (nextChunk) is appended back onto the buffer (m_strReceived) and the new buffer size
is found.

I think what you are looking at is old code, because what you are describing no longer happens.
 I cannot see a situation where what you are describing can happen, but I can only test this
if you can send me your WSDL and response message.

Regards,

Fred Preston.

> Chunked encoding is not implemented correctly
> ---------------------------------------------
>
>          Key: AXISCPP-930
>          URL: http://issues.apache.org/jira/browse/AXISCPP-930
>      Project: Axis-C++
>         Type: Bug
>   Components: Transport (axis3), Transport (axis2)
>     Versions: 1.5 Final
>  Environment: Solaris 8
>     Reporter: Michael Dufel

>
> <Rant>The chunked transfer encoding is broken and results in a 'peekNextChar' error
 similar to the one described in AXISCPP-555. I was forced to re-write HTTPTransport::getBytes()
from almost the ground up because of the unreadableness of the code. Nested do/while loops???
Come on ... Yes I know, I am a code snob. </Rant> 
> I believe the problem in the original code was reflected in the case that the buffer
from the channel contains data in the following form:
> <some continued data>CRLF
> <chunk length 1>CRLF
> <some data 1><CRLF>
> <chunk length 2>CRLF
> <some data 2>CRLF
> .
> .
> .
> <chunk length n>CRLF
> <some data n>
> everything after <chunk length 2> was being dropped by the transport library. The
transport library sends a 'TRANSPORT FINISHED' response and the xml parser is only given a
partial message to deal with. This causes the 'peekNextChar' error. 
> Yes, I know that solaris 8 is not supported in Axis 1.5, but this is a protocol issue,
not a platform related issue. Again, since I had to re-write the getBytes method, I can't
offer a code snippet which will 'magically' fix this problem. 

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


Mime
View raw message