Annotation of parser3/src/targets/cgi/parser3.C, revision 1.17
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.17 ! paf 6: $Id: parser3.C,v 1.16 2001/03/18 11:37:53 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.5 paf 23: #include "pa_globals.h"
1.2 paf 24: #include "pa_request.h"
25: #include "pa_common.h"
1.1 paf 26:
1.5 paf 27: Pool pool; // global pool
28:
1.3 paf 29: #ifdef WIN32
1.14 paf 30: # if _MSC_VER
1.5 paf 31: // intercept global system errors
32: LONG WINAPI TopLevelExceptionFilter (
33: struct _EXCEPTION_POINTERS *ExceptionInfo
34: ) {
35: char buf[MAX_STRING];
36: if(ExceptionInfo && ExceptionInfo->ExceptionRecord) {
37: struct _EXCEPTION_RECORD *r=ExceptionInfo->ExceptionRecord;
38:
39: int printed=0;
40: printed+=snprintf(buf+printed, MAX_STRING-printed, "Exception 0x%X at 0x%p",
41: r->ExceptionCode,
42: r->ExceptionAddress);
43: for(unsigned int i=0; i<r->NumberParameters; i++)
44: printed+=snprintf(buf+printed, MAX_STRING-printed, ", 0x%X",
45: r->ExceptionInformation[i]);
46: } else
47: strcpy(buf, "Exception <unknown>");
48:
49: PTHROW(0, 0,
50: 0,
51: buf);
52:
53: return EXCEPTION_EXECUTE_HANDLER; // never reached
54: }
1.8 paf 55: # endif
1.3 paf 56: #endif
57:
1.12 paf 58: int read_post(char *buf, int max_bytes) {
59: int read_size=0;
60: do {
61: int chunk_size=read
62: (fileno(stdin), buf+read_size, min(0x400*0x400, max_bytes-read_size));
63: if(chunk_size<0)
64: break;
65: read_size+=chunk_size;
66: } while(read_size<max_bytes);
67:
68: return read_size;
1.10 paf 69: }
70:
1.17 ! paf 71: void stdout_write_header_attribute(const Hash::Key& key, Hash::Value *value, void *info) {
! 72: String *key_to_exclude=static_cast<String *>(info);
! 73: if(key==*key_to_exclude)
! 74: return;
! 75:
! 76: printf("%s: %s\n",
! 77: key.cstr(),
! 78: static_cast<Value *>(value)->as_string().cstr());
! 79: }
! 80:
1.5 paf 81: int main(int argc, char *argv[]) {
1.12 paf 82: //TODO: umask(2);
83: #ifdef WIN32
84: _setmode(fileno(stdin), _O_BINARY);
85: _setmode(fileno(stdout), _O_BINARY);
86: _setmode(fileno(stderr), _O_BINARY);
87: #endif
88:
1.10 paf 89: // Service funcs
90: service_funcs.read_post=read_post;
91:
1.3 paf 92: // were we started as CGI?
1.2 paf 93: bool cgi=
94: getenv("SERVER_SOFTWARE") ||
95: getenv("SERVER_NAME") ||
96: getenv("GATEWAY_INTERFACE") ||
97: getenv("REQUEST_METHOD");
1.5 paf 98:
1.10 paf 99: if(!cgi) {
100: if(argc<2) {
101: char *binary=argv[0];
1.13 paf 102: printf("Usage: %s <file>\n", binary?binary:"parser3");
1.10 paf 103: exit(1);
104: }
105: }
106:
107: const char *filespec_to_process=cgi?getenv("PATH_TRANSLATED"):argv[1];
108:
1.5 paf 109: PTRY { // global try
110: // must be first in PTRY{}PCATCH
111: #ifdef WIN32
1.14 paf 112: # if _MSC_VER
1.5 paf 113: SetUnhandledExceptionFilter(&TopLevelExceptionFilter);
114: //TODO: initSocks();
1.8 paf 115: # endif
1.5 paf 116: #endif
1.2 paf 117:
1.10 paf 118: // init global variables
1.9 paf 119: globals_init(pool);
1.10 paf 120:
1.13 paf 121: if(!filespec_to_process)
122: PTHROW(0, 0,
123: 0,
124: "no file to process");
125:
1.10 paf 126: // Request info
1.5 paf 127: // TODO: ifdef WIN32 flip \\ to /
1.10 paf 128: Request::Info request_info;
1.13 paf 129: const char *document_root=getenv("DOCUMENT_ROOT");
130: if(!document_root) {
131: static char fake_document_root[MAX_STRING];
132: strncpy(fake_document_root, filespec_to_process, MAX_STRING);
133: rsplit(fake_document_root, '/'); rsplit(fake_document_root, '\\');// strip filename
134: document_root=fake_document_root;
135: }
136: request_info.document_root=document_root;
1.10 paf 137: request_info.path_translated=filespec_to_process;
1.15 paf 138: request_info.method=getenv("REQUEST_METHOD");
1.10 paf 139: request_info.query_string=getenv("QUERY_STRING");
1.15 paf 140: request_info.uri=getenv("REQUEST_URI");
1.10 paf 141: request_info.content_type=getenv("CONTENT_TYPE");
142: const char *content_length=getenv("CONTENT_LENGTH");
143: request_info.content_length=(content_length?atoi(content_length):0);
144:
1.5 paf 145: // prepare to process request
1.6 paf 146: Request request(Pool(),
1.10 paf 147: request_info,
148: cgi ? String::Untaint_lang::HTML_TYPO : String::Untaint_lang::NO
1.5 paf 149: );
150:
151: // some root-controlled location
152: char *sys_auto_path1;
1.3 paf 153: #ifdef WIN32
1.10 paf 154: // c:\windows
1.5 paf 155: sys_auto_path1=(char *)pool.malloc(MAX_STRING);
1.7 paf 156: GetWindowsDirectory(sys_auto_path1, MAX_STRING);
1.10 paf 157: strcat(sys_auto_path1, PATH_DELIMITER_STRING);
1.3 paf 158: #else
1.10 paf 159: // ~nobody
1.5 paf 160: sys_auto_path1=getenv("HOME");
161: #endif
162:
163: // beside by binary
164: char *sys_auto_path2=(char *)pool.malloc(MAX_STRING);
1.6 paf 165: strncpy(sys_auto_path2, argv[0], MAX_STRING); // filespec of my binary
1.13 paf 166: rsplit(sys_auto_path2, '/'); rsplit(sys_auto_path2, '\\');// strip filename
167: strcat(sys_auto_path2, PATH_DELIMITER_STRING);
1.5 paf 168:
169: // process the request
1.16 paf 170: request.core(pool.exception(),
1.5 paf 171: sys_auto_path1,
172: sys_auto_path2);
173:
1.16 paf 174: // extract request.response body
175: Value *body_value=static_cast<Value *>(
176: request.response.fields().get(*body_name));
177: const char *body=body_value?
178: body_value->as_string().cstr():"no body";// TODO: IMAGE&FILE
179:
180: // OK. write out the result
181: if(cgi) {
1.17 ! paf 182: // header: response fields
! 183: request.response.fields().foreach(stdout_write_header_attribute,
! 184: body_name);
! 185:
! 186: // header: content-length
1.16 paf 187: printf(
1.17 ! paf 188: "content-length: %d\n"
1.16 paf 189: "\n",
190: strlen(body));
191: }
192: // body
193: stdout_write(body);
194:
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.16 paf 200: // successful finish
201: return 0;
1.3 paf 202: #endif
1.16 paf 203: } PCATCH(e) { // global problem
204: // @globals fill
205: // @Request create
206: // @prepare to .core()
207: // @request.core when reporting request exception
208: // @write result
209: const char *error=e.comment();
1.5 paf 210:
1.16 paf 211: if(cgi) {
1.4 paf 212: printf(
213: "Content-type: text/plain\n"
214: "Content-length: %d\n"
215: "\n",
216: strlen(error));
217: stdout_write(error);
1.16 paf 218: } else
1.4 paf 219: fputs(error, stderr);
1.2 paf 220:
1.16 paf 221: // unsuccessful finish
222: return 1;
223: }
224: PEND_CATCH
1.1 paf 225: }
E-mail: