Annotation of parser3/src/targets/cgi/parser3.C, revision 1.26.2.1
1.1 paf 1: /*
2: Parser
3: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
4: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
5:
1.26.2.1! paf 6: $Id: parser3.C,v 1.26 2001/03/19 21:39:35 paf Exp $
1.1 paf 7: */
8:
1.5 paf 9: #ifdef HAVE_CONFIG_H
10: # include "pa_config.h"
11: #endif
12:
1.3 paf 13:
14: #ifdef WIN32
15: # include <windows.h>
16: # include <io.h>
17: #endif
18: #include <stdlib.h>
1.4 paf 19: #include <stdio.h>
20: #include <string.h>
21: #include <fcntl.h>
1.3 paf 22:
1.24 paf 23: #include "pa_common.h"
1.5 paf 24: #include "pa_globals.h"
1.2 paf 25: #include "pa_request.h"
1.1 paf 26:
1.5 paf 27: Pool pool; // global pool
1.20 paf 28: bool cgi;
1.5 paf 29:
1.3 paf 30: #ifdef WIN32
1.14 paf 31: # if _MSC_VER
1.5 paf 32: // intercept global system errors
33: LONG WINAPI TopLevelExceptionFilter (
34: struct _EXCEPTION_POINTERS *ExceptionInfo
35: ) {
36: char buf[MAX_STRING];
37: if(ExceptionInfo && ExceptionInfo->ExceptionRecord) {
38: struct _EXCEPTION_RECORD *r=ExceptionInfo->ExceptionRecord;
39:
40: int printed=0;
41: printed+=snprintf(buf+printed, MAX_STRING-printed, "Exception 0x%X at 0x%p",
42: r->ExceptionCode,
43: r->ExceptionAddress);
44: for(unsigned int i=0; i<r->NumberParameters; i++)
45: printed+=snprintf(buf+printed, MAX_STRING-printed, ", 0x%X",
46: r->ExceptionInformation[i]);
47: } else
48: strcpy(buf, "Exception <unknown>");
49:
50: PTHROW(0, 0,
51: 0,
52: buf);
53:
54: return EXCEPTION_EXECUTE_HANDLER; // never reached
55: }
1.8 paf 56: # endif
1.26 paf 57:
58: void fix_slashes(char *s) {
59: for(; *s; s++)
60: if(*s=='\\')
61: *s='/';
62: }
1.3 paf 63: #endif
64:
1.19 paf 65: // service funcs
66:
1.12 paf 67: int read_post(char *buf, int max_bytes) {
68: int read_size=0;
69: do {
70: int chunk_size=read
71: (fileno(stdin), buf+read_size, min(0x400*0x400, max_bytes-read_size));
72: if(chunk_size<0)
73: break;
74: read_size+=chunk_size;
75: } while(read_size<max_bytes);
76:
77: return read_size;
1.10 paf 78: }
79:
1.19 paf 80: void output_header_attribute(const char *key, const char *value) {
1.20 paf 81: if(cgi)
82: printf("%s: %s\n", key, value);
1.19 paf 83: }
84:
85: void output_body(const char *buf, size_t size) {
1.20 paf 86: if(cgi) // header | body delimiter
87: puts("");
88:
1.19 paf 89: stdout_write(buf, size);
1.17 paf 90: }
91:
1.19 paf 92: // main
93:
1.5 paf 94: int main(int argc, char *argv[]) {
1.23 paf 95: // TODO:umask(2);
1.12 paf 96: #ifdef WIN32
97: _setmode(fileno(stdin), _O_BINARY);
98: _setmode(fileno(stdout), _O_BINARY);
99: _setmode(fileno(stderr), _O_BINARY);
100: #endif
101:
1.10 paf 102: // Service funcs
103: service_funcs.read_post=read_post;
1.19 paf 104: service_funcs.output_header_attribute=output_header_attribute;
105: service_funcs.output_body=output_body;
1.10 paf 106:
1.3 paf 107: // were we started as CGI?
1.20 paf 108: cgi=
1.2 paf 109: getenv("SERVER_SOFTWARE") ||
110: getenv("SERVER_NAME") ||
111: getenv("GATEWAY_INTERFACE") ||
112: getenv("REQUEST_METHOD");
1.5 paf 113:
1.10 paf 114: if(!cgi) {
115: if(argc<2) {
116: char *binary=argv[0];
1.13 paf 117: printf("Usage: %s <file>\n", binary?binary:"parser3");
1.10 paf 118: exit(1);
119: }
120: }
121:
1.26 paf 122: char *filespec_to_process=cgi?getenv("PATH_TRANSLATED"):argv[1];
123: #ifdef WIN32
124: fix_slashes(filespec_to_process);
125: #endif
1.10 paf 126:
1.5 paf 127: PTRY { // global try
128: // must be first in PTRY{}PCATCH
129: #ifdef WIN32
1.14 paf 130: # if _MSC_VER
1.5 paf 131: SetUnhandledExceptionFilter(&TopLevelExceptionFilter);
132: //TODO: initSocks();
1.8 paf 133: # endif
1.5 paf 134: #endif
1.2 paf 135:
1.10 paf 136: // init global variables
1.9 paf 137: globals_init(pool);
1.10 paf 138:
1.13 paf 139: if(!filespec_to_process)
140: PTHROW(0, 0,
141: 0,
142: "no file to process");
143:
1.10 paf 144: // Request info
145: Request::Info request_info;
1.13 paf 146: const char *document_root=getenv("DOCUMENT_ROOT");
147: if(!document_root) {
148: static char fake_document_root[MAX_STRING];
149: strncpy(fake_document_root, filespec_to_process, MAX_STRING);
150: rsplit(fake_document_root, '/'); rsplit(fake_document_root, '\\');// strip filename
151: document_root=fake_document_root;
152: }
153: request_info.document_root=document_root;
1.10 paf 154: request_info.path_translated=filespec_to_process;
1.15 paf 155: request_info.method=getenv("REQUEST_METHOD");
1.10 paf 156: request_info.query_string=getenv("QUERY_STRING");
1.15 paf 157: request_info.uri=getenv("REQUEST_URI");
1.10 paf 158: request_info.content_type=getenv("CONTENT_TYPE");
159: const char *content_length=getenv("CONTENT_LENGTH");
160: request_info.content_length=(content_length?atoi(content_length):0);
1.21 paf 161: request_info.cookie=getenv("HTTP_COOKIE");
1.10 paf 162:
1.5 paf 163: // prepare to process request
1.6 paf 164: Request request(Pool(),
1.10 paf 165: request_info,
1.26.2.1! paf 166: cgi ? String::UL_HTML_TYPO : String::UL_NO
1.5 paf 167: );
168:
169: // some root-controlled location
170: char *sys_auto_path1;
1.3 paf 171: #ifdef WIN32
1.10 paf 172: // c:\windows
1.5 paf 173: sys_auto_path1=(char *)pool.malloc(MAX_STRING);
1.7 paf 174: GetWindowsDirectory(sys_auto_path1, MAX_STRING);
1.10 paf 175: strcat(sys_auto_path1, PATH_DELIMITER_STRING);
1.3 paf 176: #else
1.10 paf 177: // ~nobody
1.5 paf 178: sys_auto_path1=getenv("HOME");
179: #endif
180:
181: // beside by binary
182: char *sys_auto_path2=(char *)pool.malloc(MAX_STRING);
1.6 paf 183: strncpy(sys_auto_path2, argv[0], MAX_STRING); // filespec of my binary
1.13 paf 184: rsplit(sys_auto_path2, '/'); rsplit(sys_auto_path2, '\\');// strip filename
185: strcat(sys_auto_path2, PATH_DELIMITER_STRING);
1.5 paf 186:
187: // process the request
1.16 paf 188: request.core(pool.exception(),
1.5 paf 189: sys_auto_path1,
190: sys_auto_path2);
1.19 paf 191: // no actions with request' data past this point
192: // request.exception not not handled here, but all
193: // request' data are associated with it's pool=exception
1.16 paf 194:
1.22 paf 195: // must be last in PTRY{}PCATCH
1.5 paf 196: #ifdef WIN32
1.14 paf 197: # if _MSC_VER
1.5 paf 198: SetUnhandledExceptionFilter(0);
1.8 paf 199: # endif
1.25 paf 200: #endif
1.16 paf 201: // successful finish
202: return 0;
203: } PCATCH(e) { // global problem
1.19 paf 204: const char *body=e.comment();
205: int content_length=strlen(body);
1.5 paf 206:
1.19 paf 207: // header
208: (*service_funcs.output_header_attribute)("content-type", "text/plain");
209: char content_length_cstr[MAX_NUMBER];
210: snprintf(content_length_cstr, MAX_NUMBER, "%d", content_length);
211: (*service_funcs.output_header_attribute)("content-length",
212: content_length_cstr);
213:
214: // body
215: (*service_funcs.output_body)(body, content_length);
1.2 paf 216:
1.16 paf 217: // unsuccessful finish
218: return 1;
219: }
220: PEND_CATCH
1.1 paf 221: }
E-mail: