[ 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
