Changeset 24 in cheroxy for trunk/src/CRXProxy.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/CRXProxy.cpp

    r23 r24  
    33 */
    44
    5 #include "CRXSocket.h"
    6 #include "CRXHttpRequest.h"
    7 #include "CRXHttpResponse.h"
    8 
    95#include "CRXProxy.h"
    106
    117#include <string.h>
    128
    13 #ifdef _DEBUG
    14 # include <iostream>
    15 using namespace std;
    16 # define PRINT_ERROR        cerr
    17 #else
    18 # define PRINT_ERROR
    19 #endif
    20 
    21 #ifdef _WIN32
    22 # include <process.h>
    23 # define THREAD_TYPE                            void *
    24 # define THREAD_FUNCTION_RETURN                 unsigned int
    25 # define THREAD_FUNCTION_CALLING_CONVENTION     WINAPI
    26 #else
    27 # define THREAD_TYPE                            pthread_t
    28 # define THREAD_FUNCTION_RETURN                 void *
    29 # define THREAD_FUNCTION_CALLING_CONVENTION
    30 #endif
    31 
    32 THREAD_FUNCTION_RETURN
    33 THREAD_FUNCTION_CALLING_CONVENTION
    34 CRXProxyWrapper (void * aThreadArg)
    35 {
    36     int         aResult = 0;
    37     CRXProxy    * aProxy = (CRXProxy *) aThreadArg;
     9CRXProxy::CRXProxy (void)
     10    : mClient (0),
     11      mServer (0)
     12{
     13    /*----------------------------------------------------------------*/
     14    /*----------------------------------------------------------------*/
     15}
     16
     17CRXProxy::~CRXProxy (void)
     18{
     19    /*----------------------------------------------------------------*/
     20    Close ();
     21    /*----------------------------------------------------------------*/
     22}
     23
     24CRXProxy *
     25CRXProxy::GetNewInstance(void)
     26{
     27    /*----------------------------------------------------------------*/
     28    /*----------------------------------------------------------------*/
     29
     30    return new(std::nothrow) CRXProxy ();
     31}
     32
     33void
     34CRXProxy::ReleaseInstance (void)
     35{
     36    /*----------------------------------------------------------------*/
     37    delete this;
     38    /*----------------------------------------------------------------*/
     39}
     40
     41void
     42CRXProxy::SetClientSocket (const int aSocket)
     43{
     44    /*----------------------------------------------------------------*/
     45    if (aSocket <= 0)
     46        return ;
     47
     48    mClient = aSocket;
     49    /*----------------------------------------------------------------*/
     50}
     51
     52void
     53CRXProxy::Close (void)
     54{
     55    /*----------------------------------------------------------------*/
     56    mServer.Close ();
     57    mClient.Close ();
     58    /*----------------------------------------------------------------*/
     59}
     60
     61int
     62CRXProxy::GetStatus (void)
     63{
     64    /*----------------------------------------------------------------*/
     65    /*----------------------------------------------------------------*/
     66
     67    return mProxyStatus;
     68}
     69
     70int
     71CRXProxy::Forward (void)
     72{
     73    int     aResult = 0;
     74
     75    /*----------------------------------------------------------------*/
     76    aResult = ReceiveRequest ();
     77    if (aResult < 0)
     78    {
     79        aResult = ERROR_PROXY_FAILED_TO_RECEIVE_REQUEST;
     80        CRX_ERROR (aResult, "Failed to receive from client");
     81    }
     82
     83    aResult = SendRequest ();
     84    if (aResult < 0)
     85    {
     86        aResult = ERROR_PROXY_FAILED_TO_SEND_REQUEST;
     87        CRX_ERROR (aResult, "Failed to send to server");
     88        return aResult;
     89    }
     90
     91    aResult = ReceiveResponse ();
     92    if (aResult < 0)
     93    {
     94        aResult = ERROR_PROXY_FAILED_TO_RECEIVE_RESPONSE;
     95        CRX_ERROR (aResult, "Failed to receive from server");
     96    }
     97
     98    aResult = SendResponse ();
     99    if (aResult < 0)
     100    {
     101        aResult = ERROR_PROXY_FAILED_TO_SEND_RESPONSE;
     102        CRX_ERROR (aResult, "Failed to send to client");
     103        return aResult;
     104    }
     105    /*----------------------------------------------------------------*/
     106
     107    return aResult;
     108}
     109
     110void
     111CRXProxy::SetHttpRequest (const char * aHttpRequest)
     112{
     113    /*----------------------------------------------------------------*/
     114    mHttpRequest = aHttpRequest;
     115    /*----------------------------------------------------------------*/
     116}
     117
     118char *
     119CRXProxy::GetHttpRequest (char      * aBuffer,
     120                          const int aBufferSize) const
     121{
     122    void * aPtr = static_cast<void *> (aBuffer);
     123
     124    /*----------------------------------------------------------------*/
     125    if (aPtr == NULL)
     126        return NULL;
    38127   
    39     aResult = aProxy->Forward ();
    40     if (aResult)
    41         PRINT_ERROR << aProxy->GetErrorMessage ();
    42 
    43     delete aProxy;
    44     return (THREAD_FUNCTION_RETURN)0;
    45 }
    46 
    47 CRXProxy::CRXProxy (const int aSocket)
    48 {
    49     /*----------------------------------------------------------------*/
    50     mClient = aSocket;
    51     /*----------------------------------------------------------------*/
    52 }
    53 
    54 CRXProxy *
    55 CRXProxy::GetNewInstance(const int aSocket)
    56 {
    57     return new(std::nothrow) CRXProxy (aSocket);
    58 }
    59 
    60 int
    61 CRXProxy::ForwardMT (void)
    62 {
    63     THREAD_TYPE     aThreadID = (THREAD_TYPE)0;
    64     /*----------------------------------------------------------------*/
    65 #ifdef _WIN32
    66     aThreadID = reinterpret_cast<void *> (_beginthreadex (0, 0, CRXProxyWrapper, this, 0, 0));
    67     if (aThreadID == NULL)
    68     {
    69         return -1;
    70     }
    71 
    72     CloseHandle (aThreadID);
    73 
    74     return 0;
    75 #else
    76     return pthread_create (&aThreadID, NULL, CRXProxyWrapper, this);
    77 #endif
    78     /*----------------------------------------------------------------*/
    79 }
    80 
    81 int
    82 CRXProxy::Forward (void)
    83 {
    84     int                 aResult         = 0;
    85     int                 aReceivedSize   = 0;
    86 
    87     const unsigned int  aBufferSize     = 1024 * 16;
    88     char                aBuffer[aBufferSize] = {0x00, };
    89 
    90     CRXHttpRequest      aHttpRequest;
    91 
    92     CRXSocket           aWebServer;
    93 
    94     bool                aIsMoreRequest  = false;
    95 
    96     /*----------------------------------------------------------------*/
    97     do
    98     {
    99         /* BROWSER --- request ---> [PROXY]                  SERVER */
    100         aResult = mClient.Receive (aBuffer, aBufferSize);
     128    if (aBufferSize > 0)
     129        memcpy (aPtr, mHttpRequest.GetHeader ().c_str (), aBufferSize);
     130    /*----------------------------------------------------------------*/
     131
     132    return aBuffer;
     133}
     134
     135int
     136CRXProxy::GetHttpRequestLength (void) const
     137{
     138    /*----------------------------------------------------------------*/
     139    /*----------------------------------------------------------------*/
     140
     141    return mHttpRequest.GetHeader().length ();
     142}
     143
     144void
     145CRXProxy::SetHttpResponse (const char * aHttpResponse)
     146{
     147    /*----------------------------------------------------------------*/
     148    mHttpResponse = aHttpResponse;
     149    /*----------------------------------------------------------------*/
     150}
     151
     152char *
     153CRXProxy::GetHttpResponse (char         * aBuffer,
     154                           const int    aBufferSize) const
     155{
     156    void    * aPtr = static_cast<void *> (aBuffer);
     157
     158    int     aRemainLength = aBufferSize;
     159
     160    /*----------------------------------------------------------------*/
     161    if (aPtr == NULL)
     162        return NULL;
     163
     164    if (aRemainLength > 0)
     165        memcpy (aPtr, mHttpResponse.GetHeader ().c_str (), aRemainLength);
     166
     167    aRemainLength -= mHttpResponse.GetHeader ().length ();
     168
     169    if (aRemainLength > 0)
     170        memcpy (aPtr, mHttpResponse.GetContentBody (), aRemainLength);
     171    /*----------------------------------------------------------------*/
     172
     173    return aBuffer;
     174}
     175
     176int
     177CRXProxy::GetHttpResponseLength (void) const
     178{
     179    /*----------------------------------------------------------------*/
     180    /*----------------------------------------------------------------*/
     181
     182    return mHttpResponse.GetHeader ().length ()
     183         + mHttpResponse.GetContentLength ();
     184}
     185
     186int
     187CRXProxy::ReceiveRequest (void)
     188{
     189    int                 aResult     = 0;
     190
     191    const unsigned int  aBufferSize = 1024 * 56;
     192    char                aBuffer[aBufferSize + 1] = {0x00, };
     193
     194    /*----------------------------------------------------------------*/
     195    aResult = mClient.Receive (aBuffer, aBufferSize);
     196    if (aResult < 0)
     197    {
     198        aResult = ERROR_PROXY_FAILED_TO_RECEIVE_REQUEST;
     199        CRX_ERROR_ADD (mClient.GetErrorMessage ().c_str ());
     200        CRX_ERROR (aResult, "Failed to receive from client");
     201        return aResult;
     202    }
     203
     204    /* parse http request */
     205    mHttpRequest = aBuffer;
     206    /*----------------------------------------------------------------*/
     207
     208    return aResult < 0 ? aResult : 0;
     209}
     210
     211int
     212CRXProxy::SendRequest (void)
     213{
     214    int     aResult = 0;
     215    int     aSize   = mHttpRequest.GetHeader ().length ();
     216
     217    /*----------------------------------------------------------------*/
     218    if (!mServer)
     219    {
     220        /* connect */
     221        aResult = mServer.Connect (mHttpRequest.GetHost (), mHttpRequest.GetPort (), 1);
    101222        if (aResult < 0)
    102223        {
    103             CRX_ERROR_ADD (mClient.GetErrorMessage ().c_str ());
    104             CRX_ERROR (aResult, "Failed to receive from browser");
     224            aResult = ERROR_PROXY_FAILED_TO_CONNECT_TO_SERVER;
     225            CRX_ERROR_ADD (mServer.GetErrorMessage ().c_str ());
     226            CRX_ERROR (aResult, "Failed to connect to server <%s>", mHttpRequest.GetURL ().c_str ());
     227            return aResult;
     228        }
     229    }
     230
     231    aResult = mServer.Send (mHttpRequest.GetHeader ().c_str (), aSize);
     232    if (aResult != aSize)
     233    {
     234        CRX_ERROR_ADD (mServer.GetErrorMessage ().c_str ());
     235        CRX_ERROR (aResult, "Failed to send to server <%s>", mHttpRequest.GetURL ().c_str ());
     236    }
     237    /*----------------------------------------------------------------*/
     238
     239    return aResult < 0 ? aResult : 0;
     240}
     241
     242int
     243CRXProxy::ReceiveResponse (void)
     244{
     245    int                 aResult         = 0;
     246
     247    const unsigned int  aBufferSize     = 1024 * 64;
     248    char                aBuffer[aBufferSize + 1] = {0x00, };
     249
     250    std::string         aHttpResponse;
     251
     252    /*----------------------------------------------------------------*/
     253    for (;;)
     254    {
     255        memset (aBuffer, 0x00, sizeof (aBuffer));
     256
     257        aResult = mServer.Receive (aBuffer, aBufferSize);
     258        if (aResult < 0)
     259        {
     260            aResult = ERROR_PROXY_FAILED_TO_RECEIVE_REQUEST;
     261            CRX_ERROR_ADD (mServer.GetErrorMessage ().c_str ());
     262            CRX_ERROR (aResult, "Failed to receive from server");
     263            return aResult;
     264        }
     265        else if (aResult == 0)
     266        {
    105267            break;
    106268        }
    107         aReceivedSize = aResult;
    108 
    109         /* BROWSER ?--- waiting --- [PROXY] --- connect ---> SERVER */
    110         if (!aWebServer)
     269
     270        aResult = mHttpResponse.SetResponse (aBuffer, aResult);
     271        if (aResult)
    111272        {
    112             /* parse http request */
    113             aHttpRequest = aBuffer;
    114 
    115             /* connect */
    116             aResult = aWebServer.Connect (aHttpRequest.GetHost (), aHttpRequest.GetPort (), 1);
    117             if (aResult < 0)
    118             {
    119                 CRX_ERROR_ADD (aWebServer.GetErrorMessage ().c_str ());
    120                 CRX_ERROR (aResult, "Failed to connect to server <%s>", aHttpRequest.GetURL ().c_str ());
    121                 return aResult;
    122             }
    123         }
    124 
    125         /* BROWSER ?--- waiting --- [PROXY] --- request ---> SERVER */
    126         aResult = aWebServer.Send (aBuffer, aReceivedSize);
    127         if (aResult != aReceivedSize)
    128         {
    129             CRX_ERROR_ADD (aWebServer.GetErrorMessage ().c_str ());
    130             CRX_ERROR (aResult, "Failed to send to server <%s>", aHttpRequest.GetURL ().c_str ());
     273            aResult = ERROR_PROXY_FAILED_TO_SET_RESPONSE;
     274            CRX_ERROR (aResult, "Failed to set response");
    131275            return aResult;
    132276        }
    133 
    134         /* BROWSER <--- response--- [PROXY] <--- response--- SERVER */
    135         for (;;)
    136         {
    137             memset (aBuffer, 0x00, aBufferSize);
    138 
    139             aResult = aWebServer.Receive (aBuffer, aBufferSize);
    140             if (aResult < 0)
    141             {
    142                 CRX_ERROR_ADD (aWebServer.GetErrorMessage ().c_str ());
    143                 CRX_ERROR (aResult, "Failed to receive <%s>", aHttpRequest.GetURL ().c_str ());
    144                 break;
    145             }
    146             else if (aResult == 0)
    147             {
    148                 break;
    149             }
    150             aReceivedSize = aResult;
    151 
    152             aResult = mClient.Send (aBuffer, aReceivedSize);
    153             if (aResult != aReceivedSize)
    154             {
    155                 CRX_ERROR_ADD (mClient.GetErrorMessage ().c_str ());
    156                 CRX_ERROR (aResult, "Failed to send <%s>", aHttpRequest.GetURL ().c_str ());
    157                 break;
    158             }
    159         }
    160     } while (aIsMoreRequest);
    161 
    162     /*----------------------------------------------------------------*/
    163     mClient.Close ();
    164     aWebServer.Close ();
    165 
    166     return aResult;
    167 }
     277    }
     278    /*----------------------------------------------------------------*/
     279
     280    return aResult < 0 ? aResult : 0;
     281}
     282
     283int
     284CRXProxy::SendResponse (void)
     285{
     286    int     aResult = 0;
     287    int     aSize   = 0;
     288
     289    /*----------------------------------------------------------------*/
     290    aSize = mHttpResponse.GetHeader ().length ();;
     291    aResult = mClient.Send (mHttpResponse.GetHeader ().c_str (), aSize);
     292    if (aResult != aSize)
     293    {
     294        CRX_ERROR_ADD (mClient.GetErrorMessage ().c_str ());
     295        CRX_ERROR (aResult, "Failed to send to client");
     296        return aResult;
     297    }
     298
     299    aSize = mHttpResponse.GetContentLength ();
     300    aResult = mClient.Send (mHttpResponse.GetContentBody (), aSize);
     301    if (aResult != aSize)
     302    {
     303        CRX_ERROR_ADD (mClient.GetErrorMessage ().c_str ());
     304        CRX_ERROR (aResult, "Failed to send to client");
     305    }
     306    /*----------------------------------------------------------------*/
     307
     308    return aResult < 0 ? aResult : 0;
     309}
Note: See TracChangeset for help on using the changeset viewer.