/*
*   Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
*
*   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.
*/

// !!! This include file must be first thing in file !!!
#include "../../platforms/PlatformAutoSense.hpp"

#include "HTTPTransport.hpp"

#include "../../platforms/PlatformLanguage.hpp"

// for the basic auth encryption
#include "../../soap/apr_base64.h"

#include <stdio.h>


#include "../../common/AxisTrace.h"

static int axtoi( char *pcHexString);

/*
 * HTTPTransport constuctor
 */
HTTPTransport::
HTTPTransport ():
m_bReopenConnection (false),
m_strHTTPProtocol ("HTTP/1.1"),
m_strHTTPMethod ("POST"),
m_strProxyHost (""), 
m_uiProxyPort (0), 
m_bUseProxy (false),
m_bMaintainSession (false)
{
    logEntryTransport("HTTPTransport::HTTPTransport")

    m_pcEndpointUri = NULL;
    m_pReleaseBufferCallback = 0;
    m_eProtocolType = APTHTTP1_1;
    m_strBytesToSend = "";
    m_strBytesToSendRedirect = "";
    m_strHeaderBytesToSend = "";
    m_bChannelSecure = false;
    m_pNormalChannel = 0;
    m_pSecureChannel = 0;
    m_pActiveChannel = 0;
    m_pChannelFactory = new ChannelFactory();
    m_viCurrentHeader = m_vHTTPHeaders.begin();
    m_viCurrentResponseHeader = m_vResponseHTTPHeaders.begin();
    m_pszRxBuffer = new char [BUF_SIZE];
    m_pcUsername=NULL;
    m_pcPassword=NULL;
#ifdef WIN32
    m_lChannelTimeout = 10;
    m_strChannelTimeout = "10";
#else
    m_lChannelTimeout = 0;
    m_strChannelTimeout = "0";
#endif
    m_lChannelConnectTimeout = 0;
    m_strChannelConnectTimeout = "0";
    m_strResponseLocationURI = "";
    m_bPerformAutoRedirect = false;
    m_iMaximumAutoRedirects = 1;
    m_strMaximumAutoRedirects = "1";
    m_iNbrOfRedirectAttempts = 0;
    m_bHasReadBeenDone = false;
    m_pNormalChannel = m_pChannelFactory->createChannel(UnsecureChannel);
    m_pSecureChannel = m_pChannelFactory->createChannel(SecureChannel);

    resetInputStateMachine();
    
    logExit()
}

/*
 * HTTPTransport destructor
 */
HTTPTransport::
~HTTPTransport()
{
    logEntryTransport("HTTPTransport::~HTTPTransport")

    delete [] m_pcEndpointUri;
    delete m_pChannelFactory; // should also destroy channels
    delete [] m_pszRxBuffer;
    
    logExit()
}

void HTTPTransport::
resetOutputStateMachine()
{
    logEntryTransport("HTTPTransport::resetOutputStateMachine")

    // Empty the bytes to send string. Note that the payload is saved in the case
    // we need to handle redirect.
    if (m_bPerformAutoRedirect && m_iMaximumAutoRedirects > 0 && m_strBytesToSend.length() > 0)
        m_strBytesToSendRedirect = m_strBytesToSend;

    m_strBytesToSend = "";
    m_strHeaderBytesToSend = "";

    // Also empty the response headers as there aren't any yet until the response comes back !
    m_vResponseHTTPHeaders.clear();
    // TODO: Possible memory leak here - does the clear op clean out the memory too?

    // Empty other variables set from response received
    m_strResponseHTTPStatusMessage = "";
    m_strResponseContentType = "";
    m_strResponseLocationURI = "";

    logExit()
}

void HTTPTransport::
resetInputStateMachine()
{
    logEntryTransport("HTTPTransport::resetInputStateMachine")

    m_GetBytesState = eWaitingForHTTPHeader;
    
    m_strReceived.erase();
    m_iBytesLeft = 0;
    m_iChunkedDataLeftToConsume = 0;
    m_iNextChunkedDataSize = 0;
    m_iContentLength = 0;
    m_bMimeTrue = false;  
    
    logExit()
}

/*
 * HTTPTransport::setEndpointUri( EndpointURI) sets the URI for the message.
 * Every time 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)
{
    logEntryTransport("HTTPTransport::setEndpointUri")

    logDebugArg1("Endpoint is %s", pcEndpointUri ? pcEndpointUri : "NULL")

    // if URI not valid, return
    if (!pcEndpointUri || strlen(pcEndpointUri) < strlen("http://") )
    {
        logExit()
        
        return;  
    }

    // Does the new URI equal the existing channel URI?
    // If there is a new URI, then connection will be closed and a secure or unsecure channel 
    // will be set. If the required channel is not available, an exception will be thrown.    
    if (m_pActiveChannel == NULL || m_pActiveChannel->getURL() == NULL
            || strcmp(m_pActiveChannel->getURL(), pcEndpointUri) != 0)
    {
        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)
            {
                logThrowException("HTTPTransportException - CLIENT_TRANSPORT_HAS_NO_SECURE_TRANSPORT_LAYER")

                throw HTTPTransportException( CLIENT_TRANSPORT_HAS_NO_SECURE_TRANSPORT_LAYER);
            }
        }
        else if (m_bChannelSecure)
        {
            if( m_pNormalChannel != NULL)
            {
                m_pSecureChannel->close();
                m_pActiveChannel = m_pNormalChannel;
                m_pActiveChannel->setURL( pcEndpointUri);
                m_bChannelSecure = false;
            }

            if( m_bChannelSecure)
            {
                logThrowException("HTTPTransportException - CLIENT_TRANSPORT_HAS_NO_UNSECURE_TRANSPORT_LAYER")

                throw HTTPTransportException( CLIENT_TRANSPORT_HAS_NO_UNSECURE_TRANSPORT_LAYER);
            }
        }
    }

    // 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);
        m_pActiveChannel->setConnectTimeout( m_lChannelConnectTimeout);
    }
    
    logExit()
}

/*
 * HTTPTransport::openConnection().
 */

int HTTPTransport::
openConnection()
{
    logEntryTransport("HTTPTransport::openConnection")

    // If connection not valid or reopen required, open a connection to server.
    if (m_pActiveChannel->reopenRequired() || m_bReopenConnection)
    {
        closeConnection(true);
        if( m_pActiveChannel->open() != AXIS_SUCCESS)
        {
            logThrowExceptionWithData("HTTPTransportException - CLIENT_TRANSPORT_OPEN_CONNECTION_FAILED", 
                                      m_pActiveChannel->GetLastErrorMsg().c_str())

            throw HTTPTransportException( CLIENT_TRANSPORT_OPEN_CONNECTION_FAILED,
                                          m_pActiveChannel->GetLastErrorMsg().c_str());
        }
    }

    logExitWithReturnCode(AXIS_SUCCESS)
    
    return AXIS_SUCCESS;
}

/*
 * HTTPTransport::closeConnection().
 */
void HTTPTransport::
closeConnection(bool forceClose)
{
    logEntryTransport("HTTPTransport::closeConnection")

    resetInputStateMachine();
    
    // We will close the connection if forced close, or if "Connection: close" 
    // header was detected.
    if (forceClose || m_bReopenConnection)
    {
        m_bReopenConnection = false;
        m_pActiveChannel->close();
    }
    
    logExit()
}

