Mixe for Privacy and Anonymity in the Internet
Public Member Functions | Private Attributes
CAHttpClient Class Reference

Very simple http client. More...

#include <CAHttpClient.hpp>

Collaboration diagram for CAHttpClient:
[legend]

List of all members.

Public Member Functions

 CAHttpClient (CASocket *pSocket)
 CAHttpClient ()
 ~CAHttpClient ()
SINT32 setSocket (CASocket *pSocket)
SINT32 sendGetRequest (const UINT8 *url)
 Sends a HTTP GET request to the server.
SINT32 sendPostRequest (const UINT8 *url, const UINT8 *data, const UINT32 dataLen)
 Sends a HTTP POST request to the server.
SINT32 parseHTTPHeader (UINT32 *contentLength, UINT32 *statusCode=NULL, UINT32 msTimeOut=3000)
 receives the HTTP header and parses the content length
SINT32 getContent (UINT8 *a_pContent, UINT32 *a_pLength)
 Retruns the content of the response.

Private Attributes

CASocketm_pSocket
 the socket connection to the http server

Detailed Description

Very simple http client.

Used by CAInfoService and CAAccountingBIInterface. Must be initialized with a connected socket. Note that the socket is still owned by the caller. CAHttpClient will not delete the socket

Author:
Bastian Voigt

Definition at line 43 of file CAHttpClient.hpp.


Constructor & Destructor Documentation

CAHttpClient::CAHttpClient ( CASocket pSocket) [inline]

Definition at line 46 of file CAHttpClient.hpp.

References m_pSocket.

    {
      m_pSocket = pSocket;
    }

Definition at line 51 of file CAHttpClient.hpp.

References m_pSocket.

    {
      m_pSocket = NULL;
    }

Definition at line 56 of file CAHttpClient.hpp.

{}

Member Function Documentation

SINT32 CAHttpClient::getContent ( UINT8 a_pContent,
UINT32 a_pLength 
)

Retruns the content of the response.

Gets the content of a HTTP response.

Parameters:
a_pContentbuff which receives the content
a_pLengthon input contains the size of a_pContent, on return contains the number of received bytes
Return values:
E_NOT_CONNECTEDif socket is not connected
E_SUCCESSif successful

Definition at line 234 of file CAHttpClient.cpp.

References E_NOT_CONNECTED, E_SUCCESS, len, m_pSocket, and CASocket::receive().

