aboutsummaryrefslogtreecommitdiff
path: root/src/old/http.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2007-04-03 03:49:53 +0000
committerMike Buland <eichlan@xagasoft.com>2007-04-03 03:49:53 +0000
commitf4c20290509d7ed3a8fd5304577e7a4cc0b9d974 (patch)
tree13cdf64f7cf134f397a7165b7a3fe0807e37026b /src/old/http.cpp
parent74d4c8cd27334fc7204d5a8773deb3d424565778 (diff)
downloadlibbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.gz
libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.bz2
libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.tar.xz
libbu++-f4c20290509d7ed3a8fd5304577e7a4cc0b9d974.zip
Ok, no code is left in src, it's all in src/old. We'll gradually move code back
into src as it's fixed and re-org'd. This includes tests, which, I may write a unit test system into libbu++ just to make my life easier.
Diffstat (limited to 'src/old/http.cpp')
-rw-r--r--src/old/http.cpp377
1 files changed, 377 insertions, 0 deletions
diff --git a/src/old/http.cpp b/src/old/http.cpp
new file mode 100644
index 0000000..df7dafe
--- /dev/null
+++ b/src/old/http.cpp
@@ -0,0 +1,377 @@
1#include <string.h>
2#include <stdlib.h>
3#include "http.h"
4#include "hashfunctionstring.h"
5
6Http::Http( Connection *pConnection ) : hReqHeader( new HashFunctionString(), 100 )
7{
8 pCon = pConnection;
9 nParseState = parseInit;
10}
11
12Http::~Http()
13{
14 for( int j = 0; j < lStrings.getSize(); j++ )
15 {
16 delete (std::string *)lStrings[j];
17 }
18}
19
20bool Http::parseRequest()
21{
22 for(;;)
23 {
24 pCon->readInput();
25 switch( nParseState )
26 {
27 case parseInit:
28 {
29 int nLen = pCon->scanInputFor( CR );
30 if( nLen == -1 )
31 {
32 return false;
33 }
34 else
35 {
36 nReqType = getRequestType( pCon->getInput() );
37 pCon->usedInput( pCon->scanInputFor(' ')+1 );
38
39 nLen = pCon->scanInputFor(' ');
40 sReqURI.append( pCon->getInput(), nLen );
41 pCon->usedInput( nLen+1 );
42
43 if( !strncmp( pCon->getInput(), "HTTP/", 5 ) )
44 {
45 char mbuf[2]={'\0','\0'};
46 unsigned char major, minor;
47
48 pCon->usedInput( 5 );
49 mbuf[0] = pCon->getInput()[0];
50 major = (unsigned char)atoi(mbuf);
51 mbuf[0] = pCon->getInput()[2];
52 minor = (unsigned char)atoi(mbuf);
53 setRequestVersion( major, minor );
54 if( checkRequestVer() )
55 {
56 nParseState = parseHeader;
57 }
58 else
59 {
60 setResponseStatus( statusHTTPVersionNotSupported );
61 //printf("Verson not supported.\n");
62 return true;
63 }
64
65 pCon->usedInput( 5 );
66 }
67 else
68 {
69 setResponseStatus( statusBadRequest );
70 }
71
72 //return false;
73 }
74 }
75 break;
76
77 case parseHeader:
78 {
79 int nLen = pCon->scanInputFor( CR );
80 //printf("nLen = %d: :::%s:::\n", nLen, pCon->getInput() );
81 if( nLen == -1 )
82 {
83 pCon->readInput( 1, 0);
84 }
85 else if( nLen == 0 )
86 {
87 // We've got our double-newline, time for content.
88 pCon->usedInput( 2 );
89 setResponseStatus( statusOK );
90 return true;
91 }
92 else
93 {
94 nLen = pCon->scanInputFor(':');
95 if( nLen == -1 )
96 {
97 //printf("No colon? what are you trying to pull?\n");
98 }
99 else
100 {
101 std::string *pName = new std::string( pCon->getInput(), nLen );
102 lStrings.append( pName );
103 pCon->usedInput( nLen+1 );
104
105 nLen = pCon->scanInputFor( CR );
106 std::string *pValue = convSpaceString( pCon->getInput(), nLen );
107 lStrings.append( pValue );
108 pCon->usedInput( nLen+2 );
109
110 hReqHeader.insert(
111 pName->c_str(),
112 pValue->c_str()
113 );
114
115 //printf("::%s = \"%s\"\n",
116 // pName->c_str(),
117 // pValue->c_str()
118 // );
119 }
120 }
121 }
122 break;
123
124 case parseFinished:
125 break;
126 }
127 }
128}
129
130bool Http::buildResponse( short nResponseCode, const char *sResponse )
131{
132 if( nResponseCode > 0 )
133 {
134 nResStatus = nResponseCode;
135 }
136
137 if( sResponse == NULL )
138 {
139 sResStatusStr = "uh yeah";
140 }
141 else
142 {
143 sResStatusStr = sResponse;
144 }
145
146 time_t curTime;
147 time( &curTime );
148 gmtime_r( &curTime, &tResTime );
149
150 sServerStr = "libbu++ Http/0.0.1";
151 bResPersistant = false;
152
153 //char buf[30];
154 //strftime( buf, 30, "%a, %d %b %Y %H:%M:%S GMT", &tResponseTime );
155
156 return true;
157}
158
159bool Http::sendResponse()
160{
161 char buf[256];
162
163 sprintf( buf, "HTTP/1.1 %d %s\r\n", nResStatus, sResStatusStr.c_str() );
164 pCon->appendOutput( buf );
165
166 strftime( buf, 256, "Date: %a, %d %b %Y %H:%M:%S GMT\r\n", &tResTime );
167 pCon->appendOutput( buf );
168
169 sprintf( buf, "Server: %s\r\n", sServerStr.c_str() );
170 pCon->appendOutput( buf );
171
172 if( bResPersistant )
173 {
174 }
175 else
176 {
177 pCon->appendOutput("Connection: close\r\n");
178 }
179
180 sprintf( buf, "Content-Type: %s\r\n", sResMime.c_str() );
181 pCon->appendOutput( buf );
182
183 sprintf( buf, "Content-Length: %d\r\n", sResContent.size() );
184 pCon->appendOutput( buf );
185
186 pCon->appendOutput("\r\n");
187
188 pCon->appendOutput( sResContent.c_str(), sResContent.size() );
189
190 return true;
191}
192
193void Http::setResponsePersistant( bool bPersistant )
194{
195 bResPersistant = bPersistant;
196}
197
198void Http::setResponseContent( const char *sMime, const char *sContent, int nLen )
199{
200 sResMime = sMime;
201 sResContent.erase();
202 sResContent.append( sContent, nLen );
203}
204
205std::string *Http::convSpaceString( const char *sStr, int nLen )
206{
207 int nNewLen = 0;
208 bool bStart = true;
209 bool bSpace = false;
210
211 for( int j = 0; j < nLen; j++ )
212 {
213 if( sStr[j] == ' ' || sStr[j] == '\t' )
214 {
215 if( bStart )
216 {
217 }
218 else if( bSpace == false )
219 {
220 bSpace = true;
221 nNewLen++;
222 }
223 }
224 else
225 {
226 bStart = false;
227 bSpace = false;
228 nNewLen++;
229 }
230 }
231 if( bSpace )
232 {
233 nNewLen--;
234 }
235
236 std::string *pSStr = new std::string;
237 //char *pStr = pSStr->c_str();
238 nNewLen = 0;
239 bStart = true;
240 bSpace = false;
241
242 for( int j = 0; j < nLen; j++ )
243 {
244 if( sStr[j] == ' ' || sStr[j] == '\t' )
245 {
246 if( bStart )
247 {
248 }
249 else if( bSpace == false )
250 {
251 bSpace = true;
252 *pSStr += ' ';
253 //pStr[nNewLen++] = ' ';
254 }
255 }
256 else
257 {
258 bStart = false;
259 bSpace = false;
260 *pSStr += sStr[j];
261 //pStr[nNewLen++] = sStr[j];
262 }
263 }
264 if( bSpace == true )
265 {
266 nNewLen--;
267// pStr[nNewLen] = '\0';
268 }
269
270 return pSStr;
271}
272
273const char *Http::getRequestURI()
274{
275 return sReqURI.c_str();
276}
277
278short Http::getRequestType( const char *sType )
279{
280 if( !strncmp( sType, "OPTIONS", 7 ) )
281 {
282 return reqOptions;
283 }
284 else if( !strncmp( sType, "GET", 3 ) )
285 {
286 return reqGet;
287 }
288 else if( !strncmp( sType, "HEAD", 4 ) )
289 {
290 return reqHead;
291 }
292 else if( !strncmp( sType, "POST", 4 ) )
293 {
294 return reqPost;
295 }
296 else if( !strncmp( sType, "PUT", 3 ) )
297 {
298 return reqPut;
299 }
300 else if( !strncmp( sType, "DELETE", 6 ) )
301 {
302 return reqDelete;
303 }
304 else if( !strncmp( sType, "TRACE", 5 ) )
305 {
306 return reqTrace;
307 }
308 else if( !strncmp( sType, "CONNECT", 7 ) )
309 {
310 return reqConnect;
311 }
312 else
313 {
314 printf(" Uh oh, extension!\n");
315 return reqExtension;
316 }
317}
318
319const char *Http::getRequestType( short nType )
320{
321 switch( nType )
322 {
323 case reqOptions: return "OPTIONS";
324 case reqGet: return "GET";
325 case reqHead: return "HEAD";
326 case reqPost: return "POST";
327 case reqPut: return "PUT";
328 case reqDelete: return "DELETE";
329 case reqTrace: return "TRACE";
330 case reqConnect: return "CONNECT";
331 case reqExtension: return "EXTENSION";
332 default: return "INVALID VALUE";
333 }
334}
335
336short Http::getRequestType()
337{
338 return nReqType;
339}
340
341const char *Http::getRequestTypeStr()
342{
343 return getRequestType( nReqType );
344}
345
346void Http::setResponseStatus( short nStatus )
347{
348 nResStatus = nStatus;
349}
350
351void Http::setRequestVersion( unsigned char nMajor, unsigned char nMinor )
352{
353 cReqVersion = (nMajor<<4)|nMinor;
354}
355
356unsigned char Http::getRequestMinorVer()
357{
358 return cReqVersion&0x0F;
359}
360
361unsigned char Http::getRequestMajorVer()
362{
363 return cReqVersion>>4;
364}
365
366bool Http::checkRequestVer()
367{
368 if( cReqVersion == HTTP11 )
369 return true;
370 return false;
371}
372
373const char *Http::getHeader( const char *lpStr )
374{
375 return (const char *)hReqHeader[lpStr];
376}
377