/*
 * 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 (AxisException, HTTPTransportException)
{
    logEntryTransport("HTTPTransport::flushOutput")

    // since we are writing...we need to reset flag indicating a read has been done.
    m_bHasReadBeenDone = false;

    char *utf8BufHeader  = NULL; // buffer for HTTP header when converting to utf8.
    char *utf8BufPayload = NULL; // buffer for HTTP payload when converting to utf8.
    char buff[24];

    // Handle re-sending payload in case of redirect.
    int payLoadLength   = m_strBytesToSend.length();
    const char *payLoad = m_strBytesToSend.c_str();

    if (payLoadLength == 0 && m_bPerformAutoRedirect && m_iMaximumAutoRedirects > 0)
    {
        payLoadLength   = m_strBytesToSendRedirect.length();
        payLoad         = m_strBytesToSendRedirect.c_str();
    }

    // Send HTTP headers and body
    try
    {
#ifndef __OS400__
        // Generate HTTP header string - need to set content-length before generating headers.
        sprintf( buff, "%d", payLoadLength);
        this->setTransportProperty ("Content-Length", buff);
        generateHTTPHeaders ();

        m_pActiveChannel->writeBytes(m_strHeaderBytesToSend.c_str(), m_strHeaderBytesToSend.length());
        m_pActiveChannel->writeBytes(payLoad, payLoadLength);
#else
        // Generate HTTP header string - need to set content-length before generating headers.
        // We need to convert payload to UTF-8 first to get accurate length of payload.
        utf8BufPayload    = PlatformLanguage::toUTF8(payLoad, payLoadLength+1);
        payLoadLength = strlen(utf8BufPayload);

        sprintf( buff, "%d", payLoadLength);
        this->setTransportProperty ("Content-Length", buff);
        generateHTTPHeaders ();

        // Convert HTTP header to UTF-8. (Really should be US-ASCII, but it is compatible with UTF-8.)
        utf8BufHeader = PlatformLanguage::toUTF8((const char *)m_strHeaderBytesToSend.c_str(), m_strHeaderBytesToSend.length()+1);

        // Write out the HTTP header followed by the HTTP payload.
        m_pActiveChannel->writeBytes(utf8BufHeader, strlen(utf8BufHeader));
        delete utf8BufHeader;
        utf8BufHeader = NULL;

        m_pActiveChannel->writeBytes(utf8BufPayload, payLoadLength);
        delete utf8BufPayload;
        utf8BufPayload = NULL;
#endif
    }
    catch(...)
    {
        delete utf8BufHeader;
        delete utf8BufPayload;

        resetOutputStateMachine();
        
        logRethrowException()
        
        throw;
    }

    resetOutputStateMachine();

    logExit()
    
    return TRANSPORT_FINISHED;
}

/* HTTPTransport::getHTTPHeaders() Called to retrieve 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::
generateHTTPHeaders()
{
    logEntryTransport("HTTPTransport::generateHTTPHeaders")

    URL & url = m_pActiveChannel->getURLObject();
    unsigned short uiPort;
    char buff[32];

    m_strHeaderBytesToSend = m_strHTTPMethod + " ";

    if (m_bUseProxy)
        m_strHeaderBytesToSend += url.getURL ();
    else
        m_strHeaderBytesToSend += url.getResource ();

    m_strHeaderBytesToSend += " ";
    m_strHeaderBytesToSend += m_strHTTPProtocol;

    // The "Host:" HTTP request header should specify the Internet host and port number of 
    // the resource being requested, as obtained from the original URI given by the user or 
    // referring resource. 
    
    m_strHeaderBytesToSend += "\r\nHost: ";
    m_strHeaderBytesToSend += url.getHostName ();
    uiPort = url.getPort();
    
    sprintf(buff, ":%u\r\n", uiPort);
    m_strHeaderBytesToSend += buff;

    // The Content-Type must be set, but it may already be set.
    bool foundCT = false;
    for (unsigned int j = 0; j < m_vHTTPHeaders.size (); j++)
        if (0==PLATFORM_STRCASECMP(AXIS_CONTENT_TYPE,m_vHTTPHeaders[j].first.c_str()))
            foundCT = true;

    if (!foundCT)
        m_strHeaderBytesToSend += AXIS_CONTENT_TYPE ": text/xml; charset=UTF-8\r\n";

    // set basic auth if the username and password are both set
    if(getUsername()!=NULL && getPassword() !=NULL)
    {
        char *cpUsernamePassword = new char[strlen (getUsername()) + strlen (getPassword()) + 2];
        strcpy (cpUsernamePassword, getUsername());
        strcat (cpUsernamePassword, ":");
        strcat (cpUsernamePassword, getPassword());

        // We use apr_base64_encode and NOT apr_base64_encode_binary since this is 
        // textual data that needs to be converted to ascii on ebcdic platforms. 
        // On ascii platforms the data will just get passed to apr_base64_encode_binary().
        int len = apr_base64_encode_len (strlen (cpUsernamePassword));
        AxisChar *base64Value = new AxisChar[len + 1];
        len = apr_base64_encode(base64Value,(const char *) cpUsernamePassword);

        std::string strValue = "Basic ";
        strValue += base64Value;

        setTransportProperty ("Authorization", strValue.c_str ());

        delete[]cpUsernamePassword;
        delete[]base64Value;
    }

    // Set other HTTP headers but not cookies as they are put in afterwards.
    for (unsigned int i = 0; i < m_vHTTPHeaders.size (); i++)
    {
        if( PLATFORM_STRCASECMP(m_vHTTPHeaders[i].first.c_str(), "Cookie")!=0)
        {
            m_strHeaderBytesToSend += m_vHTTPHeaders[i].first;
            m_strHeaderBytesToSend += ": ";
            m_strHeaderBytesToSend += m_vHTTPHeaders[i].second;
            m_strHeaderBytesToSend += "\r\n";
            
            if (0==PLATFORM_STRCASECMP("Connection",m_vHTTPHeaders[i].first.c_str())
                    && 0==PLATFORM_STRCASECMP("close", m_vHTTPHeaders[i].second.c_str()))
                m_bReopenConnection = true;
        }
    }

    // Set cookies
    if (m_bMaintainSession && (m_vCookies.size () > 0))
    {
        string cookieHeader="";

        // Add in all the cookies ar the last one because that shouldn't have a ';' on it
        for (unsigned int var = 0; var < m_vCookies.size()-1; var++)
        {
            cookieHeader += m_vCookies[var].first;
            cookieHeader += "=";
            cookieHeader += m_vCookies[var].second;
            cookieHeader += ";";
        }
        
        // add on the last cookie
        cookieHeader += m_vCookies[m_vCookies.size()-1].first;
        cookieHeader += "=";
        cookieHeader += m_vCookies[m_vCookies.size()-1].second;

        m_strHeaderBytesToSend += "Cookie: ";
        m_strHeaderBytesToSend += cookieHeader;
        m_strHeaderBytesToSend += "\r\n";

        // Now add this header in to the list of sent headers if it's not already been set ! If it has been then
        // override it
        bool b_keyFound=false;
        for (unsigned int i = 0; i < m_vHTTPHeaders.size(); i++)
        {
            if (PLATFORM_STRCASECMP(m_vHTTPHeaders[i].first.c_str(), "Cookie") == 0)
            {
                m_vHTTPHeaders[i].second = (string) cookieHeader;
                b_keyFound = true;

                break;
            }
        }
        if(!b_keyFound)
        {
            m_vHTTPHeaders.push_back( std::make_pair( (string) "Cookie", (string) cookieHeader));
        }
    }

    m_strHeaderBytesToSend += "\r\n";

    logExit()
    
    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)
{
    logEntryTransport("HTTPTransport::setHTTPMethod")
    
    logDebugArg1("HTTP method is %s", cpMethod ? cpMethod : "NULL")

    if (cpMethod)
        m_strHTTPMethod = std::string( cpMethod);
    
    logExit()
}

/* 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);

    // Since we are sending new data, ensure nothing in redirect buffer.
    if (m_strBytesToSendRedirect.length() > 0)
    {
        m_iNbrOfRedirectAttempts = 0;
        m_strBytesToSendRedirect = "";
    }

    return TRANSPORT_IN_PROGRESS;
}

bool HTTPTransport::
isThereResponseData()
{
    logEntryTransport("HTTPTransport::isThereResponseData")

    // We do not want to consume any SOAP data, just find out if there is any data.
    int bufLen = 0;
    if (!m_bHasReadBeenDone)
        getBytes(NULL, &bufLen);
    bool returnValue = (m_GetBytesState != eWaitingForHTTPHeader || m_iBytesLeft != 0);
    
    logExitWithBoolean(returnValue)
    
    return returnValue;
}

/* 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 * piSize) throw (AxisException, HTTPTransportException)
{
    logEntryTransport("HTTPTransport::getBytes")

    // The method getBytes has three distinct states.  These are defined as
    // follows:-
    //   eWaitingForHTTPHeader        - Waiting for HTTP response header. Initiate processing
    //                                  that will read an HTTP header. One caveat. 
    //                                  We can be in this state but still have data
    //                                  to be processed. So if there is data, it will
    //                                  be returned and we will not attempt to read 
    //                                  an HTTP response. 
    //   eSOAPMessageIsChunked        - Keep reading until a zero length chunk is 
    //                                  encountered, signifying end of response.
    //   eSOAPMessageIsNotChunked     - Keep reading until the connection is closed. 
    //   eSOAPMessageHasContentLength - Keep reading until content-length is zero.        

    
    // Read in an HTTP header if we are waiting for one.  Now this is a bit tricky
    // and I was fooled by this when I was fix problems in the code so here is 
    // the tricky part.  If we have data in the buffer then we need to return 
    // the data - i.e. we will skip reading HTTP header until data has been 
    // consumed!  Not the most elegant of designs, but it works.  The reason is 
    // that we read in data later on and then change the state based on whether 
    // there is more data to read or not.  The caller of this routine will have
    // data copied into buffer, but the buffer may not be big enough to consume
    // the data, so that is why we have data in the buffer left and thus must 
    // skip reading HTTP header until data has been consumed. 
    if (m_GetBytesState == eWaitingForHTTPHeader)
        if (m_iBytesLeft == 0)
            readHTTPHeader();

    // Process data based on current state. 
    int iBytesToCopy = m_iBytesLeft;
    
    if (m_GetBytesState == eSOAPMessageHasContentLength)
        iBytesToCopy = getBytes_MessageHasContentLength(pcBuffer, piSize);
    else if (m_GetBytesState == eSOAPMessageIsNotChunked)
        iBytesToCopy = getBytes_MessageIsNotChunked(pcBuffer, piSize);
    else if( m_GetBytesState == eSOAPMessageIsChunked)
        iBytesToCopy = getBytes_MessageIsChunked(pcBuffer, piSize);

    // Copy as much of the message to the parser buffer as possible.
    if (iBytesToCopy > 0 && *piSize > 0)
    {
        int iToCopy = (*piSize < iBytesToCopy) ? *piSize : iBytesToCopy;

        m_strReceived.copy(pcBuffer, iToCopy);
        *piSize = iToCopy;
        m_iBytesLeft -= iToCopy;
        m_strReceived.erase(0, iToCopy);
    }
    else
        *piSize = 0;
    
    logExit()
    
    // Set transport status 
    return (m_iBytesLeft > 0 || (m_GetBytesState != eWaitingForHTTPHeader)) ? 
                TRANSPORT_IN_PROGRESS : TRANSPORT_FINISHED;
}

/**
 * getBytes_MessageHasContentLength() is used when the HTTP response 
 * includes the Content-Length HTTP header. 
 */
