Mixe for Privacy and Anonymity in the Internet
CAHttpClient.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2000, The JAP-Team
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6 
7  - Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 
14  - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
15  may be used to endorse or promote products derived from this software without specific
16  prior written permission.
17 
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
20 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
27 */
28 #include "StdAfx.h"
29 #include "CAHttpClient.hpp"
30 
40  {
41  static const char* requestF = "GET %s HTTP/1.0\r\n\r\n";
42  static const UINT32 requestFLen=strlen(requestF);
43  if(m_pSocket==NULL)
44  {
45  return E_NOT_CONNECTED;
46  }
47 
48  // put request together
49  UINT32 len = requestFLen + strlen((char *)url);
50  UINT8* requestS = new UINT8[len+1];
51  sprintf((char *)requestS, requestF, (const char *)url);
52  len = strlen((char *)requestS);
53 
54  #ifdef DEBUG
55  CAMsg::printMsg(LOG_DEBUG, "HttpClient now sending: %s\n", requestS);
56  #endif
57 
58  // send it
59  SINT32 ret = m_pSocket->sendFullyTimeOut(requestS,len, 1000, 1000);
60  delete[] requestS;
61  requestS = NULL;
62  if(ret != E_SUCCESS)
63  { // socket error
64  return E_UNKNOWN;
65  }
66  return E_SUCCESS;
67  }
68 
69 
70 
81 SINT32 CAHttpClient::sendPostRequest(const UINT8 * url, const UINT8 * data, const UINT32 dataLen)
82  {
83  UINT8 requestF[] = "POST %s HTTP/1.0\r\nContent-length: %u\r\n\r\n";
84  UINT32 len;
85  UINT8* requestS;
86 
87  if(!m_pSocket)
88  {
89  return E_NOT_CONNECTED;
90  }
91 
92  // put request together
93  len = strlen((char *)requestF) + strlen((char *)url) + 30;
94  requestS=new UINT8[len+1];
95  sprintf((char *)requestS, (char *)requestF, (char *)url, dataLen);
96  len = strlen((char *)requestS);
97  #ifdef DEBUG
98  CAMsg::printMsg(LOG_DEBUG, "HttpClient now sending: %s\n", requestS);
99  #endif
100  SINT32 ret=m_pSocket->sendFullyTimeOut(requestS,len, 1000, 1000);
101  //SINT32 ret=m_pSocket->sendFully(requestS,len);
102  delete[] requestS;
103  requestS = NULL;
104  if(ret!=E_SUCCESS)
105  {
106  return E_UNKNOWN;
107  }
108  ret=m_pSocket->sendFullyTimeOut(data,dataLen, 2000, 1000);
109  //ret=m_pSocket->sendFully(data,dataLen);
110  if(ret != E_SUCCESS)
111  { // socket error
112  return E_UNKNOWN;
113  }
114  return E_SUCCESS;
115  }
116 
128 SINT32 CAHttpClient::parseHTTPHeader(UINT32* contentLength, UINT32 * statusCode, UINT32 msTimeOut)
129  {
130  if(contentLength!=NULL)
131  *contentLength=0;
132  if(statusCode!=NULL)
133  *statusCode=0;
134  char *line = new char[255];
135  SINT32 ret = 0;
136  SINT32 ret2 = E_UNKNOWN;
137 
138  UINT64 currentTime = 0, endTime = 0;
139  bool nbl = false;
140 
141  getcurrentTimeMillis(currentTime);
142  set64(endTime,currentTime);
143  add64(endTime,msTimeOut);
144 
145  if(msTimeOut > 0)
146  {
147  m_pSocket->getNonBlocking(&nbl);
148  m_pSocket->setNonBlocking(true);
149  }
150 
151  if(!m_pSocket)
152  {
153  return E_NOT_CONNECTED;
154  }
155  do
156  {
157  int i=0;
158  UINT8 byte = 0;
159  do//Read a line from the WebServer
160  {
161 
162 receiving:
163  ret = m_pSocket->receive(&byte, 1); //bytewise? ugh!
164  if( (ret == E_AGAIN) && (msTimeOut > 0) )
165  {
166  getcurrentTimeMillis(currentTime);
167  if(!isLesser64(currentTime,endTime))
168  {
169  CAMsg::printMsg(LOG_ERR, "HTTP-Client parseHeader: timeout!\n");
170  ret = E_TIMEDOUT;
171  ret2 = E_TIMEDOUT;
172  break;
173  }
174  msTimeOut=diff64(endTime,currentTime);
175  msSleep(50);
176  goto receiving;
177  }
178  if(byte == '\r' || byte == '\n')
179  {
180  line[i++] = 0;
181  }
182  else
183  {
184  line[i++] = byte;
185  }
186  }
187  while(byte != '\n' && i<255 && ret > 0 );
188 
189  if(ret < 0||i>=255)
190  {
191  CAMsg::printMsg(LOG_CRIT,"HttpClient: Error return code: %i.\n",ret);
192  break;
193  }
194  if(strncmp(line, "HTTP", 4) == 0)
195  {
196  if(statusCode!=NULL && strlen(line)>9) // parse statusCode
197  {
198  *statusCode = atoi(line+9);
199  }
200  if(strstr(line, "200 OK") == NULL)
201  {
202  CAMsg::printMsg(LOG_CRIT,"HttpClient: Error: Server returned: '%s'.\n",line);
203  break;
204  }
205  else
206  ret2=E_SUCCESS;
207  }
209  else if( (strncmp(line, "Content-length: ", 16) == 0) ||
210  (strncmp(line, "Content-Length: ", 16) == 0))
211  {
212  *contentLength = (UINT32) atol(line+16);
213  }
214  #ifdef DEBUG
215  CAMsg::printMsg(LOG_DEBUG,"Server returned: '%s'.\n",line);
216  #endif
217  }
218  while(strlen(line) > 0);//Stop reading of response lines, if an empty line was reveived...
219  if(msTimeOut > 0)
220  {
222  }
223  delete[] line;
224  line = NULL;
225  return ret2;
226  }
227 
234 SINT32 CAHttpClient::getContent(UINT8* a_pContent, UINT32* a_pLength)
235  {
236  if(m_pSocket==NULL)
237  {
238  return E_NOT_CONNECTED;
239  }
240 
241  UINT32 aktIndex = 0;
242  UINT32 len=*a_pLength;
243  while(len>0)
244  {
245  SINT32 ret=m_pSocket->receive(a_pContent+aktIndex,len);
246  if(ret<=0)
247  break;
248  aktIndex+=ret;
249  len-=ret;
250  }
251  *a_pLength=aktIndex;
252  return E_SUCCESS;
253  }
SINT32 getcurrentTimeMillis(UINT64 &u64Time)
Gets the current Systemtime in milli seconds.
Definition: CAUtil.cpp:252
SINT32 msSleep(UINT32 ms)
Sleeps ms milliseconds.
Definition: CAUtil.cpp:406
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
void add64(UINT64 &op1, UINT32 op2)
Definition: CAUtil.hpp:375
bool isLesser64(UINT64 &smallOp1, UINT64 &bigOp2)
Definition: CAUtil.hpp:442
void set64(UINT64 &op1, UINT32 op2)
Definition: CAUtil.hpp:321
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
SINT32 sendGetRequest(const UINT8 *url)
Sends a HTTP GET request to the server.
CASocket * m_pSocket
the socket connection to the http server
SINT32 sendPostRequest(const UINT8 *url, const UINT8 *data, const UINT32 dataLen)
Sends a HTTP POST request to the server.
SINT32 getContent(UINT8 *a_pContent, UINT32 *a_pLength)
Retruns the content of the response.
SINT32 parseHTTPHeader(UINT32 *contentLength, UINT32 *statusCode=NULL, UINT32 msTimeOut=3000)
receives the HTTP header and parses the content length
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
virtual SINT32 receive(UINT8 *buff, UINT32 len)
Will receive some bytes from the socket.
Definition: CASocket.cpp:645
virtual SINT32 getNonBlocking(bool *b)
Definition: CASocket.cpp:972
virtual SINT32 setNonBlocking(bool b)
Definition: CASocket.cpp:947
virtual SINT32 sendFullyTimeOut(const UINT8 *buff, UINT32 len, UINT32 msTimeOut, UINT32 msTimeOutSingleSend)
Sends all data over the network.
Definition: CASocket.cpp:488
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_NOT_CONNECTED
Definition: errorcodes.hpp:22
#define E_AGAIN
Definition: errorcodes.hpp:9
#define E_UNKNOWN
Definition: errorcodes.hpp:3
#define E_TIMEDOUT
Definition: errorcodes.hpp:10
UINT8 data[PAYLOAD_SIZE]
Definition: typedefs.hpp:2
UINT16 len
Definition: typedefs.hpp:0