Mixe for Privacy and Anonymity in the Internet
CAHttpClient.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team 
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification, 
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice, 
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice, 
00011     this list of conditions and the following disclaimer in the documentation and/or 
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 
00015     may be used to endorse or promote products derived from this software without specific 
00016     prior written permission. 
00017 
00018   
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #include "CAHttpClient.hpp"
00030 
00039 SINT32 CAHttpClient::sendGetRequest(const UINT8 * url)
00040   {
00041     static const UINT8 requestF[] = "GET %s HTTP/1.0\r\n\r\n";
00042     static const UINT32 requestFLen=strlen((char *)requestF);
00043     if(m_pSocket==NULL)
00044       {
00045         return E_NOT_CONNECTED;
00046       }
00047     
00048     // put request together
00049     UINT32 len = requestFLen + strlen((char *)url);
00050     UINT8* requestS = new UINT8[len+1];
00051     sprintf((char *)requestS, (const char *)requestF, (const char *)url);
00052     len = strlen((char *)requestS);
00053   
00054     #ifdef DEBUG
00055       CAMsg::printMsg(LOG_DEBUG, "HttpClient now sending: %s\n", requestS);
00056     #endif
00057     
00058     // send it
00059     SINT32 ret = m_pSocket->sendFullyTimeOut(requestS,len, 1000, 1000);
00060     delete[] requestS;
00061     requestS = NULL;
00062     if(ret != E_SUCCESS)
00063       { // socket error
00064         return E_UNKNOWN;
00065       }
00066     return E_SUCCESS;
00067   }
00068 
00069 
00070 
00081 SINT32 CAHttpClient::sendPostRequest(const UINT8 * url, const UINT8 * data, const UINT32 dataLen)
00082   {
00083     UINT8 requestF[] = "POST %s HTTP/1.0\r\nContent-length: %u\r\n\r\n";
00084     UINT32 len;
00085     UINT8* requestS;
00086     
00087     if(!m_pSocket)
00088       {
00089         return E_NOT_CONNECTED;
00090       }
00091   
00092     // put request together
00093     len = strlen((char *)requestF) + strlen((char *)url) + 30;
00094     requestS=new UINT8[len+1];
00095     sprintf((char *)requestS, (char *)requestF, (char *)url, dataLen);
00096     len = strlen((char *)requestS);
00097     #ifdef DEBUG
00098       CAMsg::printMsg(LOG_DEBUG, "HttpClient now sending: %s\n", requestS);
00099     #endif
00100     SINT32 ret=m_pSocket->sendFullyTimeOut(requestS,len, 1000, 1000);
00101     //SINT32 ret=m_pSocket->sendFully(requestS,len);
00102     delete[] requestS;
00103     requestS = NULL;
00104     if(ret!=E_SUCCESS)
00105       {
00106         return E_UNKNOWN;
00107       }
00108     ret=m_pSocket->sendFullyTimeOut(data,dataLen, 2000, 1000);
00109     //ret=m_pSocket->sendFully(data,dataLen);
00110     if(ret != E_SUCCESS)
00111       { // socket error
00112         return E_UNKNOWN;
00113       }
00114     return E_SUCCESS;
00115   }
00116 
00128 SINT32 CAHttpClient::parseHTTPHeader(UINT32* contentLength, UINT32 * statusCode, UINT32 msTimeOut)
00129   {
00130     if(contentLength!=NULL)
00131       *contentLength=0;
00132     if(statusCode!=NULL)
00133       *statusCode=0;
00134     char *line = new char[255];
00135     SINT32 ret = 0;
00136     SINT32 ret2 = E_UNKNOWN;
00137     
00138     UINT64 currentTime = 0, endTime = 0;
00139     bool nbl = false;
00140     
00141     getcurrentTimeMillis(currentTime);
00142     set64(endTime,currentTime);
00143     add64(endTime,msTimeOut);
00144     
00145     if(msTimeOut > 0)
00146     {
00147       m_pSocket->getNonBlocking(&nbl);
00148       m_pSocket->setNonBlocking(true);
00149     }
00150     
00151     if(!m_pSocket)
00152     {
00153       return E_NOT_CONNECTED;
00154     }
00155     do
00156     {
00157       int i=0;
00158       UINT8 byte = 0;
00159       do//Read a line from the WebServer
00160       {
00161         
00162 receiving:        
00163         ret = m_pSocket->receive(&byte, 1); //bytewise? ugh!
00164         if( (ret == E_AGAIN) && (msTimeOut > 0) )
00165         {
00166           getcurrentTimeMillis(currentTime);
00167           if(!isLesser64(currentTime,endTime))
00168           {
00169             CAMsg::printMsg(LOG_ERR, "HTTP-Client parseHeader: timeout!\n");
00170             ret = E_TIMEDOUT;
00171             ret2 = E_TIMEDOUT;
00172             break;
00173           }
00174           msTimeOut=diff64(endTime,currentTime);
00175           msSleep(50);
00176           goto receiving;
00177         }
00178         if(byte == '\r' || byte == '\n')
00179         {
00180           line[i++] = 0;
00181         }
00182         else
00183         {
00184           line[i++] = byte;
00185         }
00186       }
00187       while(byte != '\n' && i<255 && ret > 0 );
00188 
00189       if(ret < 0||i>=255)
00190       {
00191         CAMsg::printMsg(LOG_CRIT,"HttpClient: Error return code: %i.\n",ret);
00192         break;
00193       }
00194       if(strncmp(line, "HTTP", 4) == 0)
00195         {
00196           if(statusCode!=NULL && strlen(line)>9) // parse statusCode
00197             {
00198               *statusCode = atoi(line+9);
00199             }
00200           if(strstr(line, "200 OK") == NULL)
00201             {
00202               CAMsg::printMsg(LOG_CRIT,"HttpClient: Error: Server returned: '%s'.\n",line);
00203               break;
00204             }
00205           else
00206             ret2=E_SUCCESS;
00207         }
00209       else if( (strncmp(line, "Content-length: ", 16) == 0) ||
00210                   (strncmp(line, "Content-Length: ", 16) == 0))
00211         {
00212           *contentLength = (UINT32) atol(line+16);
00213         }
00214       #ifdef DEBUG
00215         CAMsg::printMsg(LOG_DEBUG,"Server returned: '%s'.\n",line);
00216       #endif  
00217     } 
00218     while(strlen(line) > 0);//Stop reading of response lines, if an empty line was reveived...
00219     if(msTimeOut > 0)
00220     {
00221       m_pSocket->setNonBlocking(nbl);
00222     }
00223     delete[] line;
00224     line = NULL;
00225     return ret2;
00226   }
00227 
00234 SINT32 CAHttpClient::getContent(UINT8* a_pContent, UINT32* a_pLength)
00235   {
00236     if(m_pSocket==NULL)
00237       {
00238         return E_NOT_CONNECTED;
00239       }
00240       
00241     UINT32 aktIndex = 0;
00242     UINT32 len=*a_pLength;
00243     while(len>0)
00244       {
00245         SINT32 ret=m_pSocket->receive(a_pContent+aktIndex,len);
00246         if(ret<=0)
00247           break;
00248         aktIndex+=ret;
00249         len-=ret; 
00250       }
00251     *a_pLength=aktIndex;  
00252     return E_SUCCESS;
00253   }