int HTTPTransport::
getBytes_MessageHasContentLength(char * pcBuffer, int * piSize)
{
    logEntryTransport("HTTPTransport::getBytes_MessageHasContentLength")

    // If we do not have data to give back, read more.  
    if (m_iContentLength > 0 && m_iBytesLeft == 0)
    {
        getNextDataPacket( "No data available for message.");

        // Check for Mime header
        if( m_bMimeTrue)
        {
            processRootMimeBody();
            m_iBytesLeft = m_strReceived.length();
        }              
    }
    
    // Subtract message length (so far) from expected content length.
    if( m_iContentLength >= m_iBytesLeft)
        m_iContentLength -= m_iBytesLeft;
    else
        m_iContentLength = 0;          
    
    // If all of the message has been received, then reset the process state
    if (0 == m_iContentLength)
        m_GetBytesState = eWaitingForHTTPHeader;
        
    logExitWithInteger(m_iBytesLeft)

    // Return number of bytes that can be copied
    return m_iBytesLeft;
}

/**
 * getBytes_MessageIsNotChunked() is used when the HTTP response 
 * is not chunked and does not include the Content-Length HTTP header.
 * Thus, the only way we know that the data has been read is to read 
 * from the input stream until a zero length read completes. 
 */
int HTTPTransport::
getBytes_MessageIsNotChunked(char * pcBuffer, int * piSize)
{
    logEntryTransport("HTTPTransport::getBytes_MessageIsNotChunked")

    // Keep reading until the connection is closed by the server.
    getNextDataPacket( "Expecting server connection to close.");

    // Check for Mime header
    if( m_bMimeTrue)
    {
        processRootMimeBody();
        m_iBytesLeft = m_strReceived.length();
    }
    
    logExitWithInteger(m_iBytesLeft)

    // Return number of bytes that can be copied
    return m_iBytesLeft;
}

/**
 * getBytes_MessageIsChunked() is used when the HTTP response 
 * is chunked. The chunked encoding modifies the body of a message 
 * in order to transfer it as a series of chunks, each with its own 
 * size indicator, followed by an OPTIONAL trailer containing 
 * entity-header fields. This allows dynamically produced content to 
 * be transferred along with the information necessary for the recipient 
 * to verify that it has received the full message. Format is as follows:
 * 
 *     Chunked-Body   = *chunk
 *                      last-chunk
 *                      trailer
 *                      CRLF
 * 
 *     chunk          = chunk-size [ chunk-extension ] CRLF
 *                      chunk-data CRLF
 *     chunk-size     = 1*HEX
 *     last-chunk     = 1*("0") [ chunk-extension ] CRLF
 * 
 *     chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
 *     chunk-ext-name = token
 *     chunk-ext-val  = token | quoted-string
 *     chunk-data     = chunk-size(OCTET)
 *     trailer        = *(entity-header CRLF)
 * 
 * The chunk-size field is a string of hex digits indicating the size of the 
 * chunk. The chunked encoding is ended by any chunk whose size is zero, 
 * followed by the trailer, which is terminated by an empty line.  The 
 * trailer is ignored by this routine.
 */
int HTTPTransport::
getBytes_MessageIsChunked(char * pcBuffer, int * piSize)
{
    logEntryTransport("HTTPTransport::getBytes_MessageIsChunked")

    // We only read the next chunk if the chunk we have has been consumed. 
    if (m_iChunkedDataLeftToConsume == 0)
    {
        // First, ensure that we remove any leading CRLF.  This would be the 
        // ending CRLF for a chunk.  A chunk has this form:
        //    chunk-data CRLF
        if (m_iBytesLeft > 1 
                && m_strReceived[0] == ASCII_C_CR && m_strReceived[1] == ASCII_C_LF)
        {
            m_strReceived.erase(0, 2);
            m_iBytesLeft = m_strReceived.length();
        }
        
        // Get chunk size.  We may already have it. It is set to zero only if we have 
        // not obtained it. It is also set to zero for end of chunk size of zero, but we should
        // never be coming down to read it. 
        if (m_iNextChunkedDataSize > 0)
        {
            // Need to remove the chunk-size line since it has been already processed.
            // Should never be the case where we get npos, but we check just in case.
            string::size_type iEndOfChunkSize = m_strReceived.find(ASCII_S_CRLF);
            if (iEndOfChunkSize != std::string::npos)
            {
                m_strReceived.erase(0, iEndOfChunkSize + 2);
                m_iBytesLeft  = m_strReceived.length(); 
            }
            
            m_iChunkedDataLeftToConsume = m_iNextChunkedDataSize;
            m_iNextChunkedDataSize = 0;
        }
        else
            m_iChunkedDataLeftToConsume = getChunkSize(); 
    
        // We should never be in a situation where caller invokes getBytes 
        // and there is no data to read, but just in case...
        if (m_iChunkedDataLeftToConsume > 0)
        {
            // If the chunk size is larger than the available data, then read in more 
            // data until all of the chunk has been read.  We read in the CRLF that
            // ends a chunk and at least one more byte so that later we can read the
            // next chunk size.            
            while ((m_iChunkedDataLeftToConsume + 2) >= m_iBytesLeft)
                getNextDataPacket( "No data available for next chunk.");
        
            // Determine next chunk size, mainly to determine if zero-length, 
            // meaning end-of-chunk processing and thus a state reset. 
            // "+ 2" used in if-check for CRLF since at end of each chunk there should be CRLF.
            if (0 == (m_iNextChunkedDataSize = getChunkSize(m_iChunkedDataLeftToConsume + 2)))
                m_GetBytesState = eWaitingForHTTPHeader;
        
            // The chunk may contain Mime data (this depends on information in the HTTP header).  
            if( m_bMimeTrue)
            {
                processRootMimeBody();
                m_iBytesLeft = m_strReceived.length();
            }
        }
        else
            m_GetBytesState = eWaitingForHTTPHeader;
    }
    
    // OK, now we need to determine how much of the chunk will be left 
    // over depending on the buffer length that is passed in.
    int iDataToCpyLen;
    if (*((unsigned int *)piSize) >= m_iChunkedDataLeftToConsume)
    {
        iDataToCpyLen = m_iChunkedDataLeftToConsume;
        m_iChunkedDataLeftToConsume = 0;
    }
    else
    {
        iDataToCpyLen = *piSize;
        m_iChunkedDataLeftToConsume -= *piSize;
    }
    
    logExitWithInteger(iDataToCpyLen)

    return iDataToCpyLen;
}

/**
 * getChunkSize() is method used to obtain the chunk size. 
 * Once obtained, it may remove the chunksize line from 
 * the data since it is not data to be returned.
 */
int HTTPTransport::
getChunkSize(string::size_type pos)
{
    logEntryTransport("HTTPTransport::getChunkSize")

    string::size_type iEndOfChunkSize;
    string::size_type iEndOfChunkLine;
    
    // Here is what a chunk size line may look like:
    //    chunk-size [ chunk-extension ] CRLF
    // where chunk-extension is defined as:
    //    *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
    
    // Get complete line.
    while( (iEndOfChunkLine = m_strReceived.find(ASCII_S_CRLF, pos)) == std::string::npos )
        getNextDataPacket("Could not find delimiter for end of chunk size.");    

    string chunkSizeLine = m_strReceived.substr( pos, iEndOfChunkLine-pos);
    
    // Look to see if there are any extensions - these are put in brackets.
    if ((iEndOfChunkSize = chunkSizeLine.find(ASCII_S_LEFTPAREN)) != std::string::npos)
        chunkSizeLine.erase(iEndOfChunkSize);
    
    // Convert the hex string into the length of the chunk.
    int chunkSize = axtoi((char *)chunkSizeLine.c_str());  
    
    // A chunk size of -1 means either we received an invalid chunk size 
    // or the code is not parsing chunks correctly.  Whatever the case, 
    // we are hosed and there is no use continuing.
    if (-1 == chunkSize)
    {
        m_bReopenConnection = true;
        
        // We will only dump out just 40 bytes...otherwise we may be 
        // dumping out huge chunks of data
        if (chunkSizeLine.length() > 40)
            chunkSizeLine = chunkSizeLine.substr(0, 40);
        
        PLATFORM_ASCTOSTR(chunkSizeLine.c_str());
        string errorMessage = string("Chunk size (") + chunkSizeLine + string(") not valid.");
        
        logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_HTTP_EXCEPTION", errorMessage.c_str())
                                         
        throw HTTPTransportException(SERVER_TRANSPORT_HTTP_EXCEPTION, errorMessage.c_str());        
    }

    // If chunksize is zero, remove the line including ending CRLFCRLF. This line
    // will never be consumed so it needs to be removed from the buffer. Otherwise,
    // if chunksize is not zero, we only remove the chunksize line only if offset is 
    // zero, i.e. at the beginning of line. If offset is not zero, it means this 
    // request came down to peek at the next chunksize.     
    if (0 == chunkSize)
    {
        string::size_type iEndOfResponse;
        while ((iEndOfResponse = m_strReceived.find(ASCII_S_CRLFCRLF, pos)) == std::string::npos )
            getNextDataPacket("Could not find delimiter for end of chunked response."); 
        
        m_strReceived.erase(pos, iEndOfResponse + 4); // "+4" for CRLFCRLF
    }
    else if (pos == 0)
        m_strReceived.erase(0, iEndOfChunkLine + 2); // "+2" for CRLF
    m_iBytesLeft  = m_strReceived.length();   
    
    logExitWithInteger(chunkSize)
 
    // return chunksize
    return chunkSize;
}

/* 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.
 */
int HTTPTransport::
setTransportProperty( AXIS_TRANSPORT_INFORMATION_TYPE type, const char *value) throw (HTTPTransportException)
{
    logEntryTransport("HTTPTransport::setTransportProperty")

    const char *key = NULL;
    int   iSuccess = AXIS_SUCCESS;

    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:
        {
            if (value && (PLATFORM_STRCASECMP(value, "Connection: close") == 0))
                setTransportProperty("Connection", "close");
            else if( m_pActiveChannel != NULL)
                m_pActiveChannel->setTransportProperty( type, value);

            break;
        }

        case SECURE_PROPERTIES:
        {
            if( m_pActiveChannel != NULL)
                iSuccess = m_pActiveChannel->setSecureProperties( value);
            
            break;
        }

        case CHANNEL_HTTP_DLL_NAME:
        {
            if( m_pChannelFactory != NULL)
                m_pNormalChannel = m_pChannelFactory->LoadChannelLibrary( UnsecureChannel, value);

            break;
        }

        case CHANNEL_HTTP_SSL_DLL_NAME:
        {
            if( m_pChannelFactory != NULL)
                m_pSecureChannel = m_pChannelFactory->LoadChannelLibrary( SecureChannel, value);

            break;
        }

        case ENABLE_AUTOMATIC_REDIRECT:
        {
            if (value && (PLATFORM_STRCASECMP(value, "true") == 0))
                m_bPerformAutoRedirect = true;
            else
                m_bPerformAutoRedirect = false;
            break;
        }

        case MAX_AUTOMATIC_REDIRECT:
        {
            if (value)
                m_iMaximumAutoRedirects = atoi(value);

            if (m_iMaximumAutoRedirects < 1)
                m_iMaximumAutoRedirects = 0;

            char buffer[100];
            sprintf(buffer, "%d", m_iMaximumAutoRedirects);
            m_strMaximumAutoRedirects = (const char *)buffer;

            break;
        }

        case IO_TIMEOUT:
        {
            if (value)
                setTimeout((long)atoi(value));

            break;
        }

        case CONNECT_TIMEOUT:
        {
            if (value)
                setConnectTimeout((long)atoi(value));

            break;
        }

        default:
        {
            break;
        }
    }

    if( key)
        setTransportProperty( key, value);

    logExitWithReturnCode(iSuccess)
    
    return iSuccess;
}

/* HTTPTransport::setTransportProperty( Key, Value) Is an overloaded public
 * method used to set a HTTP transport or SSL implementation property.
 *
 * Any existing transport property will be replaced with the new value.
 *
 * @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.
 */
int HTTPTransport::
setTransportProperty( const char *pcKey, const char *pcValue) throw (HTTPTransportException)
{
    logEntryTransport("HTTPTransport::setTransportProperty")

    int   iSuccess = AXIS_SUCCESS;

    if( pcKey && pcValue) 
    {
        logDebugArg2("Transport property to set: %s=%s", pcKey, pcValue)

        bool b_KeyFound = false;
    
        // Cookies are handled elsewhere.  For other properties, we first check to
        // see if there is a matching (i.e. duplicate property) already set.  If one
        // exists, we replace the value.
        if(PLATFORM_STRCASECMP(pcKey, "Cookie")==0)
        {
            iSuccess = addCookie(pcValue);
            b_KeyFound = true;
        }
        else
        {
            for (unsigned int i = 0; i < m_vHTTPHeaders.size(); i++)
                if (PLATFORM_STRCASECMP(m_vHTTPHeaders[i].first.c_str(), pcKey) == 0)
                {
                    m_vHTTPHeaders[i].second = (string) pcValue;
                    b_KeyFound = true;
    
                    break;
                }
        }
        
        // If the property was not handled, then add it to the list of transport properties.
        if( !b_KeyFound)
            m_vHTTPHeaders.push_back( std::make_pair( (string) pcKey, (string) pcValue));
    }

    
    logExitWithReturnCode(iSuccess)

    return iSuccess;
}

/* 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)
{
    logEntryTransport("HTTPTransport::getTransportProperty")

    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:
        case CONTENT_TYPE:
        {
            break;
        }

        case ENABLE_AUTOMATIC_REDIRECT:
        {
            pszPropValue = m_bPerformAutoRedirect ? "true" : "false";
            break;
        }

        case MAX_AUTOMATIC_REDIRECT:
        {
            pszPropValue = m_strMaximumAutoRedirects.c_str();
            break;
        }


        case IO_TIMEOUT:
        {
            pszPropValue = m_strChannelTimeout.c_str();

            break;
        }

        case CONNECT_TIMEOUT:
        {
            pszPropValue = m_strChannelConnectTimeout.c_str();

            break;
        }
    }

    logExitWithString(pszPropValue)

    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;

    while( (unsigned int) iIndex < m_vHTTPHeaders.size() && !bKeyFound)
    {
        if (!m_vHTTPHeaders[iIndex].first.compare( sKey))
            bKeyFound = true;
        else
            iIndex++;
    }

    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;
    }

    return AXIS_FAIL;
}

/**
 * HTTPTransport::getSubProtocol() is a public method that is supposed to
 * return the sub protocol (currently this method always return POST).
 * 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)
{
    logEntryTransport("HTTPTransport::setProxy")

    logDebugArg2("Proxy host is %s, proxy port is %d", pcProxyHost ? pcProxyHost : "NULL", uiProxyPort)

    m_pActiveChannel->setProxy(pcProxyHost,uiProxyPort);
    m_strProxyHost = pcProxyHost;
    m_uiProxyPort = uiProxyPort;
    m_bUseProxy = true;
    
    logExit()
}

/* HTTPTransport::setTimeout( Timeout) Is a public method for setting the
 * current maximum timeout period between that can elapse between receiving
 * message parts.
 *
 * @param long Timeout is a long value in seconds.
 */
void HTTPTransport::
setTimeout( long lSeconds)
{
    logEntryTransport("HTTPTransport::setTimeout")

    logDebugArg1("I/O timeout: %d", lSeconds)

    if( m_pActiveChannel != NULL)
        m_pActiveChannel->setTimeout( lSeconds);

    m_lChannelTimeout = lSeconds;
    
    char buffer[100];
    sprintf(buffer, "%d", m_lChannelTimeout);
    m_strChannelTimeout = (const char *)buffer;

    logExit()
}

/* HTTPTransport::setConnectTimeout( Timeout) Is a public method for setting the
 * current maximum connect timeout.
 *
 * @param long Timeout is a long value in seconds.
 */
void HTTPTransport::
setConnectTimeout( long lSeconds)
{
    logEntryTransport("HTTPTransport::setConnectTimeout")

    logDebugArg1("Connect timeout: %d", lSeconds)

    if( m_pActiveChannel != NULL)
        m_pActiveChannel->setConnectTimeout( lSeconds);

    m_lChannelConnectTimeout = lSeconds;

    char buffer[100];
    sprintf(buffer, "%d", m_lChannelConnectTimeout);
    m_strChannelConnectTimeout = (const char *)buffer;

    logExit()
}

/* 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.
 */
static int axtoi( char *pcHexString)
{
    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

    bool     badChunkSize = false;

    while( iN < 32 && pcHexString[iN] != '\0')
    {
        if( pcHexString[iN] >= ASCII_C_ZERO && pcHexString[iN] <= ASCII_C_NINE)
        {
            iDigit[iN] = pcHexString[iN] & 0x0f;   //convert to int
        }
        else if ((pcHexString[iN] >= ASCII_C_LOWERCASEA &&
                  pcHexString[iN] <= ASCII_C_LOWERCASEF) ||
                 (pcHexString[iN] >= ASCII_C_UPPERCASEA &&
                  pcHexString[iN] <= ASCII_C_UPPERCASEF))
        {
            iDigit[iN] = (pcHexString[iN] & 0x0f) + 9;   //convert to int
        }
        else
        {
            badChunkSize = true;
            break;
        }

        iN++;
    }
    
    if (badChunkSize || pcHexString[0] == '\0')
        return -1;

    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::processHTTPHeader() Is a public method used to
 * parse the HTTP header of the response message.
 */
void HTTPTransport::
processHTTPHeader()
{
    logEntryTransport("HTTPTransport::processHTTPHeader")

    // Prior to calling this method, m_strResponseHTTPHeaders should have been 
    // set to the HTTP header in the response, which is in ascii.  For EBCDIC 
    // systems, we need to convert the data from ASCII to EBCDIC.
    // WARNING: Response header processing within here should not be moved 
    //          unless you search for the right string - ascii or ebcdic. 
    //          Since we convert everything to EBCDIC, we can use literal 
    //          strings such as "\r\n" instead of ascii equivalent "\x0d\x0a". 
    PLATFORM_ASCTOSTR(m_strResponseHTTPHeaders.c_str());

    // The first line of a Response message is the Status-Line:
    // 
    //    Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
    // 
    // Parse it to get status code and reason-phrase.
    
    string::size_type iPosition = std::string::npos;
    string::size_type iStartPosition = iPosition;
    
    if( (iPosition = m_strResponseHTTPHeaders.find( "HTTP" )) == std::string::npos)
    {
        logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_UNKNOWN_HTTP_RESPONSE", "Protocol is not HTTP.")

        throw HTTPTransportException( SERVER_TRANSPORT_UNKNOWN_HTTP_RESPONSE,
                                      "Protocol is not HTTP.");
    }
    
    m_strResponseHTTPProtocol = m_strResponseHTTPHeaders.substr( iPosition, strlen("HTTP/1.x"));
    iPosition += strlen("HTTP/1.x");

    while( m_strResponseHTTPHeaders[iPosition] == ' ')
        iPosition++;

    iStartPosition = iPosition;

    while( m_strResponseHTTPHeaders[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++;

    // Now read the header fields and add to vector.
    do
    {
        // Remove consumed line from header string.
        m_strResponseHTTPHeaders = m_strResponseHTTPHeaders.substr( iStartPosition);
        
        // now find end of line...if we do not find one, break out.
        iPosition = m_strResponseHTTPHeaders.find( "\n" );
        if( iPosition == std::string::npos)
            break;
        iStartPosition = iPosition + 1;
        
        // store line in work buffer and find seperator ":", if no seperator, 
        // continue on with next line.
        std::string strHeaderLine = m_strResponseHTTPHeaders.substr(0, iPosition);
        
        string::size_type iSeperator = strHeaderLine.find( ":" ); 
        if( iSeperator == std::string::npos)
            continue;

        // Store as key-value pairs 
        string key   = strHeaderLine.substr( 0, iSeperator);
        string value = strHeaderLine.substr( iSeperator + 1, strHeaderLine.length() - iSeperator - 2);
        trim(value);
        trim(key);
        m_vResponseHTTPHeaders.push_back( std::make_pair( key, value));

        // Content length set? Chunked overrides Content-length. It should be noted
        // that on successful one-way requests Content-Length would be set to zero.
        if (PLATFORM_STRCASECMP(key.c_str(), "Content-Length") == 0)
            if (m_GetBytesState != eSOAPMessageIsChunked)
            {
                m_iContentLength = atoi(value.c_str());
                m_GetBytesState = eSOAPMessageHasContentLength;
            }

        // Redirect?
        if (PLATFORM_STRCASECMP(key.c_str(), "Location") == 0)
            m_strResponseLocationURI = value;

        // Is chunked? 
        if ((PLATFORM_STRCASECMP(key.c_str(), "Transfer-Encoding") == 0)
                && (PLATFORM_STRCASECMP(value.c_str(), "chunked") == 0))
            m_GetBytesState = eSOAPMessageIsChunked;

        // Now handle whether we are going to close connection after processing 
        // request. If HTTP/1.0 we have to always close the connection by default; otherwise,
        // we assume persistent connection by default.
        if( m_eProtocolType == APTHTTP1_0)
            m_bReopenConnection = true;

        // We need to close the connection and open a new one if we have 'Connection: close'
        if ((PLATFORM_STRCASECMP(key.c_str(), "Connection") == 0)
                && (PLATFORM_STRCASECMP(value.c_str(), "close") == 0))
        {
            m_bReopenConnection = true;
            m_pActiveChannel->closeQuietly( true);
        }

        // We need to close the connection and open a new one if we have 'Proxy-Connection: close'
        if ((PLATFORM_STRCASECMP(key.c_str(), "Proxy-Connection") == 0)
                && (PLATFORM_STRCASECMP(value.c_str(), "close") == 0))
            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 ((PLATFORM_STRCASECMP(key.c_str(), "Connection") == 0)
                && (PLATFORM_STRCASECMP(value.c_str(), "Keep-Alive") == 0))
            m_bReopenConnection = false;

        // Look for cookies
        if ( m_bMaintainSession )
            if (PLATFORM_STRCASECMP(key.c_str(), "Set-Cookie") == 0)
                addCookie(value);

        /* If Content-Type: Multipart/Related; boundary=<MIME_boundary>; type=text/xml; start="<content id>" */
        if (PLATFORM_STRCASECMP(key.c_str(), "Content-Type") == 0)
        {
            m_strResponseContentType = value;

            string::size_type   ulMimePos = m_strResponseContentType.find( ";");
            std::string      strTypePart;

            if( ulMimePos != std::string::npos)
                strTypePart = m_strResponseContentType.substr( 1, ulMimePos - 1);

            if ( "Multipart/Related" == strTypePart)
            {
                m_bMimeTrue = true;
                m_strResponseContentType = m_strResponseContentType.substr( ulMimePos + 1, m_strResponseContentType.length());

                ulMimePos = m_strResponseContentType.find( "boundary=");
                m_strMimeBoundary = m_strResponseContentType.substr( ulMimePos);
                ulMimePos = m_strMimeBoundary.find( ";");
                m_strMimeBoundary = m_strMimeBoundary.substr( 9, ulMimePos - 9);

                ulMimePos = m_strResponseContentType.find( "type=");
                m_strMimeType = m_strResponseContentType.substr( ulMimePos);
                ulMimePos = m_strMimeType.find( ";");
                m_strMimeType = m_strMimeType.substr( 5, ulMimePos - 5);

                ulMimePos = m_strResponseContentType.find( "start=");
                m_strMimeStart = m_strResponseContentType.substr( ulMimePos);
                ulMimePos = m_strMimeStart.find( ";");
                m_strMimeStart = m_strMimeStart.substr( 6, ulMimePos - 6);
            }
        }
    }
    while( iPosition != std::string::npos);
    
    // If 100 Continue is the response header, then we need to ensure we are waiting for 
    // an HTTP header.  Otherwise, HTTP protocol allows body with no Content-Length 
    // and no transfer-encoding! This means that we read from the stream until we are unable 
    // to read anymore. So ensure state is set correctly. In this case we set it to not-chunked.
    if (m_iResponseHTTPStatusCode == 100)
        m_GetBytesState = eWaitingForHTTPHeader;
    else if (m_GetBytesState == eWaitingForHTTPHeader)
        m_GetBytesState = eSOAPMessageIsNotChunked;
    
    logExit()
}

/* HTTPTransport::processRootMimeBody() Is a public method used to
 * parse the mime attachments.
 */
void HTTPTransport::
processRootMimeBody()
{
    logEntryTransport("HTTPTransport::processRootMimeBody")

    int numberOfBytesRead = 0;
    
    if( false == m_bReadPastRootMimeHeader)
    {
        do
        {
            if( m_strReceived.find( ASCII_S_CRLFCRLF ) == std::string::npos)
            {
                numberOfBytesRead = m_pActiveChannel->readBytes(m_pszRxBuffer, BUF_SIZE);
                if (numberOfBytesRead > 0)
                    m_strReceived += m_pszRxBuffer;
            }
        }
        while( m_strReceived.find( ASCII_S_CRLFCRLF ) == 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( ASCII_S_CRLFCRLF ) + 4);

        string::size_type intMimeTemp = m_strReceived.find( m_strMimeBoundary);

        if (intMimeTemp != std::string::npos)
        {
            m_strReceived = m_strReceived.substr( 0, intMimeTemp);
            m_strMimeReceived = m_strReceived.substr( intMimeTemp);
            PLATFORM_ASCTOSTR(m_strMimeReceived.c_str());

            // Using m_strMimeReceived will be continued when getAttachment is called.
            m_bMimeTrue = false;
        }
    }
    else
    {
        string::size_type intMimeTemp = m_strReceived.find( m_strMimeBoundary);

        if( intMimeTemp != std::string::npos)
        {
            m_strReceived = m_strReceived.substr( 0, intMimeTemp);
            m_strMimeReceived = m_strReceived.substr( intMimeTemp);
            PLATFORM_ASCTOSTR(m_strMimeReceived.c_str());

            // Using m_strMimeReceived will be continued when getAttachment is called.
            m_bMimeTrue = false;
        }
    }
    
    logExit()
}

/* HTTPTransport::processMimeHeaders() Is a public method used to
 * parse the Mime headers of the response message.
 */
void HTTPTransport::
processMimeHeader()
{
    logEntryTransport("HTTPTransport::processMimeHeader")

    string::size_type pos = 0;
    string::size_type 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);
    }
    
    logExit()
}

void HTTPTransport::
processMimeBody ()
{
}

void HTTPTransport::
getAttachment( char * pStrAttachment, int * pIntSize, int intAttachmentId)
{
    logEntryTransport("HTTPTransport::getAttachment")

    int numberOfBytesRead = 0;
    
    do
    {
        numberOfBytesRead = m_pActiveChannel->readBytes(m_pszRxBuffer, BUF_SIZE);
        if (numberOfBytesRead > 0)
            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();
    
    logExit()
}

void HTTPTransport::
setSocket( unsigned int uiNewSocket)
{
    m_pActiveChannel->setSocket( uiNewSocket);
}

const char * HTTPTransport::
getTransportProperty( const char * pcKey, bool response) throw (HTTPTransportException)
{
    logEntryTransport("HTTPTransport::getTransportProperty")
    
    const char *returnValue = NULL;

    if (pcKey == NULL)
        return NULL;

    std::vector < std::pair < std::string, std::string > > *hdrs=NULL;
    
    if (response)
        hdrs = &m_vResponseHTTPHeaders;
    else
        hdrs = &m_vHTTPHeaders;

    for( unsigned int i = 0; i < hdrs->size(); i++)
        if (PLATFORM_STRCASECMP((*hdrs)[i].first.c_str(), pcKey) == 0)
        {
            returnValue = (*hdrs)[i].second.c_str();
            break;
        }

    logExitWithString(returnValue)

    return returnValue;
}

const char * HTTPTransport::
getFirstTransportPropertyKey(bool response)
{
    if(response)
    {
        m_viCurrentResponseHeader = m_vResponseHTTPHeaders.begin ();

        if( m_viCurrentResponseHeader == m_vResponseHTTPHeaders.end())
            return NULL;
        else
            return (*m_viCurrentResponseHeader).first.c_str();
    }
    else
    {
        m_viCurrentHeader = m_vHTTPHeaders.begin ();

        if( m_viCurrentHeader == m_vHTTPHeaders.end())
            return NULL;
        else
            return (*m_viCurrentHeader).first.c_str();
    }
}

const char * HTTPTransport::
getNextTransportPropertyKey(bool response)
{
    if(response)
    {
        //already at the end?
        if( m_viCurrentResponseHeader == m_vResponseHTTPHeaders.end())
            return NULL;

        m_viCurrentResponseHeader++;

        if( m_viCurrentResponseHeader == m_vResponseHTTPHeaders.end())
            return NULL;
        else
            return (*m_viCurrentResponseHeader).first.c_str();
    }
    else
    {

        //already at the end?
        if( m_viCurrentHeader == m_vResponseHTTPHeaders.end())
            return NULL;

        m_viCurrentHeader++;

        if( m_viCurrentHeader == m_vHTTPHeaders.end())
            return NULL;
        else
            return (*m_viCurrentHeader).first.c_str();
    }
}

const char * HTTPTransport::
getCurrentTransportPropertyKey(bool response)
{
    if (response)
    {
        if( m_viCurrentResponseHeader == m_vResponseHTTPHeaders.end())
            return NULL;
        else
            return (*m_viCurrentResponseHeader).first.c_str();
    }
    else if( m_viCurrentHeader == m_vHTTPHeaders.end())
        return NULL;
    else
        return (*m_viCurrentHeader).first.c_str();
}

const char * HTTPTransport::
getCurrentTransportPropertyValue(bool response)
{
    if(response)
    {
        if( m_viCurrentResponseHeader == m_vResponseHTTPHeaders.end())
            return NULL;
        else
            return (*m_viCurrentResponseHeader).second.c_str();
    }
    else if( m_viCurrentHeader == m_vHTTPHeaders.end())
        return NULL;
    else
        return (*m_viCurrentHeader).second.c_str();
}

void HTTPTransport::
deleteCurrentTransportProperty(bool response)
{
    // response=true by default
    std::vector < std::pair < std::string, std::string > >* headers = &m_vResponseHTTPHeaders;
    vector <std::pair < std::string, std::string > >::iterator* currentHeader = &m_viCurrentResponseHeader;
    if(!response)
    {
        headers = &m_vHTTPHeaders;
        currentHeader = &m_viCurrentHeader;
    }
    
    if( *currentHeader != headers->end())
       headers->erase( *currentHeader);
}

void HTTPTransport::
deleteTransportProperty (char *pcKey, unsigned int uiOccurance)
{
    if (pcKey == NULL)
        return;

    vector < std::pair < std::string,
    std::string > >::iterator currentHeader = m_vHTTPHeaders.begin();
    unsigned int uiCount = 1;
    bool found=false;
    while( currentHeader != m_vHTTPHeaders.end() && uiCount <= uiOccurance)
    {
        if (PLATFORM_STRCASECMP(pcKey, (*currentHeader).first.c_str()) == 0)
        {
            if( uiCount == uiOccurance)
            {
                m_vHTTPHeaders.erase( currentHeader);
                // if this is the special case of cookies then delete them all
                if (PLATFORM_STRCASECMP(pcKey, "Cookie")==0)
                    removeAllCookies();
                found=true;
                break;
            }

            uiCount++;
        }

        currentHeader++;
    }
    
    // if the property has not been found then it might be a cookie
    if(!found)
        removeCookie(pcKey);
}

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();
}

const char * HTTPTransport::
getLastChannelError()
{
    if( m_pActiveChannel != NULL)
        return m_pActiveChannel->GetLastErrorMsg().c_str();

    return NULL;
}

void HTTPTransport::
readHTTPHeader()
{    
    logEntryTransport("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; 
       
    resetInputStateMachine();
    
    m_bHasReadBeenDone = true;

    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;
                
                logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_INPUT_STREAMING_ERROR", 
                                           "Socket connection has been closed.")

                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();
        
        // Remove the HTTP header from the buffer since it has been processed.
        m_strReceived = m_strReceived.substr( iHTTPEnd + 4);
        m_iBytesLeft  = m_strReceived.length(); 
    }
    while( m_iResponseHTTPStatusCode == 100); 
    
    // Now have a valid HTTP header that is not 100. Interrogate status code.
    const char *contentType = m_strResponseContentType.c_str();
    if (m_iResponseHTTPStatusCode > 199 && m_iResponseHTTPStatusCode < 300)
    {
        // SOAP return is OK - so fall through
    }
    else if ((contentType != NULL) && (strncmp(contentType, "text/html", 9) != 0)
            && ((m_iResponseHTTPStatusCode > 499) && (m_iResponseHTTPStatusCode < 600)))
    {
        // SOAP Fault should be in here - so fall through
    }
    else if ((m_strResponseLocationURI.length() != 0)
            && ((m_iResponseHTTPStatusCode == 301)
                    || (m_iResponseHTTPStatusCode == 302)
                    || (m_iResponseHTTPStatusCode == 307)))
    {
        // Redirect (HTTP: 301/302/307)
        handleRedirect();
    }
    else
    {
        m_iNbrOfRedirectAttempts = 0;
        m_strBytesToSendRedirect = "";

        // Unknown return code - so wrap up the content into a SOAP fault TODO

        m_strResponseHTTPStatusMessage = std::string( "Server sent HTTP error: '") +
          m_strResponseHTTPStatusMessage +  std::string("'\n");

        m_GetBytesState = eWaitingForHTTPHeader;
        
        logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_HTTP_EXCEPTION", 
                                  m_strResponseHTTPStatusMessage.c_str())

        throw HTTPTransportException( SERVER_TRANSPORT_HTTP_EXCEPTION, m_strResponseHTTPStatusMessage.c_str());
    }  
    
    m_iNbrOfRedirectAttempts = 0;
    m_strBytesToSendRedirect = "";

    logExit()
}

