45 switch (request.
Method()) {
47 if (
DoGet(request, response))
51 if (
DoPost(request, response))
55 if (
DoHead(request, response))
81 Text response =
"HTTP/1.1 200 OK\nServer: ";
83 response +=
"\nMIME-Version: 1.0\nContent-Type: text/html\nConnection: close\n\n";
91 Text response =
"HTTP/1.1 500 Internal Server Error\nServer:";
93 response +=
"\nMIME-Version: 1.0\nContent-Type: text/html\nConnection: close\n\n";
95 response +=
"<html><head><title>";
97 response +=
" Error</title></head>\n";
98 response +=
"<body bgcolor=\"black\" text=\"white\">\n<h1>";
100 response +=
"</h1>\n<p>Veruca... sweetheart... angel... I'm not a magician!\n";
101 response +=
"</body></html>\n\n";
114 content =
"<html><head><title>";
116 content +=
"</title></head>\n";
117 content +=
"<body bgcolor=\"white\" text=\"black\">\n<h1>";
119 content +=
"</h1>\n";
120 content +=
"<br><h3>Client Address:</h3><p>\n";
122 sprintf_s(buffer,
"%d.%d.%d.%d:%d<br><br>\n",
130 content +=
"<h3>Request Method:</h3><p>\n";
132 switch (request.
Method()) {
146 content +=
"(unsupported?)";
151 content +=
"<br><h3>URI Requested:</h3><p>\n";
152 content += request.
URI();
156 content +=
"<br><h3>Query Parameters:</h3>\n";
161 sprintf_s(buffer,
"<b>%s:</b> <i>%s</i><br>\n", q->
name.
data(), q->
value.
data());
166 content +=
"<br><h3>Request Headers:</h3>\n";
170 sprintf_s(buffer,
"<b>%s:</b> <i>%s</i><br>\n", h->
name.
data(), h->
value.
data());
174 content +=
"</body></html>\n\n";
178 response.
AddHeader(
"MIME-Version",
"1.0");
179 response.
AddHeader(
"Content-Type",
"text/html");
190 return DoGet(request, response);
198 if (
DoGet(request, response)) {
202 sprintf_s(buffer,
"%d", len);
203 response.
SetHeader(
"Content-Length", buffer);
235 if (request.
length() <= 8)
238 const char* pReq = 0;
239 const char* pURI = 0;
240 const char* pQuery = 0;
242 switch (request[0]) {
244 if (request.
indexOf(
"GET") == 0)
249 if (request.
indexOf(
"POST") == 0)
254 if (request.
indexOf(
"HEAD") == 0)
268 pReq = request.
data();
269 while (*pReq && *pReq !=
'\n')
270 buffer[i++] = *pReq++;
273 request_line = buffer;
277 pURI = request.
data();
278 while (*pURI && !isspace(*pURI))
281 while (*pURI && isspace(*pURI))
285 while (*pURI && *pURI !=
'?' && !isspace(*pURI)) {
286 buffer[i++] = *pURI++;
294 if (*pQuery ==
'?') {
297 while (*pQuery && !isspace(*pQuery)) {
299 char value_buf[1024];
302 while (*pQuery && *pQuery !=
'=' && !isspace(*pQuery))
303 name_buf[i++] = *pQuery++;
310 while (*pQuery && *pQuery !=
'&' && !isspace(*pQuery))
311 value_buf[i++] = *pQuery++;
324 const char* p = request.
data();
325 while (*p && *p !=
'\n')
330 while (*p && *p !=
'\r' && *p !=
'\n') {
332 char value_buf[1024];
335 while (*p && *p !=
':')
336 name_buf[i++] = *p++;
340 while (isspace(*p)) p++;
343 while (*p && *p !=
'\r' && *p !=
'\n')
344 value_buf[i++] = *p++;
347 if (!_stricmp(name_buf,
"Cookie")) {
356 while (*p && *p !=
'\n')
363 while (*p ==
'\n' || *p ==
'\r')
369 while (*pQuery && !isspace(*pQuery)) {
371 char value_buf[1024];
374 while (*pQuery && *pQuery !=
'=' && !isspace(*pQuery))
375 name_buf[i++] = *pQuery++;
382 while (*pQuery && *pQuery !=
'&' && !isspace(*pQuery))
383 value_buf[i++] = *pQuery++;
399 const char* p = param;
402 while (isspace(*p)) p++;
406 while (*p && !isspace(*p) && *p !=
';') p++;
413 else if (isalpha(*p)) {
418 while (*p && *p !=
'=')
429 while (*p && *p !=
'"' && *p !=
';')
490 if (p->
name == name) {
532 if (p->
name == name) {
556 if (!value || !*value)
return "";
558 int size = strlen(value);
568 lbuf =
new(__FILE__,__LINE__)
char[size+1];
576 default: *p++ = *value;
break;
577 case '+': *p++ =
' ';
break;
585 val = (char) strtol(code, 0, 16);
609 if (!value || !*value)
return "";
611 int size = strlen(value);
622 lbuf =
new(__FILE__,__LINE__)
char[4*size+1];
630 default: *p++ = *value;
break;
631 case ' ': *p++ =
'+';
break;
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;
672 Text response = request_line.
data();
675 for (
int i = 0; i < headers.size(); i++) {
679 response += h->
value;
683 for (
int i = 0; i < cookies.size(); i++) {
685 response +=
"Cookie: ";
688 response += c->
value;
692 response +=
"Connection: close\n\n";
703 : status(stat), content(data)
707 : status(0), content(r)
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;
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;
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;
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;
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;
767 SetHeader(
"Connection",
"close");
771 if (content.length()) {
772 sprintf_s(buffer,
"%d", content.length());
773 SetHeader(
"Content-Length", buffer);
776 for (
int i = 0; i < cookies.size(); i++) {
778 sprintf_s(buffer,
"%s=\"%s\"; Version=\"1\"", cookie->
name.
data(), cookie->
value.
data());
780 AddHeader(
"Set-Cookie", buffer);
783 for (
int i = 0; i < headers.size(); i++) {
818 if (p->
name == name) {
860 if (p->
name == name) {
893 if (response.
length() <= 12 || response.
indexOf(
"HTTP/1.") != 0)
896 const char* pStatus = response.
data() + 9;
898 sscanf_s(pStatus,
"%d", &status);
904 const char* p = response.
data();
905 while (*p && *p !=
'\n')
910 while (*p && *p !=
'\r' && *p !=
'\n') {
912 char value_buf[1024];
915 while (*p && *p !=
':')
916 name_buf[i++] = *p++;
920 while (isspace(*p)) p++;
923 while (*p && *p !=
'\r' && *p !=
'\n')
924 value_buf[i++] = *p++;
927 if (!_stricmp(name_buf,
"Set-Cookie")) {
936 while (*p && *p !=
'\n')
949 const char* p = param;
952 while (isspace(*p)) p++;
956 while (*p && !isspace(*p) && *p !=
';') p++;
963 else if (isalpha(*p)) {
968 while (*p && *p !=
'=')
979 while (*p && *p !=
'"' && *p !=
';')
990 if (_stricmp(name,
"version")) {