From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_http_server_8cpp_source.html | 1120 ++++++++++++++++++++++++ 1 file changed, 1120 insertions(+) create mode 100644 Doc/doxygen/html/_http_server_8cpp_source.html (limited to 'Doc/doxygen/html/_http_server_8cpp_source.html') diff --git a/Doc/doxygen/html/_http_server_8cpp_source.html b/Doc/doxygen/html/_http_server_8cpp_source.html new file mode 100644 index 0000000..9e04ad4 --- /dev/null +++ b/Doc/doxygen/html/_http_server_8cpp_source.html @@ -0,0 +1,1120 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/NetEx/HttpServer.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
HttpServer.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: NetEx.lib
+
6  FILE: HttpServer.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Network Server Pump for HTTP Server
+
13 */
+
14 
+
15 
+
16 #include "MemDebug.h"
+
17 #include "HttpServer.h"
+
18 #include "NetLayer.h"
+
19 
+
20 #include <stdlib.h>
+
21 #include <stdio.h>
+
22 #include <ctype.h>
+
23 
+
24 // +-------------------------------------------------------------------+
+
25 
+
26 HttpServer::HttpServer(WORD port, int poolsize)
+
27  : NetServer(port, poolsize)
+
28 {
+
29  http_server_name = "Generic HttpServer 1.0";
+
30 }
+
31 
+ +
33 { }
+
34 
+
35 // +--------------------------------------------------------------------+
+
36 
+
37 Text
+ +
39 {
+
40  HttpRequest request(msg);
+
41  HttpResponse response;
+
42 
+
43  request.SetClientAddr(addr);
+
44 
+
45  switch (request.Method()) {
+ +
47  if (DoGet(request, response))
+
48  return response;
+
49 
+ +
51  if (DoPost(request, response))
+
52  return response;
+
53 
+ +
55  if (DoHead(request, response))
+
56  return response;
+
57  }
+
58 
+
59  return ErrorResponse();
+
60 }
+
61 
+
62 // +--------------------------------------------------------------------+
+
63 
+
64 Text
+ +
66 {
+
67  return http_server_name;
+
68 }
+
69 
+
70 void
+
71 HttpServer::SetServerName(const char* name)
+
72 {
+
73  http_server_name = name;
+
74 }
+
75 
+
76 // +--------------------------------------------------------------------+
+
77 
+
78 Text
+ +
80 {
+
81  Text response = "HTTP/1.1 200 OK\nServer: ";
+
82  response += http_server_name;
+
83  response += "\nMIME-Version: 1.0\nContent-Type: text/html\nConnection: close\n\n";
+
84 
+
85  return response;
+
86 }
+
87 
+
88 Text
+ +
90 {
+
91  Text response = "HTTP/1.1 500 Internal Server Error\nServer:";
+
92  response += http_server_name;
+
93  response += "\nMIME-Version: 1.0\nContent-Type: text/html\nConnection: close\n\n";
+
94 
+
95  response += "<html><head><title>";
+
96  response += http_server_name;
+
97  response += " Error</title></head>\n";
+
98  response += "<body bgcolor=\"black\" text=\"white\">\n<h1>";
+
99  response += http_server_name;
+
100  response += "</h1>\n<p>Veruca... sweetheart... angel... I'm not a magician!\n";
+
101  response += "</body></html>\n\n";
+
102 
+
103  return response;
+
104 }
+
105 
+
106 // +--------------------------------------------------------------------+
+
107 
+
108 bool
+ +
110 {
+
111  char buffer[1024];
+
112  Text content;
+
113 
+
114  content = "<html><head><title>";
+
115  content += http_server_name;
+
116  content += "</title></head>\n";
+
117  content += "<body bgcolor=\"white\" text=\"black\">\n<h1>";
+
118  content += http_server_name;
+
119  content += "</h1>\n";
+
120  content += "<br><h3>Client Address:</h3><p>\n";
+
121 
+
122  sprintf_s(buffer, "%d.%d.%d.%d:%d<br><br>\n",
+
123  client_addr.B1(),
+
124  client_addr.B2(),
+
125  client_addr.B3(),
+
126  client_addr.B4(),
+
127  client_addr.Port());
+
128 
+
129  content += buffer;
+
130  content += "<h3>Request Method:</h3><p>\n";
+
131 
+
132  switch (request.Method()) {
+ +
134  content += "GET";
+
135  break;
+
136 
+ +
138  content += "POST";
+
139  break;
+
140 
+ +
142  content += "HEAD";
+
143  break;
+
144 
+
145  default:
+
146  content += "(unsupported?)";
+
147  break;
+
148  }
+
149 
+
150  content += "<br>\n";
+
151  content += "<br><h3>URI Requested:</h3><p>\n";
+
152  content += request.URI();
+
153  content += "<br>\n";
+
154 
+
155  if (request.GetQuery().size() > 0) {
+
156  content += "<br><h3>Query Parameters:</h3>\n";
+
157 
+
158  ListIter<HttpParam> q_iter = request.GetQuery();
+
159  while (++q_iter) {
+
160  HttpParam* q = q_iter.value();
+
161  sprintf_s(buffer, "<b>%s:</b> <i>%s</i><br>\n", q->name.data(), q->value.data());
+
162  content += buffer;
+
163  }
+
164  }
+
165 
+
166  content += "<br><h3>Request Headers:</h3>\n";
+
167  ListIter<HttpParam> h_iter = request.GetHeaders();
+
168  while (++h_iter) {
+
169  HttpParam* h = h_iter.value();
+
170  sprintf_s(buffer, "<b>%s:</b> <i>%s</i><br>\n", h->name.data(), h->value.data());
+
171  content += buffer;
+
172  }
+
173 
+
174  content += "</body></html>\n\n";
+
175 
+
176  response.SetStatus(HttpResponse::SC_OK);
+
177  response.AddHeader("Server", http_server_name);
+
178  response.AddHeader("MIME-Version", "1.0");
+
179  response.AddHeader("Content-Type", "text/html");
+
180  response.SetContent(content);
+
181 
+
182  return true;
+
183 }
+
184 
+
185 // +--------------------------------------------------------------------+
+
186 
+
187 bool
+ +
189 {
+
190  return DoGet(request, response);
+
191 }
+
192 
+
193 // +--------------------------------------------------------------------+
+
194 
+
195 bool
+ +
197 {
+
198  if (DoGet(request, response)) {
+
199  int len = response.Content().length();
+
200 
+
201  char buffer[256];
+
202  sprintf_s(buffer, "%d", len);
+
203  response.SetHeader("Content-Length", buffer);
+
204  response.SetContent("");
+
205 
+
206  return true;
+
207  }
+
208 
+
209  return false;
+
210 }
+
211 
+
212 // +--------------------------------------------------------------------+
+
213 // +--------------------------------------------------------------------+
+
214 // +--------------------------------------------------------------------+
+
215 
+ +
217  : method(0)
+
218 {
+
219  if (r && *r)
+
220  ParseRequest(r);
+
221 }
+
222 
+ +
224 {
+
225  query.destroy();
+
226  headers.destroy();
+
227  cookies.destroy();
+
228 }
+
229 
+
230 // +--------------------------------------------------------------------+
+
231 
+
232 void
+ +
234 {
+
235  if (request.length() <= 8)
+
236  return;
+
237 
+
238  const char* pReq = 0;
+
239  const char* pURI = 0;
+
240  const char* pQuery = 0;
+
241 
+
242  switch (request[0]) {
+
243  case 'G':
+
244  if (request.indexOf("GET") == 0)
+
245  method = HTTP_GET;
+
246  break;
+
247 
+
248  case 'P':
+
249  if (request.indexOf("POST") == 0)
+
250  method = HTTP_POST;
+
251  break;
+
252 
+
253  case 'H':
+
254  if (request.indexOf("HEAD") == 0)
+
255  method = HTTP_HEAD;
+
256  break;
+
257 
+
258  default:
+
259  break;
+
260  }
+
261 
+
262  if (!method) return;
+
263 
+
264  char buffer[1024];
+
265  int i = 0;
+
266 
+
267  // save the request line:
+
268  pReq = request.data();
+
269  while (*pReq && *pReq != '\n')
+
270  buffer[i++] = *pReq++;
+
271  buffer[i] = 0;
+
272 
+
273  request_line = buffer;
+
274  i = 0;
+
275 
+
276  // find the URI:
+
277  pURI = request.data();
+
278  while (*pURI && !isspace(*pURI))
+
279  pURI++;
+
280 
+
281  while (*pURI && isspace(*pURI))
+
282  pURI++;
+
283 
+
284  // copy the URI and find the query string:
+
285  while (*pURI && *pURI != '?' && !isspace(*pURI)) {
+
286  buffer[i++] = *pURI++;
+
287  }
+
288 
+
289  buffer[i] = 0;
+
290  uri = buffer;
+
291  pQuery = pURI;
+
292 
+
293  // parse the query string:
+
294  if (*pQuery == '?') {
+
295  pQuery++;
+
296 
+
297  while (*pQuery && !isspace(*pQuery)) {
+
298  char name_buf[1024];
+
299  char value_buf[1024];
+
300 
+
301  i = 0;
+
302  while (*pQuery && *pQuery != '=' && !isspace(*pQuery))
+
303  name_buf[i++] = *pQuery++;
+
304  name_buf[i] = 0;
+
305 
+
306  if (*pQuery == '=')
+
307  pQuery++;
+
308 
+
309  i = 0;
+
310  while (*pQuery && *pQuery != '&' && !isspace(*pQuery))
+
311  value_buf[i++] = *pQuery++;
+
312  value_buf[i] = 0;
+
313 
+
314  if (*pQuery == '&')
+
315  pQuery++;
+
316 
+
317  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name_buf, DecodeParam(value_buf));
+
318  if (param)
+
319  query.append(param);
+
320  }
+
321  }
+
322 
+
323  // get the headers:
+
324  const char* p = request.data();
+
325  while (*p && *p != '\n')
+
326  p++;
+
327 
+
328  if (*p == '\n') p++;
+
329 
+
330  while (*p && *p != '\r' && *p != '\n') {
+
331  char name_buf[1024];
+
332  char value_buf[1024];
+
333 
+
334  i = 0;
+
335  while (*p && *p != ':')
+
336  name_buf[i++] = *p++;
+
337  name_buf[i] = 0;
+
338 
+
339  p++; // skip ':'
+
340  while (isspace(*p)) p++; // skip spaces
+
341 
+
342  i = 0;
+
343  while (*p && *p != '\r' && *p != '\n') // read to end of header line
+
344  value_buf[i++] = *p++;
+
345  value_buf[i] = 0;
+
346 
+
347  if (!_stricmp(name_buf, "Cookie")) {
+
348  ParseCookie(value_buf);
+
349  }
+
350  else {
+
351  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name_buf, value_buf);
+
352  if (param)
+
353  headers.append(param);
+
354  }
+
355 
+
356  while (*p && *p != '\n')
+
357  p++;
+
358 
+
359  if (*p == '\n') p++;
+
360  }
+
361 
+
362  if (method == HTTP_POST && *p) {
+
363  while (*p == '\n' || *p == '\r')
+
364  p++;
+
365 
+
366  content = *p;
+
367  pQuery = p;
+
368 
+
369  while (*pQuery && !isspace(*pQuery)) {
+
370  char name_buf[1024];
+
371  char value_buf[1024];
+
372 
+
373  i = 0;
+
374  while (*pQuery && *pQuery != '=' && !isspace(*pQuery))
+
375  name_buf[i++] = *pQuery++;
+
376  name_buf[i] = 0;
+
377 
+
378  if (*pQuery == '=')
+
379  pQuery++;
+
380 
+
381  i = 0;
+
382  while (*pQuery && *pQuery != '&' && !isspace(*pQuery))
+
383  value_buf[i++] = *pQuery++;
+
384  value_buf[i] = 0;
+
385 
+
386  if (*pQuery == '&')
+
387  pQuery++;
+
388 
+
389  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name_buf, DecodeParam(value_buf));
+
390  if (param)
+
391  query.append(param);
+
392  }
+
393  }
+
394 }
+
395 
+
396 void
+
397 HttpRequest::ParseCookie(const char* param)
+
398 {
+
399  const char* p = param;
+
400 
+
401  while (p && *p) {
+
402  while (isspace(*p)) p++;
+
403 
+
404  // just ignore reserved attributes
+
405  if (*p == '$') {
+
406  while (*p && !isspace(*p) && *p != ';') p++;
+
407 
+
408  if (*p == ';')
+
409  p++;
+
410  }
+
411 
+
412  // found a cookie!
+
413  else if (isalpha(*p)) {
+
414  char name[1024];
+
415  char data[1024];
+
416 
+
417  char* d = name;
+
418  while (*p && *p != '=')
+
419  *d++ = *p++;
+
420  *d = 0;
+
421 
+
422  if (*p == '=')
+
423  p++;
+
424 
+
425  if (*p == '"')
+
426  p++;
+
427 
+
428  d = data;
+
429  while (*p && *p != '"' && *p != ';')
+
430  *d++ = *p++;
+
431  *d = 0;
+
432 
+
433  if (*p == '"')
+
434  p++;
+
435 
+
436  if (*p == ';')
+
437  p++;
+
438 
+
439  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, data);
+
440  if (param)
+
441  cookies.append(param);
+
442  }
+
443 
+
444  // this shouldn't happen - abandon the parse
+
445  else {
+
446  return;
+
447  }
+
448  }
+
449 }
+
450 
+
451 // +--------------------------------------------------------------------+
+
452 
+
453 Text
+
454 HttpRequest::GetParam(const char* name)
+
455 {
+
456  ListIter<HttpParam> iter = query;
+
457  while (++iter) {
+
458  HttpParam* p = iter.value();
+
459 
+
460  if (p->name == name)
+
461  return p->value;
+
462  }
+
463 
+
464  return Text();
+
465 }
+
466 
+
467 // +--------------------------------------------------------------------+
+
468 
+
469 Text
+
470 HttpRequest::GetHeader(const char* name)
+
471 {
+
472  ListIter<HttpParam> iter = headers;
+
473  while (++iter) {
+
474  HttpParam* p = iter.value();
+
475 
+
476  if (p->name == name)
+
477  return p->value;
+
478  }
+
479 
+
480  return Text();
+
481 }
+
482 
+
483 void
+
484 HttpRequest::SetHeader(const char* name, const char* value)
+
485 {
+
486  ListIter<HttpParam> iter = headers;
+
487  while (++iter) {
+
488  HttpParam* p = iter.value();
+
489 
+
490  if (p->name == name) {
+
491  p->value = value;
+
492  return;
+
493  }
+
494  }
+
495 
+
496  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, value);
+
497  if (param)
+
498  headers.append(param);
+
499 }
+
500 
+
501 void
+
502 HttpRequest::AddHeader(const char* name, const char* value)
+
503 {
+
504  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, value);
+
505  if (param)
+
506  headers.append(param);
+
507 }
+
508 
+
509 // +--------------------------------------------------------------------+
+
510 
+
511 Text
+
512 HttpRequest::GetCookie(const char* name)
+
513 {
+
514  ListIter<HttpParam> iter = cookies;
+
515  while (++iter) {
+
516  HttpParam* p = iter.value();
+
517 
+
518  if (p->name == name)
+
519  return p->value;
+
520  }
+
521 
+
522  return Text();
+
523 }
+
524 
+
525 void
+
526 HttpRequest::SetCookie(const char* name, const char* value)
+
527 {
+
528  ListIter<HttpParam> iter = cookies;
+
529  while (++iter) {
+
530  HttpParam* p = iter.value();
+
531 
+
532  if (p->name == name) {
+
533  p->value = value;
+
534  return;
+
535  }
+
536  }
+
537 
+
538  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, value);
+
539  if (param)
+
540  cookies.append(param);
+
541 }
+
542 
+
543 void
+
544 HttpRequest::AddCookie(const char* name, const char* value)
+
545 {
+
546  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, value);
+
547  if (param)
+
548  cookies.append(param);
+
549 }
+
550 
+
551 // +--------------------------------------------------------------------+
+
552 
+
553 Text
+
554 HttpRequest::DecodeParam(const char* value)
+
555 {
+
556  if (!value || !*value) return "";
+
557 
+
558  int size = strlen(value);
+
559  char val = 0;
+
560  char code[4];
+
561  char sbuf[256];
+
562  char* lbuf = 0;
+
563 
+
564  char* dst = sbuf;
+
565  char* p = sbuf;
+
566 
+
567  if (size > 255) {
+
568  lbuf = new(__FILE__,__LINE__) char[size+1];
+
569  dst = lbuf;
+
570  p = lbuf;
+
571  }
+
572 
+
573  if (p) {
+
574  while (*value) {
+
575  switch (*value) {
+
576  default: *p++ = *value; break;
+
577  case '+': *p++ = ' '; break;
+
578 
+
579  case '%':
+
580  value++;
+
581  code[0] = *value++;
+
582  code[1] = *value;
+
583  code[2] = 0;
+
584 
+
585  val = (char) strtol(code, 0, 16);
+
586  *p++ = val;
+
587  break;
+
588  }
+
589 
+
590  value++;
+
591  }
+
592 
+
593  *p = 0;
+
594  }
+
595 
+
596  Text result = dst;
+
597 
+
598  if (lbuf)
+
599  delete [] lbuf;
+
600 
+
601  return result;
+
602 }
+
603 
+
604 // +--------------------------------------------------------------------+
+
605 
+
606 Text
+
607 HttpRequest::EncodeParam(const char* value)
+
608 {
+
609  if (!value || !*value) return "";
+
610 
+
611  int size = strlen(value);
+
612  char hex1 = 0;
+
613  char hex2 = 0;
+
614 
+
615  char sbuf[1024];
+
616  char* lbuf = 0;
+
617 
+
618  char* dst = sbuf;
+
619  char* p = sbuf;
+
620 
+
621  if (size > 255) {
+
622  lbuf = new(__FILE__,__LINE__) char[4*size+1];
+
623  dst = lbuf;
+
624  p = lbuf;
+
625  }
+
626 
+
627  if (p) {
+
628  while (*value) {
+
629  switch (*value) {
+
630  default: *p++ = *value; break;
+
631  case ' ': *p++ = '+'; break;
+
632 
+
633  case '?': *p++ = '%'; *p++ = '3'; *p++ = 'F'; break;
+
634  case '&': *p++ = '%'; *p++ = '2'; *p++ = '6'; break;
+
635  case ':': *p++ = '%'; *p++ = '3'; *p++ = 'A'; break;
+
636  case '/': *p++ = '%'; *p++ = '2'; *p++ = 'F'; break;
+
637  case '\\': *p++ = '%'; *p++ = '5'; *p++ = 'C'; break;
+
638  case '%': *p++ = '%'; *p++ = '2'; *p++ = '5'; break;
+
639  case '|': *p++ = '%'; *p++ = '7'; *p++ = 'C'; break;
+
640  case '<': *p++ = '%'; *p++ = '3'; *p++ = 'C'; break;
+
641  case '>': *p++ = '%'; *p++ = '3'; *p++ = 'E'; break;
+
642  case '[': *p++ = '%'; *p++ = '5'; *p++ = 'B'; break;
+
643  case ']': *p++ = '%'; *p++ = '5'; *p++ = 'D'; break;
+
644  case '{': *p++ = '%'; *p++ = '7'; *p++ = 'B'; break;
+
645  case '}': *p++ = '%'; *p++ = '7'; *p++ = 'D'; break;
+
646  case '"': *p++ = '%'; *p++ = '2'; *p++ = '2'; break;
+
647  case '^': *p++ = '%'; *p++ = '5'; *p++ = 'E'; break;
+
648  case '`': *p++ = '%'; *p++ = '6'; *p++ = '0'; break;
+
649  case '\n': break;
+
650  case '\r': break;
+
651  case '\t': break;
+
652  }
+
653 
+
654  value++;
+
655  }
+
656 
+
657  *p = 0;
+
658  }
+
659 
+
660  Text result = dst;
+
661 
+
662  if (lbuf)
+
663  delete [] lbuf;
+
664 
+
665  return result;
+
666 }
+
667 
+
668 // +--------------------------------------------------------------------+
+
669 
+
670 HttpRequest::operator Text()
+
671 {
+
672  Text response = request_line.data();
+
673  response += "\n";
+
674 
+
675  for (int i = 0; i < headers.size(); i++) {
+
676  HttpParam* h = headers[i];
+
677  response += h->name;
+
678  response += ": ";
+
679  response += h->value;
+
680  response += "\n";
+
681  }
+
682 
+
683  for (int i = 0; i < cookies.size(); i++) {
+
684  HttpParam* c = cookies[i];
+
685  response += "Cookie: ";
+
686  response += c->name;
+
687  response += "=\"";
+
688  response += c->value;
+
689  response += "\"\n";
+
690  }
+
691 
+
692  response += "Connection: close\n\n";
+
693  response += content;
+
694 
+
695  return response;
+
696 }
+
697 
+
698 // +--------------------------------------------------------------------+
+
699 // +--------------------------------------------------------------------+
+
700 // +--------------------------------------------------------------------+
+
701 
+
702 HttpResponse::HttpResponse(int stat, const char* data)
+
703  : status(stat), content(data)
+
704 { }
+
705 
+ +
707  : status(0), content(r)
+
708 {
+
709  if (r && *r)
+
710  ParseResponse(r);
+
711 }
+
712 
+ +
714 {
+
715  headers.destroy();
+
716  cookies.destroy();
+
717 }
+
718 
+
719 // +--------------------------------------------------------------------+
+
720 
+
721 HttpResponse::operator Text()
+
722 {
+
723  Text response;
+
724 
+
725  switch (status) {
+
726  case SC_CONTINUE : response = "HTTP/1.1 100 Continue\n"; break;
+
727  case SC_SWITCHING_PROTOCOLS : response = "HTTP/1.1 101 Switching Protocols\n"; break;
+
728 
+
729  case SC_OK : response = "HTTP/1.1 200 OK\n"; break;
+
730  case SC_CREATED : response = "HTTP/1.1 201 Created\n"; break;
+
731  case SC_ACCEPTED : response = "HTTP/1.1 202 Accepted\n"; break;
+
732  case SC_NON_AUTHORITATIVE : response = "HTTP/1.1 203 Non Authoritative\n"; break;
+
733  case SC_NO_CONTENT : response = "HTTP/1.1 204 No Content\n"; break;
+
734  case SC_RESET_CONTENT : response = "HTTP/1.1 205 Reset Content\n"; break;
+
735  case SC_PARTIAL_CONTENT : response = "HTTP/1.1 206 Partial Content\n"; break;
+
736 
+
737  case SC_MULTIPLE_CHOICES : response = "HTTP/1.1 300 Multiple Choices\n"; break;
+
738  case SC_MOVED_PERMANENTLY : response = "HTTP/1.1 301 Moved Permanently\n"; break;
+
739  case SC_FOUND : response = "HTTP/1.1 302 Found\n"; break;
+
740  case SC_SEE_OTHER : response = "HTTP/1.1 303 See Other\n"; break;
+
741  case SC_NOT_MODIFIED : response = "HTTP/1.1 304 Not Modified\n"; break;
+
742  case SC_USE_PROXY : response = "HTTP/1.1 305 Use Proxy\n"; break;
+
743  case SC_TEMPORARY_REDIRECT : response = "HTTP/1.1 307 Temporary Redirect\n"; break;
+
744 
+
745  case SC_BAD_REQUEST : response = "HTTP/1.1 400 Bad Request\n"; break;
+
746  case SC_UNAUTHORIZED : response = "HTTP/1.1 401 Unauthorized\n"; break;
+
747  case SC_PAYMENT_REQUIRED : response = "HTTP/1.1 402 Payment Required\n"; break;
+
748  case SC_FORBIDDEN : response = "HTTP/1.1 403 Forbidden\n"; break;
+
749  case SC_NOT_FOUND : response = "HTTP/1.1 404 Not Found\n"; break;
+
750  case SC_METHOD_NOT_ALLOWED : response = "HTTP/1.1 405 Method Not Allowed\n"; break;
+
751  case SC_NOT_ACCEPTABLE : response = "HTTP/1.1 406 Not Acceptable\n"; break;
+
752  case SC_PROXY_AUTH_REQ : response = "HTTP/1.1 407 Proxy Authorization Req\n"; break;
+
753  case SC_REQUEST_TIME_OUT : response = "HTTP/1.1 408 Request Timeout\n"; break;
+
754  case SC_CONFLICT : response = "HTTP/1.1 409 Conflict\n"; break;
+
755  case SC_GONE : response = "HTTP/1.1 410 Gone\n"; break;
+
756  case SC_LENGTH_REQUIRED : response = "HTTP/1.1 411 Length Required\n"; break;
+
757 
+
758  default:
+
759  case SC_SERVER_ERROR : response = "HTTP/1.1 500 Internal Server Error\n"; break;
+
760  case SC_NOT_IMPLEMENTED : response = "HTTP/1.1 501 Not Implemented\n"; break;
+
761  case SC_BAD_GATEWAY : response = "HTTP/1.1 502 Bad Gateway\n"; break;
+
762  case SC_SERVICE_UNAVAILABLE : response = "HTTP/1.1 503 Service Unavailable\n"; break;
+
763  case SC_GATEWAY_TIMEOUT : response = "HTTP/1.1 504 Gateway Timeout\n"; break;
+
764  case SC_VERSION_NOT_SUPPORTED: response = "HTTP/1.1 505 HTTP Version Not Supported\n"; break;
+
765  }
+
766 
+
767  SetHeader("Connection", "close");
+
768 
+
769  char buffer[256];
+
770 
+
771  if (content.length()) {
+
772  sprintf_s(buffer, "%d", content.length());
+
773  SetHeader("Content-Length", buffer);
+
774  }
+
775 
+
776  for (int i = 0; i < cookies.size(); i++) {
+
777  HttpParam* cookie = cookies.at(i);
+
778  sprintf_s(buffer, "%s=\"%s\"; Version=\"1\"", cookie->name.data(), cookie->value.data());
+
779 
+
780  AddHeader("Set-Cookie", buffer);
+
781  }
+
782 
+
783  for (int i = 0; i < headers.size(); i++) {
+
784  const HttpParam* p = headers.at(i);
+
785  sprintf_s(buffer, "%s: %s\n", p->name.data(), p->value.data());
+
786  response += buffer;
+
787  }
+
788 
+
789  response += "\n";
+
790  response += content;
+
791 
+
792  return response;
+
793 }
+
794 
+
795 // +--------------------------------------------------------------------+
+
796 
+
797 Text
+
798 HttpResponse::GetHeader(const char* name)
+
799 {
+
800  ListIter<HttpParam> iter = headers;
+
801  while (++iter) {
+
802  HttpParam* p = iter.value();
+
803 
+
804  if (p->name == name)
+
805  return p->value;
+
806  }
+
807 
+
808  return Text();
+
809 }
+
810 
+
811 void
+
812 HttpResponse::SetHeader(const char* name, const char* value)
+
813 {
+
814  ListIter<HttpParam> iter = headers;
+
815  while (++iter) {
+
816  HttpParam* p = iter.value();
+
817 
+
818  if (p->name == name) {
+
819  p->value = value;
+
820  return;
+
821  }
+
822  }
+
823 
+
824  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, value);
+
825  if (param)
+
826  headers.append(param);
+
827 }
+
828 
+
829 void
+
830 HttpResponse::AddHeader(const char* name, const char* value)
+
831 {
+
832  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, value);
+
833  if (param)
+
834  headers.append(param);
+
835 }
+
836 
+
837 // +--------------------------------------------------------------------+
+
838 
+
839 Text
+
840 HttpResponse::GetCookie(const char* name)
+
841 {
+
842  ListIter<HttpParam> iter = cookies;
+
843  while (++iter) {
+
844  HttpParam* p = iter.value();
+
845 
+
846  if (p->name == name)
+
847  return p->value;
+
848  }
+
849 
+
850  return Text();
+
851 }
+
852 
+
853 void
+
854 HttpResponse::SetCookie(const char* name, const char* value)
+
855 {
+
856  ListIter<HttpParam> iter = cookies;
+
857  while (++iter) {
+
858  HttpParam* p = iter.value();
+
859 
+
860  if (p->name == name) {
+
861  p->value = value;
+
862  return;
+
863  }
+
864  }
+
865 
+
866  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, value);
+
867  if (param)
+
868  cookies.append(param);
+
869 }
+
870 
+
871 void
+
872 HttpResponse::AddCookie(const char* name, const char* value)
+
873 {
+
874  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, value);
+
875  if (param)
+
876  cookies.append(param);
+
877 }
+
878 
+
879 // +--------------------------------------------------------------------+
+
880 
+
881 void
+ +
883 {
+
884  status = SC_TEMPORARY_REDIRECT;
+
885  SetHeader("Location", url);
+
886 }
+
887 
+
888 // +--------------------------------------------------------------------+
+
889 
+
890 void
+ +
892 {
+
893  if (response.length() <= 12 || response.indexOf("HTTP/1.") != 0)
+
894  return;
+
895 
+
896  const char* pStatus = response.data() + 9;
+
897 
+
898  sscanf_s(pStatus, "%d", &status);
+
899  if (!status) return;
+
900 
+
901  int i = 0;
+
902 
+
903  // get the headers:
+
904  const char* p = response.data();
+
905  while (*p && *p != '\n')
+
906  p++;
+
907 
+
908  if (*p == '\n') p++;
+
909 
+
910  while (*p && *p != '\r' && *p != '\n') {
+
911  char name_buf[1024];
+
912  char value_buf[1024];
+
913 
+
914  i = 0;
+
915  while (*p && *p != ':')
+
916  name_buf[i++] = *p++;
+
917  name_buf[i] = 0;
+
918 
+
919  p++; // skip ':'
+
920  while (isspace(*p)) p++; // skip spaces
+
921 
+
922  i = 0;
+
923  while (*p && *p != '\r' && *p != '\n') // read to end of header line
+
924  value_buf[i++] = *p++;
+
925  value_buf[i] = 0;
+
926 
+
927  if (!_stricmp(name_buf, "Set-Cookie")) {
+
928  ParseCookie(value_buf);
+
929  }
+
930  else {
+
931  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name_buf, value_buf);
+
932  if (param)
+
933  headers.append(param);
+
934  }
+
935 
+
936  while (*p && *p != '\n')
+
937  p++;
+
938 
+
939  if (*p == '\n') p++;
+
940  }
+
941 
+
942  if (*p == '\n') p++;
+
943  content = p;
+
944 }
+
945 
+
946 void
+
947 HttpResponse::ParseCookie(const char* param)
+
948 {
+
949  const char* p = param;
+
950 
+
951  while (p && *p) {
+
952  while (isspace(*p)) p++;
+
953 
+
954  // just ignore reserved attributes
+
955  if (*p == '$') {
+
956  while (*p && !isspace(*p) && *p != ';') p++;
+
957 
+
958  if (*p == ';')
+
959  p++;
+
960  }
+
961 
+
962  // found a cookie!
+
963  else if (isalpha(*p)) {
+
964  char name[1024];
+
965  char data[1024];
+
966 
+
967  char* d = name;
+
968  while (*p && *p != '=')
+
969  *d++ = *p++;
+
970  *d = 0;
+
971 
+
972  if (*p == '=')
+
973  p++;
+
974 
+
975  if (*p == '"')
+
976  p++;
+
977 
+
978  d = data;
+
979  while (*p && *p != '"' && *p != ';')
+
980  *d++ = *p++;
+
981  *d = 0;
+
982 
+
983  if (*p == '"')
+
984  p++;
+
985 
+
986  if (*p == ';')
+
987  p++;
+
988 
+
989  // ignore the version attribute
+
990  if (_stricmp(name, "version")) {
+
991  HttpParam* param = new(__FILE__,__LINE__) HttpParam(name, data);
+
992  if (param)
+
993  cookies.append(param);
+
994  }
+
995  }
+
996 
+
997  // this shouldn't happen - abandon the parse
+
998  else {
+
999  return;
+
1000  }
+
1001  }
+
1002 }
+
1003 
+
+
+ + + + -- cgit v1.1