int HTTPTransport::
getNextDataPacket( const char * pcszExceptionMessage, char *bufferToUse, int *bufferLen)
{
    logEntryTransport("HTTPTransport::getNextDataPacket")

    int numberOfBytesRead;

    // Read whatever part of the response message that has arrived at the active channel socket.
    // The buffer used is dependent on whether one is passed in.  There is an internal buffer
    // associated with the class, m_pszRxBuffer, that will be used if one is not passed in.
    // Currently we do not pass buffers into this routine, but in the future we will as an 
    // optimization step...since if we are reading non-protocol data, we should just 
    // directly plop the data into parser buffer.
    if (bufferToUse && bufferLen)
        numberOfBytesRead = m_pActiveChannel->readBytes(bufferToUse, *bufferLen);
    else
        numberOfBytesRead = m_pActiveChannel->readBytes(m_pszRxBuffer, BUF_SIZE);

    if( numberOfBytesRead > 0)
    {
        if (bufferToUse && bufferLen)
            *bufferLen = numberOfBytesRead;
        else
        {
            m_strReceived += m_pszRxBuffer;
            m_iBytesLeft = m_strReceived.length();
        }
    }
    else if( m_strReceived.length() == 0)
    {
        m_bReopenConnection = true;

        if( pcszExceptionMessage != NULL && strlen( pcszExceptionMessage) > 0)
        {
            logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_HTTP_EXCEPTION", 
                                      pcszExceptionMessage)

            throw HTTPTransportException( SERVER_TRANSPORT_HTTP_EXCEPTION, pcszExceptionMessage);
        }
    }

    logExitWithInteger(numberOfBytesRead)
    
    return numberOfBytesRead;
}

