You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@axis.apache.org by "Samisa Abeysinghe (JIRA)" <ax...@ws.apache.org> on 2005/03/11 08:41:52 UTC

[jira] Closed: (AXISCPP-518) Call to method getBytes of the class HTTPTransport never returns a value different from TRANSPORT_IN_PROGRESS

     [ http://issues.apache.org/jira/browse/AXISCPP-518?page=history ]
     
Samisa Abeysinghe closed AXISCPP-518:
-------------------------------------

     Resolution: Fixed
    Fix Version: 1.5 Final

Applied rest of the changes. Now all requasted changes are in CVS

> Call to method getBytes of the class HTTPTransport never returns a value different from TRANSPORT_IN_PROGRESS
> -------------------------------------------------------------------------------------------------------------
>
>          Key: AXISCPP-518
>          URL: http://issues.apache.org/jira/browse/AXISCPP-518
>      Project: Axis-C++
>         Type: Bug
>   Components: Transport (axis3)
>     Versions: unspecified
>  Environment: The bug affects all platforms
>     Reporter: Arcangelo Di Balsamo
>     Assignee: Samisa Abeysinghe
>      Fix For: 1.5 Final
>  Attachments: HTTPTransport.cpp, HTTPTransportcpp diff.txt, HTTPTrasportTestClient.zip
>
> I got a bug in the http trasport library ( HTTPTransport). I wrote a simple test client to reproduce the problem (I can send the test program, if you want ).
> The problem is that the method getBytes of the class HTTPTransport never returns a value different from TRANSPORT_IN_PROGRESS. That makes the caller to loop forever.
> I tried to workaround the problem by checking the size of the ruturned buffer in the client, but that led to data truncation. 
> The regression suite should be modified too. In fact you should try to use a buffer smaller than the size of the expected response from the server.
> I've already made a fix: the affected module is HTTPTransport.cpp.
> The modified code is :
> /*
> *   Copyright 2003-2004 The Apache Software Foundation.
> *
> *   Licensed under the Apache License, Version 2.0 (the "License");
> *   you may not use this file except in compliance with the License.
> *   You may obtain a copy of the License at
> *
> *       http://www.apache.org/licenses/LICENSE-2.0
> *
> *   Unless required by applicable law or agreed to in writing, software
> *   distributed under the License is distributed on an "AS IS" BASIS,
> *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> *   See the License for the specific language governing permissions and
> *   limitations under the License.
> */
> /*
>  * @author Samisa Abeysinghe (sabeysinghe@virtusa.com)
>  *
>  */
> #ifdef WIN32
> #pragma warning (disable : 4786)
> #pragma warning (disable : 4101)
> #endif
> #include "HTTPTransport.hpp"
> #include <stdio.h>
> #include <iostream>
> /*
>  * HTTPTransport constuctor
>  */
> HTTPTransport::HTTPTransport ():m_bReopenConnection (false),
> m_strHTTPProtocol ("HTTP/1.1"),
> m_strHTTPMethod ("POST"),
> m_bChunked (false),
> m_bReadPastHTTPHeaders (false),
> m_strProxyHost (""), m_uiProxyPort (0), m_bUseProxy (false),
> m_bMaintainSession (false)
> {
>     m_pcEndpointUri = NULL;
>     m_pReleaseBufferCallback = 0;
>     m_eProtocolType = APTHTTP1_1;
>     m_strBytesToSend = "";
>     m_strHeaderBytesToSend = "";
>     m_iBytesLeft = 0;
>     m_iContentLength = 0;
>     m_pcReceived = 0;
> 	m_bChannelSecure = false;
>     m_pNormalChannel = 0;
>     m_pSecureChannel = 0;
> 	m_pActiveChannel = 0;
>     m_pChannelFactory = new ChannelFactory();
>     m_bMimeTrue = false;
>     m_viCurrentHeader = m_vHTTPHeaders.begin();
> 	m_pszRxBuffer = new char [BUF_SIZE];
> #ifdef WIN32
> 	m_lChannelTimeout = 10;
> #else
> 	m_lChannelTimeout = 0;
> #endif
> }
> /*
>  * HTTPTransport destuctor
>  */
> HTTPTransport::~HTTPTransport()
> {
>     if( m_pcEndpointUri)
>     {
> 	delete[] m_pcEndpointUri;
>     }
>     if( m_pChannelFactory)
> 	{
> 		delete m_pChannelFactory;
> 		m_pChannelFactory = 0;
> 	}
> 	delete [] m_pszRxBuffer;
> }
> /*
>  * HTTPTransport::setEndpointUri( EndpointURI) sets the URI for the message.
>  * Everytime the endpoint changes then currently connected channel is closed
>  * and a new channel connection is opened.
>  *
>  * @param	EndpointURI - char * to a null terminated string that holds the
>  *			new URI. 
>  */
> void HTTPTransport::setEndpointUri( const char * pcEndpointUri) throw (HTTPTransportException)
> {
>     bool bUpdateURL = false;
>     // Get the current channel URI
>     if( m_pActiveChannel != NULL && m_pActiveChannel->getURL())
>     {
> 	// Does the new URI equal the existing channel URI?
> 		if( strcmp (m_pActiveChannel->getURL (), pcEndpointUri) != 0)
> 		{
> 	    // There is a new URI.
> 			bUpdateURL = true;
> 		}
>     }
>     else
>     {
> 		bUpdateURL = true;
>     }
>     // If there is a new URI, then this flag will be set.  Depending on whether
>     // there is an SSL implementation available, if the new URI is a secure
> 	// connection, a secure channel will be opened.  If an SSL implementation
> 	// is not available and the URL requires a secure connection then an
> 	// exception will be thrown.
>     if( bUpdateURL)
>     {
> 		if( m_pActiveChannel == NULL)
> 		{
> 			m_pActiveChannel = m_pNormalChannel;
> 		}
> 		m_pActiveChannel->setURL( pcEndpointUri);
> 		m_bReopenConnection = true;
> 	// Check if the new URI requires SSL (denoted by the https prefix).
> 		if( (m_pActiveChannel->getURLObject()).getProtocol() == URL::https)
> 		{
> 			if( m_pSecureChannel != NULL)
> 			{
> 				m_pNormalChannel->close();
> 				m_pActiveChannel = m_pSecureChannel;
> 				m_pActiveChannel->setURL( pcEndpointUri);
> 				m_bChannelSecure = true;
> 			}
> 			if( !m_bChannelSecure)
> 			{
> 				throw HTTPTransportException( CLIENT_TRANSPORT_HAS_NO_SECURE_TRANSPORT_LAYER);
> 			}
> 		}
> 		else
> 		{
> 	    // URI does not require a secure channel.  Delete the existing
> 	    // channel if it is secure and create a new unsecure
> 	    // channel.
> 			if (m_bChannelSecure)
> 			{
> 				if( m_pNormalChannel != NULL)
> 				{
> 					m_pSecureChannel->close();
> 					m_pActiveChannel = m_pNormalChannel;
> 					m_pActiveChannel->setURL( pcEndpointUri);
> 					m_bChannelSecure = false;
> 				}
> 				if( m_bChannelSecure)
> 				{
> 					throw HTTPTransportException( CLIENT_TRANSPORT_HAS_NO_UNSECURE_TRANSPORT_LAYER);
> 				}
> 			}
> 		}
>     }
> // Need this code to set the channel timeout.  If the timeout was changed
> // before the channel was created, then it may not have the correct timeout.
> // By setting it here, the channel is sure to have the correct timeout value
> // next time the channel is read.
> 	if( m_pActiveChannel != NULL)
> 	{
> 		m_pActiveChannel->setTimeout( m_lChannelTimeout);
> 	}
> }
> /*
>  * HTTPTransport::openConnection().
>  */
> int HTTPTransport::openConnection()
> {
> 	return m_pActiveChannel->open();
> }
> /*
>  * HTTPTransport::closeConnection().
>  */
> void HTTPTransport::closeConnection()
> {
>     // get ready for a new message.
>     m_bReadPastHTTPHeaders = false;
>     //clear the message buffer in preperation of the next read.
>     m_strReceived = "";
>     m_iContentLength = 0;
> 	if( m_pActiveChannel != NULL)
> 	{
> 		m_pActiveChannel->close();
> 	}
> }
> /*
>  * HTTPTransport::flushOutput() Is called when the message construction is
>  * complete.  The message is ready to be 'flushed out' onto the network.  
>  * Check if the URI has changed.  If it has, then need to open a new Channel
>  * instance before transmitting the message.
>  *
>  * @return AXIS_TRANSPORT_STATUS If the method completes successfully, then
>  * this will be set to TRANSPORT_FINISHED.  Otherwise, an exception will have
>  * been thrown.
>  */
> AXIS_TRANSPORT_STATUS HTTPTransport::flushOutput() throw (HTTPTransportException)
> {
>     if( m_bReopenConnection)
>     {
> 		m_bReopenConnection = false;
> 		if( m_pActiveChannel->open() != AXIS_SUCCESS)
> 		{
> 		    int				iStringLength = m_pActiveChannel->GetLastErrorMsg().length() + 1;
> 			const char *	pszLastError = new char[iStringLength];
> 		    memcpy( (void *) pszLastError,
> 					m_pActiveChannel->GetLastErrorMsg().c_str(),
> 					iStringLength);
> 		    throw HTTPTransportException( CLIENT_TRANSPORT_OPEN_CONNECTION_FAILED,
> 										  (char *) pszLastError);
> 			}
> 		}
>     // In preperation for sending the message, calculate the size of the message
>     // by using the string length method.
>     // NB: This calculation may not necessarily be correct when dealing with SSL
>     //     messages as the length of the encoded message is not necessarily the
>     //         same as the length of the uncoded message.
>     char buff[8];
> 	sprintf( buff, "%d", m_strBytesToSend.length ());
>     this->setTransportProperty ("Content-Length", buff);
>     // The header is now complete.  The message header and message can now be
>     // transmitted.
> 	try
> 	{
> 		*m_pActiveChannel << this->getHTTPHeaders ();
> 		*m_pActiveChannel << this->m_strBytesToSend.c_str ();
> 	}
> 	catch( HTTPTransportException & e)
> 	{
> 		throw;
> 	}
> 	catch( AxisException & e)
> 	{
> 		throw;
> 	}
> 	catch(...)
> 	{
> 		throw;
> 	}
>     // Empty the bytes to send string.
> 	m_strBytesToSend = "";
> 	m_strHeaderBytesToSend = "";
> 	return TRANSPORT_FINISHED;
> }
> /* HTTPTransport::getHTTPHeaders() Called to retreive the current HTTP header
>  * information block that will preceed the SOAP message.
>  *
>  * @return const char* Pointer to a NULL terminated character string containing
>  * the HTTP header block of information.
>  */
> const char * HTTPTransport::getHTTPHeaders()
> {
>     URL &			url = m_pActiveChannel->getURLObject();
>     unsigned short	uiPort = url.getPort();
>     char			buff[8];
>     m_strHeaderBytesToSend = m_strHTTPMethod + " ";
>     m_strHeaderBytesToSend += std::string (url.getResource ()) + " ";
>     m_strHeaderBytesToSend += m_strHTTPProtocol + "\r\n";
>     m_strHeaderBytesToSend += std::string ("Host: ") + url.getHostName ();
>     sprintf (buff, "%u", uiPort);
>     m_strHeaderBytesToSend += ":";
>     m_strHeaderBytesToSend += buff;
>     m_strHeaderBytesToSend += "\r\n";
>     m_strHeaderBytesToSend += "Content-Type: text/xml; charset=UTF-8\r\n";
>     // Set other HTTP headers
>     for (unsigned int i = 0; i < m_vHTTPHeaders.size (); i++)
>     {
> 		m_strHeaderBytesToSend += m_vHTTPHeaders[i].first;
> 		m_strHeaderBytesToSend += ": ";
> 		m_strHeaderBytesToSend += m_vHTTPHeaders[i].second;
> 		m_strHeaderBytesToSend += "\r\n";
>     }
>     // Set session cookie
>     if (m_bMaintainSession && (m_strSessionKey.size () > 0))
>     {
> 		m_strHeaderBytesToSend += "Cookie";
> 		m_strHeaderBytesToSend += ": ";
> 		m_strHeaderBytesToSend += m_strSessionKey;
> 		m_strHeaderBytesToSend += "\r\n";
>     }
>     m_strHeaderBytesToSend += "\r\n";
>     return m_strHeaderBytesToSend.c_str ();
> }
> /* HTTPTransport::getHTTPMethod() Is a public method that gets the HTTP method
>  * (i.e. GET or POST) that will be part of the HTTP header block.
>  *
>  * @return const char* Pointer to a NULL terminated character string containing
>  * the HTTP method.
>  */
> const char * HTTPTransport::getHTTPMethod()
> {
>     return m_strHTTPMethod.c_str ();
> }
> /* HTTPTransport::setHTTPMethod( Method) Is a public method that sets the HTTP
>  * method (i.e. POST or GET) that will be part of the HTTP header block.
>  *
>  * @param const char* Pointer to a NULL terminated character string containing
>  * the new HTTP method.
>  */
> void HTTPTransport::setHTTPMethod( const char *cpMethod)
> {
>     m_strHTTPMethod = std::string( cpMethod);
> }
> /* HTTPTransport::sendBytes( SendBuffer, BufferId) Is a public method that
>  * concatinates the new send buffer to the bytes to send string.  This message
>  * will only be sent when a flush buffer is received.
>  *
>  * @param const char* SendBufer - Pointer to a NULL terminated character string
>  * containing all or some of the transmission message.
>  * @param const void* BufferId - Pointer.  This parameter is ignored.
>  *
>  * @return AXIS_TRANSPORT_STATUS Value to a status value (currently it will
>  * always be TRANSPORT_IN_PROGRESS).
>  */
> AXIS_TRANSPORT_STATUS HTTPTransport::sendBytes( const char *pcSendBuffer, const void *pBufferId)
> {
>     m_strBytesToSend += std::string (pcSendBuffer);
>     return TRANSPORT_IN_PROGRESS;
> }
> /* HTTPTransport::getBytes( ReceiveBuffer, Size) Is a public method that will
>  * receive the synchronous reply to the sent message.
>  *
>  * @param const char* ReceiveBuffer - Pointer to a character string that on
>  * return will containing all or part of the received message.
>  * @param int* Size - Pointer to an integer value that on return will contain
>  * the length of the received message.
>  *
>  * @return AXIS_TRANSPORT_STATUS Value to the status o message reception
>  * (TRANSPORT_FINISHED or TRANSPORT_IN_PROGRESS).
>  */
> AXIS_TRANSPORT_STATUS HTTPTransport::getBytes( char *pcBuffer, int *pSize) throw (AxisException, HTTPTransportException)
> {
>     if (0 >= m_iBytesLeft)
>     {
> 		try
> 		{
> 			m_pszRxBuffer [0] = '\0';
> 			*m_pActiveChannel >> m_pszRxBuffer;
> 			m_strReceived = m_pszRxBuffer;
> 		    if( !m_bReadPastHTTPHeaders)
> 		    {
> 				unsigned int start = std::string::npos;
> 				do
> 				{
> 					do
> 					{
> 						if (m_strReceived.find( "\r\n\r\n") == std::string::npos)
> 						{
> 							m_pszRxBuffer [0] = '\0';
> 							*m_pActiveChannel >> m_pszRxBuffer;
> 						    m_strReceived += m_pszRxBuffer;
> 						}
> 					} while( m_strReceived.find( "\r\n\r\n") == std::string::npos);
> 					if( m_strReceived.find ("HTTP") == std::string::npos)
> 					{
> 			// Most probably what we read was left overs from earlier reads
> 			// Skip this \r\n\r\n
> 						m_strReceived = m_strReceived.substr( m_strReceived.find( "\r\n\r\n") + 4);
> 						do
> 						{
> 							if( m_strReceived.find( "\r\n\r\n") == std::string::npos)
> 							{
> 								m_pszRxBuffer [0] = '\0';
> 								*m_pActiveChannel >> m_pszRxBuffer;
> 								m_strReceived += m_pszRxBuffer;
> 							}
> 						} while( m_strReceived.find( "\r\n\r\n") == std::string::npos);
> 			// now this must contain HTTP. Else there is a conent error.
> 					}
> 		    //now we have found the end of headers
> 					m_bReadPastHTTPHeaders = true;
> 				    unsigned int pos = 0;
> 		    // Look for content lenght
> 				    if( (pos = m_strReceived.find( "Content-Length: ")) != std::string::npos)
> 					{
> 						m_iContentLength = atoi( m_strReceived.substr( pos + strlen( "Content-Length: "),
> 																	   m_strReceived.find( "\n", pos)).c_str());
> 				    }
> 		    // Check if the message is chunked
> 				    if( (pos = m_strReceived.find( "Transfer-Encoding: chunked")) != std::string::npos)
> 					{
> 						m_bChunked = true;
> 					}
> 					else
> 					{
> 						m_bChunked = false;
> 					}
> 		    // check if there is HTTP header. If not, there must be an error and 
> 		    // will be detected by processResponseHTTPHeaders()
> 		    // However, must make sure that the left overs from eatlier reads
> 		    // do not appear before HTTP/1.x
> 					start = m_strReceived.find( "HTTP");
> 					if( start == std::string::npos)
> 					{
> 						start = 0;
> 					}
> 		    // Extract HTTP headers and process them
> 				    m_strResponseHTTPHeaders = m_strReceived.substr( start,
> 																     m_strReceived.find( "\r\n\r\n") + 2 - start);
> 				    processResponseHTTPHeaders();
> 				    if( m_iResponseHTTPStatusCode == 100)
> 				    {
> 			// Samisa: We found Continue. Keep on reading and processing headers
> 			// till we get a HTTP code other than 100
> 			// Here it is assumed that the whole of the request is already sent
> 						m_pszRxBuffer [0] = '\0';
> 						*m_pActiveChannel >> m_pszRxBuffer;
> 						m_strReceived = m_pszRxBuffer;
> 					}
> 				} while( m_iResponseHTTPStatusCode == 100);
>                 if ( m_iResponseHTTPStatusCode != 500 &&
>                     ( m_iResponseHTTPStatusCode < 200 || m_iResponseHTTPStatusCode >= 300 ))
> 				{
> 				    throw HTTPTransportException( SERVER_TRANSPORT_HTTP_EXCEPTION,
> 												  const_cast <char *> (m_strResponseHTTPStatusMessage.c_str()));
> 				}
> 		// Done with HTTP headers, get payload
> 				m_strReceived = m_strReceived.substr( m_strReceived.find( "\r\n\r\n", start) + 4);
> 		    }
> 	    // Read past headers. Deal with payload
> 	    // make sure we have a message with some content
> 		    if( m_strReceived.length () == 0)
> 			{
> 				m_pszRxBuffer [0] = '\0';
> 				*m_pActiveChannel >> m_pszRxBuffer;
> 				m_strReceived = m_pszRxBuffer;
> 			}
> 			if( m_strReceived.length () > 0) 
> 			{
> 			    if( m_bChunked && m_iContentLength < 1)	// Read first chunk
> 				{
> 			/*
> 			 *Chunked data looks like ->
> 			 *      Chunked-Body   = *chunk
> 			 *                       "0" CRLF
> 			 *                       footer
> 			 *                       CRLF
> 			 *
> 			 *      chunk          = chunk-size [ chunk-ext ] CRLF
> 			 *                         chunk-data CRLF
> 			 *
> 			 *      hex-no-zero    = <HEX excluding "0">
> 			 *
> 			 *      chunk-size     = hex-no-zero *HEX
> 			 *      chunk-ext      = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
> 			 *      chunk-ext-name = token
> 			 *      chunk-ext-val  = token | quoted-string
> 			 *      chunk-data     = chunk-size(OCTET)
> 			 *
> 			 *      footer         = *entity-header
> 			 */
> 			// firstly read in the chunk size line.
> 			//There might be chunk extensions in there too but we may not need them
> 					unsigned int endOfChunkData = m_strReceived.find( "\r\n");
> 			// make sure we have read at least some part of the message
> 					if( endOfChunkData == std::string::npos)
> 					{
> 						do
> 						{
> 							m_pszRxBuffer [0] = '\0';
> 							*m_pActiveChannel >> m_pszRxBuffer;
> 							m_strReceived = m_pszRxBuffer;
> 							endOfChunkData = m_strReceived.find( "\r\n");
> 						} while( endOfChunkData == std::string::npos);
> 					}
> 					int endOfChunkSize = endOfChunkData;
> 			// now get the size of the chunk from the data
> 			// look to see if there are any extensions - these are put in brackets so look for those
> 					if( m_strReceived.substr( 0, endOfChunkData).find( "(") != string::npos)
> 					{
> 						endOfChunkSize = m_strReceived.find( "(");
> 					}
> 			// convert the hex String into the length of the chunk
> 					m_iContentLength = axtoi( (char *) m_strReceived.substr( 0, endOfChunkSize).c_str());
> 			// if the chunk size is zero then we have reached the footer
> 			// If we have reached the footer then we can throw it away because we don't need it
> 					if( m_iContentLength > 0)
> 					{
> 				// now get the chunk without the CRLF
> 				// check if we have read past chunk length
> 						if( m_strReceived.length() >= (endOfChunkData + 2 + m_iContentLength))
> 						{
> 							m_strReceived = m_strReceived.substr( endOfChunkData + 2, m_iContentLength);
> 						}
> 						else	// we have read lesser than chunk length
> 						{
> 							m_strReceived = m_strReceived.substr( endOfChunkData + 2);
> 						}
> 				/* We have received part of chunk data. If received payload
> 				 *  is a mime struct, process it
> 				 */
> 						if( m_bMimeTrue)
> 						{
> 							processRootMimeBody();
> 						}
> 					}
> 					else
> 					{
> 						m_strReceived = "";
> 					}
> 				}
> 				else if( m_bChunked)	// read continued portions of a chunk
> 				{
> 			// Samisa - NOTE: It looks as if there is some logic duplication
> 			// in this block, where we read continued chunks and the block
> 			// above, where we read the first chunk. However, there are slight
> 			// logical differences here, and that is necessary to enable the
> 			// pull model used by the parser - this logic makes pulling more
> 			// efficient (30th Sept 2004)
> 					if( m_strReceived.length () >= m_iContentLength)	// We have reached end of current chunk
> 					{
> 				// Get remainder of current chunk
> 						std::string strTemp = m_strReceived.substr( 0, m_iContentLength);
> 				// Start looking for the next chunk
> 				// The format we are expecting here is:
> 				// <previous chunk>\r\n<chunk size>\r\n<next chunk>
> 						unsigned int endOfChunkData = m_strReceived.find( "\r\n");
> 				// Make sure that we have the found the end of previous chunk
> 						while( endOfChunkData == std::string::npos)
> 						{
> 							m_pszRxBuffer [0] = '\0';
> 							*m_pActiveChannel >> m_pszRxBuffer;
> 							m_strReceived += m_pszRxBuffer;
> 							endOfChunkData = m_strReceived.find( "\r\n");
> 						}
> 						m_strReceived = m_strReceived.substr( endOfChunkData + 2);	// Skip end of previous chunk
> 						endOfChunkData = m_strReceived.find( "\r\n");	// Locate the start of next chunk
> 				// Make sure that we have the starting line of next chunk
> 						while( endOfChunkData == std::string::npos)
> 						{
> 							m_pszRxBuffer [0] = '\0';
> 							*m_pActiveChannel >> m_pszRxBuffer;
> 							m_strReceived += m_pszRxBuffer;
> 							endOfChunkData = m_strReceived.find( "\r\n");
> 						}
> 						int endOfChunkSize = endOfChunkData;
> 				// look to see if there are any extensions - these are put in brackets so look for those
> 						if (m_strReceived.substr (0, endOfChunkData).find ("(") != string::npos)
> 						{
> 							endOfChunkSize = m_strReceived.find ("(");
> 						}
> 				// convert the hex String into the length of the chunk
> 						int iTempContentLength = axtoi( (char *) m_strReceived.substr( 0, endOfChunkSize).c_str());
> 				// if the chunk size is zero then we have reached the footer
> 				// If we have reached the footer then we can throw it away because we don't need it
> 						if( iTempContentLength > 0)
> 						{
> 				// Update the content lenght to be remainde of previous chunk and lenght of new chunk
> 							m_iContentLength += iTempContentLength;
> 				// now get the chunk without the CRLF
> 				// check if we have read past chunk length
> 							if( m_strReceived.length() >= (endOfChunkData + 2 + iTempContentLength))
> 							{
> 								m_strReceived = m_strReceived.substr( endOfChunkData + 2, iTempContentLength);
> 							}
> 							else
> 							{
> 								m_strReceived = m_strReceived.substr( endOfChunkData + 2);
> 							}
> 				/* We have received part of chunk data. If received payload
> 				 *  is a mime struct, process it
> 				 */
> 							if( m_bMimeTrue)
> 							{
> 								processRootMimeBody();
> 							}
> 						}
> 						else
> 						{
> 							m_strReceived = "";
> 						}
> 				// Append the data of new chunk to data from previous chunk
> 						m_strReceived = strTemp + m_strReceived;
> 						}		// End of if (m_strReceived.length() >= m_iContentLength)
> 			// If we have not reached end of current chunk, nothing to be done
> 					}
> 					else		// Not chunked
> 					{
> 				//nothing to do here
> 				/* We have received part of chunk data. If received payload
> 				 *  is a mime struct, process it
> 				 */
> 						if( m_bMimeTrue)
> 						{
> 							processRootMimeBody();
> 						}
> 					}
> 				}
> 				m_pcReceived = m_strReceived.c_str();
> 				if( m_pcReceived)
> 				{
> 					m_iBytesLeft = strlen( m_pcReceived);
> 				}
> 				else
> 				{
> 					throw HTTPTransportException( SERVER_TRANSPORT_BUFFER_EMPTY, "Recieved null");
> 				}
> 				m_iContentLength -= m_iBytesLeft;
> 		}
> 		catch( HTTPTransportException & e)
> 		{
> 			throw;
> 		}
> 		catch( AxisException & e)
> 		{
> 		    throw;
> 		}
> 		catch(...)
> 		{
> 		    throw;
> 		}
>     }
>     if (( m_pcReceived) && (*m_pcReceived))
>     {
> 		int iToCopy = (*pSize < m_iBytesLeft) ? *pSize : m_iBytesLeft;
> 		strncpy( pcBuffer, m_pcReceived, iToCopy);
> 		m_iBytesLeft -= iToCopy;
> 		m_pcReceived += iToCopy;
> 		*pSize = iToCopy;
> 		return TRANSPORT_IN_PROGRESS;
> 	}
> 	else
> 	{
> 		m_bReadPastHTTPHeaders = false;	// get ready for a new message
> 		m_strReceived = "";	//clear the message buffer in preperation of the next read
> 		return TRANSPORT_FINISHED;
>     }
> }
> /* HTTPTransport::setTransportProperty( Type, Value) Is an overloaded public
>  * method used to set a HTTP transport or SSL implementation property.
>  *
>  * @param AXIS_TRANSPORT_INFORMATION_TYPE Type is an enumerated type containing
>  * the type of information to be stored in either the HTTP Header or SSL
>  * implementation settings.
>  * @param const char* Value is a NULL terminated character string containing
>  * the value associated with the type.
>  */
> void HTTPTransport::setTransportProperty( AXIS_TRANSPORT_INFORMATION_TYPE type, const char *value) throw (HTTPTransportException)
> {
>     const char *key = NULL;
>     switch (type)
>     {
> 	    case SOAPACTION_HEADER:
> 		{
> 			key = "SOAPAction";
> 		    break;
> 		}
> 		case SERVICE_URI:		// need to set ?
> 		{
> 			break;
> 		}
> 		case OPERATION_NAME:	// need to set ?
> 		{
> 			break;
> 		}
> 		case SOAP_MESSAGE_LENGTH:
> 		{
> 			key = "Content-Length";	// this Axis transport handles only HTTP
> 			break;
> 		}
> 		case TRANSPORT_PROPERTIES:
> 		{
> 			m_pActiveChannel->setTransportProperty( type, value);
> 			break;
> 		}
> 		case SECURE_PROPERTIES:
> 		{
> 			m_pActiveChannel->setSecureProperties( value);
> 			break;
> 		}
> 		case CHANNEL_HTTP_DLL_NAME:
> 		{
> 			m_pNormalChannel = m_pChannelFactory->LoadChannelLibrary( UnsecureChannel, value);
> 			break;
> 		}
> 		case CHANNEL_HTTP_SSL_DLL_NAME:
> 		{
> 			m_pSecureChannel = m_pChannelFactory->LoadChannelLibrary( SecureChannel, value);
> 			break;
> 		}
> 		default:
> 		{
> 			break;
> 		}
>     }
>     if( key)
>     {
> 		setTransportProperty( key, value);
>     }
> }
> /* HTTPTransport::setTransportProperty( Key, Value) Is an overloaded public
>  * method used to set a HTTP transport or SSL implementation property.
>  *
>  * @param const char* Key is a NULL terminated character string containing
>  * the type of information to be stored in either the HTTP Header or SSL
>  * implementation settings.
>  * @param const char* Value is a NULL terminated character string containing
>  * the value associated with the type.
>  */
> void HTTPTransport::setTransportProperty( const char *pcKey, const char *pcValue) throw (HTTPTransportException)
> {
>     if( !pcKey || !pcValue)	// Samisa - fix for AXISCPP-295. We must check for valid values here.
> 	{
> 		return;
> 	}
>     bool b_KeyFound = false;
>     if( strcmp( pcKey, "SOAPAction") == 0 || strcmp( pcKey, "Content-Length") == 0)
>     {
> 		std::string strKeyToFind = std::string( pcKey);
> 		for (unsigned int i = 0; i < m_vHTTPHeaders.size(); i++)
> 		{
> 		    if (m_vHTTPHeaders[i].first == strKeyToFind)
> 			{
> 				m_vHTTPHeaders[i].second = (string) pcValue;
> 				b_KeyFound = true;
> 				break;
> 		    }
> 		}
>     }
>     if( !b_KeyFound)
>     {
> 		m_vHTTPHeaders.push_back( std::make_pair( (string) pcKey, (string) pcValue));
>     }
> }
> /* HTTPTransport::getTransportProperty( Type) Is a public method that will
>  * return the HTTP Header/SSL implementation value associated with type.
>  *
>  * @param AXIS_TRANSPORT_INFORMATION_TYPE Type is an enumerated type containing
>  * the type of information to be retrieved in either the HTTP Header or SSL
>  * implementation settings.
>  *
>  * @return const char* Value is a NULL terminated character string containing
>  * the value associated with the type.
>  */
> const char * HTTPTransport::getTransportProperty( AXIS_TRANSPORT_INFORMATION_TYPE eType) throw (HTTPTransportException)
> {
>     const char *pszPropValue = NULL;
>     switch( eType)
>     {
> 	    case SOAPACTION_HEADER:
> 		{
> 			int iIndex = FindTransportPropertyIndex( "SOAPAction");
> 		    if (iIndex > -1)
> 		    {
> 				pszPropValue = m_vHTTPHeaders[iIndex].second.c_str();
> 		    }
> 		    break;
> 		}
> 	    case SERVICE_URI:
> 		{
> 			break;
> 		}
> 	    case OPERATION_NAME:
> 		{
> 			break;
> 		}
> 	    case SOAP_MESSAGE_LENGTH:
> 		{
> 			int iIndex = FindTransportPropertyIndex( "Content-Length");
> 		    if (iIndex > -1)
> 		    {
> 				pszPropValue = m_vHTTPHeaders[iIndex].second.c_str();
> 		    }
> 		    break;
> 		}
> 	case TRANSPORT_PROPERTIES:
>     case SECURE_PROPERTIES:
> 		{
> 			pszPropValue = m_pActiveChannel->getTransportProperty( eType);
> 			break;
> 		}
> 	case CHANNEL_HTTP_SSL_DLL_NAME:
> 	case CHANNEL_HTTP_DLL_NAME:
> 		{
> 			break;
> 		}
>     }
>     return pszPropValue;
> }
> /* HTTPTransport::FindTransportPropertyIndex( Key) Is a private method that will
>  * return the HTTP Header index associated with Key.
>  *
>  * @param AXIS_TRANSPORT_INFORMATION_TYPE Key is an enumerated type containing
>  * the type of information to be retrieved in either the HTTP Header settings.
>  *
>  * @return int Index is an index to the key within the HTTP Header list.  If
>  * the return value is -1, then the key was not found.
>  */
> int HTTPTransport::FindTransportPropertyIndex( string sKey)
> {
>     bool	bKeyFound = false;
>     int		iIndex = 0;
>     do
>     {
> 		if (!m_vHTTPHeaders[iIndex].first.compare( sKey))
> 		{
> 			bKeyFound = true;
> 		}
> 		else
> 		{
> 			iIndex++;
> 		}
>     } while( (unsigned int) iIndex < m_vHTTPHeaders.size() && !bKeyFound);
>     if( !bKeyFound)
>     {
> 		iIndex = -1;
>     }
>     return iIndex;
> }
> /* HTTPTransport::getServiceName() Is a public method to return the HTTP
>  * Header service name.
>  *
>  * @return const char* Value is a NULL terminated character string containing
>  * the value associated with the service name.
>  */
> const char * HTTPTransport::getServiceName()
> {
>     //Assume SOAPAction header to contain service name
>     int		iIndex = FindTransportPropertyIndex( "SOAPAction");
>     if (iIndex > -1)
>     {
> 		return m_vHTTPHeaders[iIndex].second.c_str();
>     }
>     return NULL;
> }
> AXIS_PROTOCOL_TYPE HTTPTransport::getProtocol()
> {
>     return m_eProtocolType;
> }
> int HTTPTransport::setProtocol( AXIS_PROTOCOL_TYPE eProtocol)
> {
>     if (eProtocol == APTHTTP1_1 || eProtocol == APTHTTP1_0)
>     {
> 		m_eProtocolType = eProtocol;
> 		m_strHTTPProtocol = (m_eProtocolType == APTHTTP1_1) ? "HTTP/1.1" : "HTTP/1.0";
> 		return AXIS_SUCCESS;
>     }
>     else
> 	{
> 		return AXIS_FAIL;
> 	}
> }
> /**
>  * HTTPTransport::getSubProtocol() is a public method that is supposed to
>  * return the sub protocol (currently this method always return 0).
>  * This method is supposed to return whether it is http GET or POST
>  */
> int HTTPTransport::getSubProtocol()
> {
>     //TODO
>     // for SimpleAxisServer assume POST
>     return AXIS_HTTP_POST;
>     //return 0;
> }
> /* HTTPTransport::setProxy( Host, Port) Is a public method for setting or
>  * updating the proxy for the connection.
>  *
>  * @param const char* Host is a NULL terminated character string containing the new
>  * proxy host.
>  * @param unsigned int Port is the new proxy port number.
>  */
> void HTTPTransport::setProxy( const char *pcProxyHost, unsigned int uiProxyPort)
> {
>     m_strProxyHost = pcProxyHost;
>     m_uiProxyPort = uiProxyPort;
>     m_bUseProxy = true;
> }
> /* HTTPTransport::setTimeout( Timeout) Is a public method for setting the
>  * current maximum timeout period between that can elapse between receiving
>  * message parts.
>  *
>  * @param const long Timeout is a long value in seconds.
>  */
> void HTTPTransport::setTimeout( const long lSeconds)
> {
> 	if( m_pActiveChannel != NULL)
> 	{
> 		m_pActiveChannel->setTimeout( lSeconds);
> 	}
> 	m_lChannelTimeout = lSeconds;
> }
> /* HTTPTransport::getHTTPProtocol() Is a public method for retrieving the
>  * current HTTP protocol settings.
>  *
>  * @return const char* HTTPProtocol is a NULL terminated character string
>  * containing the HTTP protocol.
>  */
> const char * HTTPTransport::getHTTPProtocol()
> {
>     return m_strHTTPProtocol.c_str ();
> }
> /* axtoi( Hex) Is a private method to convert an ascii hex string to an integer.
>  */
> int axtoi( char *pcHexStg)
> {
>     int		iN = 0;			// position in string
>     int		iM = 0;			// position in digit[] to shift
>     int		iCount;			// loop index
>     int		intValue = 0;	// integer value of hex string
>     int		iDigit[32];		// hold values to convert
>     while( iN < 32)
>     {
> 		if( pcHexStg[iN] == '\0')
> 		{
> 			break;
> 		}
> 	
> 		if( pcHexStg[iN] > 0x29 && pcHexStg[iN] < 0x40)	//if 0 to 9
> 		{
> 			iDigit[iN] = pcHexStg[iN] & 0x0f;	//convert to int
> 		}
> 		else if (pcHexStg[iN] >= 'a' && pcHexStg[iN] <= 'f')	//if a to f
> 		{
> 			iDigit[iN] = (pcHexStg[iN] & 0x0f) + 9;	//convert to int
> 		}
> 		else if (pcHexStg[iN] >= 'A' && pcHexStg[iN] <= 'F')	//if A to F
> 		{
> 			iDigit[iN] = (pcHexStg[iN] & 0x0f) + 9;	//convert to int
> 		}
> 		else
> 		{
> 			break;
> 		}
> 	iN++;
>     }
>     iCount = iN;
>     iM = iN - 1;
>     iN = 0;
>     while( iN < iCount)
>     {
> 	// digit[n] is value of hex digit at position n
> 	// (m << 2) is the number of positions to shift
> 	// OR the bits into return value
> 		intValue = intValue | (iDigit[iN] << (iM << 2));
> 		iM--;			// adjust the position to set
> 		iN++;			// next digit to process
>     }
>     return intValue;
> }
> /* HTTPTransport::processResponseHTTPHeaders() Is a public method used to
>  * parse the HTTP header of the response message.
>  */
> void HTTPTransport::processResponseHTTPHeaders() throw (HTTPTransportException)
> {
>     unsigned int iPosition = std::string::npos;
>     unsigned int iStartPosition = iPosition;
>     if( (iPosition = m_strResponseHTTPHeaders.find( "HTTP")) != std::string::npos)
>     {
> 		m_strResponseHTTPProtocol = m_strResponseHTTPHeaders.substr( iPosition, strlen( "HTTP/1.x"));
> 		iPosition += strlen( "HTTP/1.x");
> 		while( m_strResponseHTTPHeaders.substr()[iPosition] == ' ')
> 		{
> 			iPosition++;
> 		}
> 		iStartPosition = iPosition;
> 		while( m_strResponseHTTPHeaders.substr()[iPosition] != ' ')
> 		{
> 			iPosition++;
> 		}
> 		std::string strResponseHTTPStatusCode = m_strResponseHTTPHeaders.substr( iStartPosition,
> 																				 iPosition - iStartPosition);
> 		m_iResponseHTTPStatusCode = atoi( strResponseHTTPStatusCode.c_str());
> 		iStartPosition = ++iPosition;
> 		iPosition = m_strResponseHTTPHeaders.find( "\n");
> 		m_strResponseHTTPStatusMessage = m_strResponseHTTPHeaders.substr( iStartPosition,
> 																		  iPosition - iStartPosition - 1);
> 	// reached the end of the first line
> 		iStartPosition = m_strResponseHTTPHeaders.find( "\n");
> 		iStartPosition++;
> 	// read header fields and add to vector
> 		do
> 		{
> 		    m_strResponseHTTPHeaders = m_strResponseHTTPHeaders.substr( iStartPosition);
> 			iPosition = m_strResponseHTTPHeaders.find( "\n");
> 		    if( iPosition == std::string::npos)
> 		    {
> 				break;
> 			}
> 			std::string		strHeaderLine = m_strResponseHTTPHeaders.substr( 0, iPosition);
> 			unsigned int	iSeperator = strHeaderLine.find(":");
> 		    if( iSeperator == std::string::npos)
> 			{
> 				break;
> 			}
> 			iStartPosition = iPosition + 1;
> 			string	key = strHeaderLine.substr( 0, iSeperator);
> 			string	value = strHeaderLine.substr( iSeperator + 1,
> 												  strHeaderLine.length () - iSeperator - 1 - 1);
> 			m_vResponseHTTPHeaders.push_back( std::make_pair( key, value));
> 	    // if HTTP/1.0 we have to always close the connection by default
> 		    if( m_eProtocolType == APTHTTP1_0)
> 			{
> 				m_bReopenConnection = true;
> 			}
> 	    // if HTTP/1.1 we have to assume persistant connection by default
> 	    // We need to close the connection and open a new one if we have 'Connection: close'
> 			if( key == "Connection" && value == " close")
> 			{
> 				m_bReopenConnection = true;
> 			}
> 	    // For both HTTP/1.0 and HTTP/1.1,
> 	    // We need to keep the connection if we have 'Connection: Keep-Alive'
> 			if( key == "Connection" && value == " Keep-Alive")
> 			{
> 				m_bReopenConnection = false;
> 			}
> 	    // Look for cookies
> 			if( m_bMaintainSession && !(m_strSessionKey.size() > 0))
> 		    {
> 				if( key == "Set-Cookie")
> 				{
> 					m_strSessionKey = value;
> 		    // Spec syntax : Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
> 		    // This code assumes it to be : Set-Cookie: NAME=VALUE; Anything_else
> 		    // And discards stuff after first ';'
> 		    // This is the same assumption used in Axis Java
> 					unsigned long ulKeyEndsAt = m_strSessionKey.find( ";");
> 		    
> 					if( ulKeyEndsAt != std::string::npos)
> 				    {
> 						m_strSessionKey = m_strSessionKey.substr( 0, ulKeyEndsAt);
> 				    }
> 				}
> 		    }
> 	    /* If Content-Type: Multipart/Related; boundary=<MIME_boundary>; type=text/xml;
> 	       start="<content id>" */
> 			if( key == "Content-Type")
> 			{
> 				m_strContentType = value;
> 		
> 				unsigned long	ulMimePos = m_strContentType.find( ";");
> 				std::string		strTypePart;
> 				if( ulMimePos != std::string::npos)
> 				{
> 					strTypePart = m_strContentType.substr( 1, ulMimePos - 1);
> 				}
> 		
> 				if( "Multipart/Related" == strTypePart)
> 				{
> 					m_bMimeTrue = true;
> 					m_strContentType = m_strContentType.substr( ulMimePos + 1,
> 																m_strContentType.length());
> 				    ulMimePos = m_strContentType.find( "boundary=");
> 					m_strMimeBoundary = m_strContentType.substr( ulMimePos);
> 					ulMimePos = m_strMimeBoundary.find( ";");
> 					m_strMimeBoundary = m_strMimeBoundary.substr( 9, ulMimePos - 9);
> 					ulMimePos = m_strContentType.find( "type=");
> 					m_strMimeType = m_strContentType.substr( ulMimePos);
> 					ulMimePos = m_strMimeType.find( ";");
> 					m_strMimeType = m_strMimeType.substr( 5, ulMimePos - 5);
> 				    ulMimePos = m_strContentType.find( "start=");
> 					m_strMimeStart = m_strContentType.substr( ulMimePos);
> 					ulMimePos = m_strMimeStart.find( ";");
> 					m_strMimeStart = m_strMimeStart.substr( 6, ulMimePos - 6);
> 				}
> 			}
> 		} while( iPosition != std::string::npos);
>     }
>     else
>     {
> 		throw HTTPTransportException( SERVER_TRANSPORT_UNKNOWN_HTTP_RESPONSE,
> 									  "Protocol is not HTTP.");
>     }
> }
> /* HTTPTransport::processRootMimeBody() Is a public method used to
>  * parse the mime attachments.
>  */
> void HTTPTransport::processRootMimeBody()
> {
>     if( false == m_bReadPastRootMimeHeader)
>     {
> 		do
> 		{
> 			if( m_strReceived.find( "\r\n\r\n") == std::string::npos)
> 			{
> 				m_pszRxBuffer [0] = '\0';
> 				*m_pActiveChannel >> m_pszRxBuffer;
> 				m_strReceived += m_pszRxBuffer;
> 			}
> 		} while( m_strReceived.find( "\r\n\r\n") == std::string::npos);
> 	//now we have found the end of root mime header
> 		m_bReadPastRootMimeHeader = true;
> 	//processMimeHeader(); For the time being we don't process this
> 	// Done with root mime body headers, get rest of the payload 
> 	// which contain the soap message
> 		m_strReceived = m_strReceived.substr( m_strReceived.find( "\r\n\r\n") + 4);
> 	
> 		unsigned int intMimeTemp = m_strReceived.find( m_strMimeBoundary);
> 		if (intMimeTemp != std::string::npos)
> 		{
> 			m_strReceived = m_strReceived.substr( 0, intMimeTemp);
> 			m_strMimeReceived = m_strReceived.substr( intMimeTemp);
> 	    /* Using m_strMimeReceived will be 
> 	     * continued when getAttachment is called.
> 	     */
> 			m_bMimeTrue = false;
> 		}
>     }
>     else
>     {
> 		unsigned int intMimeTemp = m_strReceived.find( m_strMimeBoundary);
> 		
> 		if( intMimeTemp != std::string::npos)
> 		{
> 			m_strReceived = m_strReceived.substr( 0, intMimeTemp);
> 			m_strMimeReceived = m_strReceived.substr( intMimeTemp);
> 	    /* Using m_strMimeReceived will be 
> 	     * continued when getAttachment is called.
> 	     */
> 			m_bMimeTrue = false;
> 		}
> 	return;
>     }
> }
> /* HTTPTransport::processMimeHeaders() Is a public method used to
>  * parse the Mime headers of the response message.
>  */
> void HTTPTransport::processMimeHeader()
> {
>     unsigned int pos = 0;
>     unsigned int temppos = 0;
>     // Look for content lenght
>     if( (pos = m_strMimeReceived.find( "Content-Type: ")) != std::string::npos)
> 	{
> 		m_strMimeContentType = m_strMimeReceived.substr( pos + strlen( "Content-Type: "),
> 														 m_strMimeReceived.find( "\n", pos));
> 		pos = m_strMimeContentType.find( ";");
> 		temppos = m_strMimeContentType.find( "\r\n");
> 		if( pos < temppos)
> 		{
> 			m_strMimeContentType = m_strMimeContentType.substr( 0, pos);
> 		}
> 		else
> 		{
> 			m_strMimeContentType = m_strMimeContentType.substr( 0, temppos);
> 		}
>     }
>     // Look for mime root body's content transfer encoding
>     if( (pos = m_strMimeReceived.find( "Content-Transfer-Encoding: ")) != std::string::npos)
> 	{
> 		m_strMimeContentTransferEncoding = m_strMimeReceived.substr( pos + strlen( "Content-Transfer-Encoding: "),
> 																     m_strMimeReceived.find( "\n", pos));
> 		temppos = m_strMimeContentTransferEncoding.find( "\r\n");
> 		m_strMimeContentTransferEncoding = m_strMimeContentTransferEncoding.substr( 0, temppos);
>     }
>     // Look for mime root body's content id
>     if( (pos = m_strMimeReceived.find( "Content-ID: ")) != std::string::npos)
> 	{
> 		m_strMimeContentID = m_strMimeReceived.substr( pos + strlen( "Content-ID: "),
> 													   m_strMimeReceived.find( "\n", pos));
> 		temppos = m_strMimeContentID.find( "\r\n");
> 		m_strMimeContentID = m_strMimeContentID.substr( 0, temppos);
>     }
>     // Look for mime root body's content location
>     if( (pos = m_strMimeReceived.find( "Content-Location: ")) != std::string::npos)
>     {
> 		m_strMimeContentLocation = atoi( m_strMimeReceived.substr( pos + strlen( "Content-Location: "),
> 																   m_strMimeReceived.find( "\n", pos)).c_str());
> 		temppos = m_strMimeContentLocation.find( "\r\n");
> 		m_strMimeContentLocation = m_strMimeContentLocation.substr( 0, temppos);
>     }
> }
> void HTTPTransport::processMimeBody ()
> {
> }
> void HTTPTransport::getAttachment( char * pStrAttachment, int * pIntSize, int intAttachmentId)
> {
> 	m_pszRxBuffer [0] = '\0';
> 	*m_pActiveChannel >> m_pszRxBuffer;
>     m_strMimeReceived += m_pszRxBuffer;
>     do
>     {
> 		if( m_strMimeReceived.find( "\r\n\r\n") == std::string::npos)
> 		{
> 			m_pszRxBuffer [0] = '\0';
> 			*m_pActiveChannel >> m_pszRxBuffer;
> 		    m_strMimeReceived += m_pszRxBuffer;
> 		}
>     } while( m_strMimeReceived.find( "\r\n\r\n") == std::string::npos);
>     //now we have found the end of next mime header
>     processMimeHeader();
>     m_strMimeReceived = m_strMimeReceived.substr( m_strMimeReceived.find( "\r\n\r\n"));
>     processMimeBody();
> }
> void HTTPTransport::setSocket( unsigned int uiNewSocket)
> {
>     m_pActiveChannel->setSocket( uiNewSocket);
> }
> const char * HTTPTransport::getTransportProperty( const char * pcKey) throw (HTTPTransportException)
> {
>     std::string strKeyToFind = std::string( pcKey);
>     for( unsigned int i = 0; i < m_vResponseHTTPHeaders.size(); i++)
> 	{
> 		if( m_vResponseHTTPHeaders[i].first == strKeyToFind)
> 		{
> 			return ((string) m_vResponseHTTPHeaders[i].second).c_str();
> 		}
>     }
>     return NULL;
> }
> const char * HTTPTransport::getFirstTransportPropertyKey()
> {
>     m_viCurrentHeader = m_vHTTPHeaders.begin ();
>     if( m_viCurrentHeader == m_vHTTPHeaders.end())
> 	{
> 		return NULL;
> 	}
>     else
> 	{
> 		return (*m_viCurrentHeader).first.c_str();
> 	}
> }
> const char * HTTPTransport::getNextTransportPropertyKey()
> {
>     //already at the end?
>     if( m_viCurrentHeader == m_vHTTPHeaders.end())
> 	{
> 		return NULL;
> 	}
>     m_viCurrentHeader++;
>     if( m_viCurrentHeader == m_vHTTPHeaders.end())
> 	{
> 		return NULL;
> 	}
>     else
> 	{
> 		return (*m_viCurrentHeader).first.c_str();
> 	}
> }
> const char * HTTPTransport::getCurrentTransportPropertyKey()
> {
>     if( m_viCurrentHeader == m_vHTTPHeaders.end())
> 	{
> 		return NULL;
> 	}
>     else
> 	{
> 		return (*m_viCurrentHeader).first.c_str();
> 	}
> }
> const char * HTTPTransport::getCurrentTransportPropertyValue()
> {
>     if( m_viCurrentHeader == m_vHTTPHeaders.end())
> 	{
> 		return NULL;
> 	}
>     else
> 	{
> 		return (*m_viCurrentHeader).second.c_str();
> 	}
> }
> void HTTPTransport::deleteCurrentTransportProperty()
> {
>     if( m_viCurrentHeader != m_vHTTPHeaders.end())
>     {
> 		m_vHTTPHeaders.erase( m_viCurrentHeader);
>     }
> }
> void HTTPTransport::deleteTransportProperty (char *pcKey, unsigned int uiOccurance)
> {
>     vector < std::pair < std::string,
> 	std::string > >::iterator currentHeader = m_vHTTPHeaders.begin();
>     unsigned int uiCount = 1;
>     while( currentHeader != m_vHTTPHeaders.end() && uiCount <= uiOccurance)
>     {
> 		if( strcmp( pcKey, (*currentHeader).first.c_str()) == 0)
> 		{
> 			if( uiCount == uiOccurance)
> 			{
> 				m_vHTTPHeaders.erase( currentHeader);
> 				break;
> 			}
> 	    
> 			uiCount++;
> 		}
> 	
> 		currentHeader++;
>     }
> }
> void HTTPTransport::setMaintainSession( bool bSession)
> {
>     m_bMaintainSession = bSession;
> }
> void HTTPTransport::setSessionId( const char * pcSessionId)
> {
>     m_strSessionKey = std::string (pcSessionId);
> }
> const char * HTTPTransport::getSessionId()
> {
>     return m_strSessionKey.c_str();
> }

-- 
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
-
If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira