Changeset 24 in cheroxy for trunk/src/CRXHttpResponse.cpp


Ignore:
Timestamp:
11/14/12 14:00:40 (12 years ago)
Author:
cheese
Message:

#1 change response, threading and proxy work-flow

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/CRXHttpResponse.cpp

    r18 r24  
    1111#include <stdlib.h>
    1212
     13#define CRLF                "\r\n"
     14#define CRLF2               "\r\n\r\n" 
     15
     16#define CONTENT_LENGTH      "Content-Length: "
     17#define TRANSFER_ENCODING   "Transfer-Encoding: "
     18
    1319CRXHttpResponse::CRXHttpResponse (void)
    14     : mStatusCode   (0)
    15 {
     20    : mStatusCode (0),
     21      mIsChunked (false),
     22      mContentLength (0)
     23{
     24    memset (&mContent, 0x00, sizeof (mContent));
     25}
     26
     27CRXHttpResponse::~CRXHttpResponse (void)
     28{
     29    ResetContent ();
    1630}
    1731
    1832void
    19 CRXHttpResponse::SetResponse (const char * aHttpResponse)
    20 {
    21     SetMessage (aHttpResponse);
    22 }
    23 
    24 std::string
    25 CRXHttpResponse::GetResponse (void) const
    26 {
    27     return GetMessage ();
     33CRXHttpResponse::ResetContent (void)
     34{
     35    if (mContent.mBody)
     36        free (mContent.mBody);
     37
     38    memset (&mContent, 0x00, sizeof (mContent));
     39}
     40
     41int
     42CRXHttpResponse::SetResponse (const char    * aHttpResponse,
     43                              const int     aResponseLength)
     44{
     45    int             aResult = 0;
     46
     47    const char      * aEndOfHeader = NULL;
     48    std::string     aHeader;
     49
     50    int             aHeaderLength = 0;
     51    int             aBodyLength = 0;
     52
     53    /*----------------------------------------------------------------*/
     54    if (aResponseLength <= 0)
     55        return ERROR_HTTP_RESPONSE_INVALID_LENGTH;
     56
     57    if (GetHeader ().length () == 0)
     58    {
     59        aEndOfHeader = strstr (aHttpResponse, CRLF2);
     60        if (aEndOfHeader == NULL)
     61            return ERROR_HTTP_RESPONSE_INVALID_FORMAT;
     62
     63        aEndOfHeader += strlen (CRLF2);
     64        aHeaderLength = aEndOfHeader - aHttpResponse;
     65        aHeader.assign (aHttpResponse, aHeaderLength);
     66
     67        SetMessage (aHeader.c_str ());
     68    }
     69
     70    aResult = ParseContent (aHttpResponse + aHeaderLength, aResponseLength - aHeaderLength);
     71    if (aResult)
     72    {
     73        return ERROR_HTTP_RESPONSE_FAILED_TO_PARSE_CONTENT;
     74    }
     75    /*----------------------------------------------------------------*/
     76
     77    return aResult;
    2878}
    2979
     
    3585}
    3686
     87std::string
     88CRXHttpResponse::GetHeader (void) const
     89{
     90    return GetMessage ();
     91}
     92
     93int
     94CRXHttpResponse::GetStatusCode (void) const
     95{
     96    return mStatusCode;
     97}
     98
     99int
     100CRXHttpResponse::GetContentLength (void) const
     101{
     102    return mContentLength;
     103}
     104
     105const char *
     106CRXHttpResponse::GetContentBody (void) const
     107{
     108    return mContent.mBody;
     109}
     110
    37111void
    38112CRXHttpResponse::Parse (void)
    39113{
    40     std::string aHttpStatus     = "";
     114    std::string aValue;
    41115
    42116    char        aStatusCode[64]     = {0x00, };
    43     char        aStatusString[64]   = {0x00, };
     117    char        aStatusName[64]     = {0x00, };
    44118    char        aHttpVersion[64]    = {0x00, };
    45119
    46     /*----------------------------------------------------------------*/
    47     aHttpStatus = GetResponse ().substr (0, mHttpMessage.find ('\r'));
     120    size_t      aBegin      = 0;
     121    size_t      aOffset     = 0;
     122    char        aBuffer[12] = {0x00, };
     123
     124    /*----------------------------------------------------------------*/
     125    aValue = GetHeader ().substr (0, GetHeader ().find (CRLF, 0));
    48126
    49127    /*----------------------------------------------------------------
    50128     * 1. separate first line to <METHOD>, <URL> and <VERSION>
    51129     *----------------------------------------------------------------*/
    52     sscanf (aHttpStatus.c_str (), "%[^ ] %[^ ] %[^ ]\r\n", aHttpVersion, aStatusCode, aStatusString);
     130    sscanf (aValue.c_str (), "%[^ ] %[^ ] %[^ ]\r\n", aHttpVersion, aStatusCode, aStatusName);
    53131    mHttpVersion.assign (aHttpVersion);
    54     mStatusString.assign (aStatusString);
     132    mStatusString.assign (aStatusName);
    55133    mStatusCode = atoi (aStatusCode);
    56     /*----------------------------------------------------------------*/
    57 }
    58 
    59 int
    60 CRXHttpResponse::GetStatusCode (void) const
    61 {
    62     return mStatusCode;
    63 }
     134
     135    /*----------------------------------------------------------------
     136     * 2. get Content-Length or check is chunked
     137     *----------------------------------------------------------------*/
     138    aBegin = GetHeader ().find (CONTENT_LENGTH);
     139    if (aBegin == std::string::npos)
     140    {
     141        /* is really chunked encoding ? */
     142        aBegin = GetHeader ().find (TRANSFER_ENCODING);
     143        if (aBegin == std::string::npos)
     144            return ;
     145
     146        aBegin += strlen (TRANSFER_ENCODING);
     147        aOffset = GetHeader ().find (CRLF, aBegin) - aBegin;
     148
     149        aValue = GetHeader ().substr (aBegin, aOffset);
     150        if (aValue == "chunked")
     151        {
     152            mIsChunked = true;
     153            return ;
     154        }
     155    }
     156
     157    aBegin += strlen (CONTENT_LENGTH);
     158    aOffset = GetHeader ().find (CRLF, aBegin) - aBegin;
     159
     160    aValue = GetHeader ().substr (aBegin, aOffset);
     161    mContentLength = atoi (aValue.c_str ());
     162    /*----------------------------------------------------------------*/
     163}
     164
     165int
     166CRXHttpResponse::ParseContent (const char   * aContent,
     167                               const int    aLength)
     168{
     169    int     aResult = 0;
     170
     171    char    * aReallocPtr = NULL;
     172
     173    /*----------------------------------------------------------------*/
     174
     175    if (!mIsChunked)
     176    {
     177        if (mContentLength <= mContent.mLength)
     178            return aResult;
     179
     180        if (mContent.mBody == NULL)
     181        {
     182            mContent.mBody = static_cast<char *> (calloc (mContentLength, 1));
     183            if (mContent.mBody == NULL)
     184            {
     185                return ERROR_HTTP_RESPONSE_FAILED_TO_MEMORY_ALLOCATION;
     186            }
     187        }
     188    }
     189    else
     190    {
     191        mContentLength += aLength;
     192        aReallocPtr = static_cast<char *> (realloc (mContent.mBody, mContentLength));
     193        if (aReallocPtr == NULL)
     194        {
     195            return ERROR_HTTP_RESPONSE_FAILED_TO_MEMORY_ALLOCATION;
     196        }
     197        mContent.mBody = aReallocPtr;
     198    }
     199
     200    memcpy (mContent.mBody + mContent.mLength, aContent, aLength);
     201    mContent.mLength += aLength;
     202    /*----------------------------------------------------------------*/
     203
     204    return aResult;
     205}
Note: See TracChangeset for help on using the changeset viewer.