int HTTPTransport::
addCookie(const string name, const string value)
{
    logEntryTransport("HTTPTransport::addCookie")

    // trim the name
    string theName(name);
    trim(theName);
    // Make sure that the cookie is not duplicated. This cookie might be replacing one that's already there
    bool b_keyFound=false;
    for (unsigned int i = 0; i < m_vCookies.size(); i++)
    {
        if (m_vCookies[i].first == theName)
        {
            m_vCookies[i].second = (string) value;
            b_keyFound = true;

            break;
        }
    }

    // if cookie has not already been found add it
    if(!b_keyFound)
        m_vCookies.push_back( std::make_pair( theName, value));
    
    logExit()
    
    return AXIS_SUCCESS;
}

int HTTPTransport::
addCookie(const string nameValuePair)
{
    logEntryTransport("HTTPTransport::addCookie")

    // 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

    string nameValue = nameValuePair;
    string::size_type ulKeyEndsAt = nameValuePair.find( ";");

    if( ulKeyEndsAt != std::string::npos)
        nameValue = nameValuePair.substr( 0, ulKeyEndsAt);

    // Now split the nameValue up
    string::size_type nameEndsAt = nameValue.find("=");
    
    string value = "";
    if (nameEndsAt != std::string::npos)
        value = nameValue.substr(nameEndsAt+1);

    int rc = addCookie(nameValue.substr(0, nameEndsAt), value);

    logExit()
    
    return rc;
}

int HTTPTransport::
removeCookie(const string name)
{
     vector < std::pair < std::string,
     std::string > >::iterator currentCookie = m_vCookies.begin();

    while( currentCookie != m_vCookies.end())
    {
        if( strcmp( name.c_str(), (*currentCookie).first.c_str()) == 0)
        {
            m_vCookies.erase( currentCookie);
            return AXIS_SUCCESS;
        }
        currentCookie++;
    }
    
    return AXIS_FAIL;
}

int HTTPTransport::
removeAllCookies()
{
    m_vCookies.clear();
    // we also need to remove it from the header properties that we send.
    // This is done from the deleteTransportMethod before this one is called.
    return AXIS_SUCCESS;
}

void HTTPTransport::
trim(string& str)
{
    string::size_type pos = str.find_last_not_of(' ');
    if(pos != string::npos) 
    {
        str.erase(pos + 1);
        pos = str.find_first_not_of(' ');
        if(pos != string::npos) 
            str.erase(0, pos);
    }
    else 
        str.erase(str.begin(), str.end());
}

void HTTPTransport::
enableTrace(const char* logFilePath, const char *filters)
{
    AxisTrace::setLogFilter(filters);
    AxisTrace::startTrace(logFilePath, false);
    
    if (m_pNormalChannel)
        m_pNormalChannel->enableTrace(logFilePath, filters);
    
    if (m_pSecureChannel)
        m_pSecureChannel->enableTrace(logFilePath, filters);
}

void HTTPTransport::
handleRedirect()
{
    logEntryTransport("HTTPTransport::handleRedirect")

    // close old connection
    closeConnection(true);

    // Setup exception data with redirect location.
    m_strResponseHTTPStatusMessage = std::string( "Redirect: ") +  m_strResponseLocationURI +  std::string("'\n");

    m_GetBytesState = eWaitingForHTTPHeader;

    // See if we can process redirect seamlessly.
    // We only do so if we are going from http -> http or https -> https.
    const char *location = m_strResponseLocationURI.c_str();
    bool throwException = true;
    if (location
            && m_bPerformAutoRedirect
            && m_iNbrOfRedirectAttempts < m_iMaximumAutoRedirects
            && ((m_bChannelSecure && strncmp("https:", location, 6) == 0)
                   || (!m_bChannelSecure && strncmp("http:", location, 5) == 0)))
    {
        throwException = false;
        m_iNbrOfRedirectAttempts++;
        setEndpointUri(location);
        openConnection();
        flushOutput();
        readHTTPHeader();
    }

    if (throwException)
    {
        m_iNbrOfRedirectAttempts = 0;
        m_strBytesToSendRedirect = "";

        logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_REDIRECT_RECEIVED",
                                  m_strResponseHTTPStatusMessage.c_str())

        throw HTTPTransportException( SERVER_TRANSPORT_REDIRECT_RECEIVED, m_strResponseHTTPStatusMessage.c_str());
    }

    logExit()
}