Referenced by CAInfoService::getPaymentInstance().

  {
    if(m_pSocket==NULL)
      {
        return E_NOT_CONNECTED;
      }
      
    UINT32 aktIndex = 0;
    UINT32 len=*a_pLength;
    while(len>0)
      {
        SINT32 ret=m_pSocket->receive(a_pContent+aktIndex,len);
        if(ret<=0)
          break;
        aktIndex+=ret;
        len-=ret; 
      }
    *a_pLength=aktIndex;  
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CAHttpClient::parseHTTPHeader ( UINT32 contentLength,
UINT32 statusCode = NULL,
UINT32  msTimeOut = 3000 
)

receives the HTTP header and parses the content length

Receives the HTTP header and parses the content length.

Parameters:
contentLengthreceives the parsed content length
statusCodeif set, receives the http statuscode (200, 403, 404, ...)
Return values:
E_SUCCESSif all is OK
E_UNKNOWNif the server returned a http errorcode TODO: Verify that "HTTP/1.1 200 OK" must be the first line!
Parameters:
contentLengthreceives the parsed content length
statusCodeif set, receives the http statuscode (200, 403, 404, ...)
msTimeOuttime in ms for receiving the HTTPHeader (<=0 means no timeout)
Return values:
E_SUCCESSif all is OK
E_NOT_CONNECTEDif the connection to the Web-Server was lost
E_UNKNOWNif the server returned a http errorcode, in this case statusCode is set to 0 and contentLength is set to 0
Todo:

: Verify that "HTTP/1.1 200 OK" must be the first line!

: Maybe set an other statusCode in case of an error ?

TODO: do it better (case insensitive compare!)

Definition at line 128 of file CAHttpClient.cpp.

References add64(), diff64(), E_AGAIN, E_NOT_CONNECTED, E_SUCCESS, E_TIMEDOUT, E_UNKNOWN, getcurrentTimeMillis(), CASocket::getNonBlocking(), isLesser64(), m_pSocket, msSleep(), CAMsg::printMsg(), CASocket::receive(), set64(), and CASocket::setNonBlocking().

Referenced by CAInfoService::getPaymentInstance(), CAInfoService::sendMixHelo(), CAAccountingBIInterface::settle(), and CAAccountingBIInterface::settleAll().

  {
    if(contentLength!=NULL)
      *contentLength=0;
    if(statusCode!=NULL)
      *statusCode=0;
    char *line = new char[255];
    SINT32 ret = 0;
    SINT32 ret2 = E_UNKNOWN;
    
    UINT64 currentTime = 0, endTime = 0;
    bool nbl = false;
    
    getcurrentTimeMillis(currentTime);
    set64(endTime,currentTime);
    add64(endTime,msTimeOut);
    
    if(msTimeOut > 0)
    {
      m_pSocket->getNonBlocking(&nbl);
      m_pSocket->setNonBlocking(true);
    }
    
    if(!m_pSocket)
    {
      return E_NOT_CONNECTED;
    }
    do
    {
      int i=0;
      UINT8 byte = 0;
      do//Read a line from the WebServer
      {
        
receiving:        
        ret = m_pSocket->receive(&byte, 1); //bytewise? ugh!
        if( (ret == E_AGAIN) && (msTimeOut > 0) )
        {
          getcurrentTimeMillis(currentTime);
          if(!isLesser64(currentTime,endTime))
          {
            CAMsg::printMsg(LOG_ERR, "HTTP-Client parseHeader: timeout!\n");
            ret = E_TIMEDOUT;
            ret2 = E_TIMEDOUT;
            break;
          }
          msTimeOut=diff64(endTime,currentTime);
          msSleep(50);
          goto receiving;
        }
        if(byte == '\r' || byte == '\n')
        {
          line[i++] = 0;
        }
        else
        {
          line[i++] = byte;
        }
      }
      while(byte != '\n' && i<255 && ret > 0 );

      if(ret < 0||i>=255)
      {
        CAMsg::printMsg(LOG_CRIT,"HttpClient: Error return code: %i.\n",ret);
        break;
      }
      if(strncmp(line, "HTTP", 4) == 0)
        {
          if(statusCode!=NULL && strlen(line)>9) // parse statusCode
            {
              *statusCode = atoi(line+9);
            }
          if(strstr(line, "200 OK") == NULL)
            {
              CAMsg::printMsg(LOG_CRIT,"HttpClient: Error: Server returned: '%s'.\n",line);
              break;
            }
          else
            ret2=E_SUCCESS;
        }
      else if( (strncmp(line, "Content-length: ", 16) == 0) ||
                  (strncmp(line, "Content-Length: ", 16) == 0))
        {
          *contentLength = (UINT32) atol(line+16);
        }
      #ifdef DEBUG
        CAMsg::printMsg(LOG_DEBUG,"Server returned: '%s'.\n",line);
      #endif  
    } 
    while(strlen(line) > 0);//Stop reading of response lines, if an empty line was reveived...
    if(msTimeOut > 0)
    {
      m_pSocket->setNonBlocking(nbl);
    }
    delete[] line;
    line = NULL;
    return ret2;
  }

Here is the call graph for this function:

Sends a HTTP GET request to the server.

Parameters:
urlthe local part of the URL requested (e.g. "/settle")
Returns:
E_UNKNOWN on socket errors
E_NOT_CONNECTED if the connection was lost
E_SUCCESS if all is OK
Parameters:
urlthe local part of the URL requested (e.g. "/settle")
Return values:
E_UNKNOWNon socket errors
E_NOT_CONNECTEDif the connection was lost
E_SUCCESSif all is OK

Definition at line 39 of file CAHttpClient.cpp.

References E_NOT_CONNECTED, E_SUCCESS, E_UNKNOWN, len, m_pSocket, CAMsg::printMsg(), and CASocket::sendFullyTimeOut().

Referenced by CAInfoService::getPaymentInstance().

  {
    static const UINT8 requestF[] = "GET %s HTTP/1.0\r\n\r\n";
    static const UINT32 requestFLen=strlen((char *)requestF);
    if(m_pSocket==NULL)
      {
        return E_NOT_CONNECTED;
      }
    
    // put request together
    UINT32 len = requestFLen + strlen((char *)url);
    UINT8* requestS = new UINT8[len+1];
    sprintf((char *)requestS, (const char *)requestF, (const char *)url);
    len = strlen((char *)requestS);
  
    #ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG, "HttpClient now sending: %s\n", requestS);
    #endif
    
    // send it
    SINT32 ret = m_pSocket->sendFullyTimeOut(requestS,len, 1000, 1000);
    delete[] requestS;
    requestS = NULL;
    if(ret != E_SUCCESS)
      { // socket error
        return E_UNKNOWN;
      }
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CAHttpClient::sendPostRequest ( const UINT8 url,
const UINT8 data,
const UINT32  dataLen 
)

Sends a HTTP POST request to the server.

Parameters:
urlthe local part of the requested URL (e.g. "/settle")
dataa buffer containing the data
dataLenthe length of the data in bytes
Returns:
E_UNKNOWN on socket errors
E_NOT_CONNECTED if the connection was lost
E_SUCCESS if all is OK

Definition at line 81 of file CAHttpClient.cpp.

References E_NOT_CONNECTED, E_SUCCESS, E_UNKNOWN, len, m_pSocket, CAMsg::printMsg(), and CASocket::sendFullyTimeOut().

Referenced by CAAccountingBIInterface::settle(), and CAAccountingBIInterface::settleAll().

  {
    UINT8 requestF[] = "POST %s HTTP/1.0\r\nContent-length: %u\r\n\r\n";
    UINT32 len;
    UINT8* requestS;
    
    if(!m_pSocket)
      {
        return E_NOT_CONNECTED;
      }
  
    // put request together
    len = strlen((char *)requestF) + strlen((char *)url) + 30;
    requestS=new UINT8[len+1];
    sprintf((char *)requestS, (char *)requestF, (char *)url, dataLen);
    len = strlen((char *)requestS);
    #ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG, "HttpClient now sending: %s\n", requestS);
    #endif
    SINT32 ret=m_pSocket->sendFullyTimeOut(requestS,len, 1000, 1000);
    //SINT32 ret=m_pSocket->sendFully(requestS,len);
    delete[] requestS;
    requestS = NULL;
    if(ret!=E_SUCCESS)
      {
        return E_UNKNOWN;
      }
    ret=m_pSocket->sendFullyTimeOut(data,dataLen, 2000, 1000);
    //ret=m_pSocket->sendFully(data,dataLen);
    if(ret != E_SUCCESS)
      { // socket error
        return E_UNKNOWN;
      }
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CAHttpClient::setSocket ( CASocket pSocket) [inline]

Member Data Documentation

the socket connection to the http server

Definition at line 102 of file CAHttpClient.hpp.

Referenced by CAHttpClient(), getContent(), parseHTTPHeader(), sendGetRequest(), sendPostRequest(), and setSocket().


The documentation for this class was generated from the following files: