Annotation of parser3/src/targets/apache/mod_parser3.c, revision 1.5
1.1 moko 1: /** @file
1.2 moko 2: Parser: apache 1.3 and 2.2 module
1.1 moko 3:
1.2 moko 4: Copyright (c) 2001-2010 ArtLebedev Group (http://www.artlebedev.com)
1.1 moko 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
6: */
7:
1.5 ! moko 8: static const char * const IDENT_MOD_PARSER3_C="$Date: 2010-11-14 22:49:57 $";
1.1 moko 9:
10: #ifdef WIN32
11: #include <winsock2.h>
12: #endif
13:
14: #include "httpd.h"
15: #include "http_config.h"
16: #include "http_core.h"
17: #include "http_log.h"
18: #include "http_main.h"
19: #include "http_protocol.h"
20: #include "util_script.h"
1.2 moko 21:
22: #include "pa_httpd.h"
23:
1.3 moko 24: #define PARSER3_HANDLER "parser3-handler"
25:
1.2 moko 26: /*
27: * To Ease Compatibility
28: */
29: #ifdef STANDARD20_MODULE_STUFF
30:
31: #include "apr_strings.h"
32:
33: #define ap_pcalloc apr_pcalloc
34: #define ap_pstrdup apr_pstrdup
35:
36: #define ap_table_get apr_table_get
37: #define ap_table_elts apr_table_elts
38: #define ap_table_addn apr_table_addn
39: #define ap_table_do apr_table_do
40:
41: #else
42:
1.1 moko 43: #include "ap_alloc.h"
44:
1.2 moko 45: #define apr_pool_t pool
46: #define apr_table_t table
47:
48: #define ap_add_version_component(p, v) ap_add_version_component(v)
49:
50: #endif /* STANDARD20_MODULE_STUFF */
1.1 moko 51:
52: /*
53: * Declare ourselves so the configuration routines can find and know us.
54: * We'll fill it in at the end of the module.
55: */
1.2 moko 56:
57: #ifdef STANDARD20_MODULE_STUFF
58: module AP_MODULE_DECLARE_DATA parser3_module;
59: #else
60: module MODULE_VAR_EXPORT parser3_module;
61: #endif
1.1 moko 62:
63: /*
64: * Locate our directory configuration record for the current request.
65: */
66: static Parser_module_config *our_dconfig(request_rec *r) {
1.5 ! moko 67: return (Parser_module_config *) ap_get_module_config(r->per_dir_config, &parser3_module);
1.1 moko 68: }
69:
70: static const char* cmd_parser_config(cmd_parms *cmd, void *mconfig, char *file_spec) {
71: Parser_module_config *cfg = (Parser_module_config *) mconfig;
72:
73: // remember assigned filespec into cfg
74: cfg->parser_config_filespec=file_spec;
75:
76: return NULL;
77: }
1.2 moko 78:
1.1 moko 79: static const char* cmd_parser_status_allowed(cmd_parms *cmd, void *mconfig, char *file_spec) {
80: Parser_module_config *cfg = (Parser_module_config *) mconfig;
81:
82: cfg->parser_status_allowed=1;
83:
84: return NULL;
85: }
86:
87: /*
1.2 moko 88: * Now let's declare routines for each of the callback phase in order.
1.1 moko 89: */
90:
1.3 moko 91: static int parser_handler(request_rec *r) {
92:
93: // ap_log_rerror(APLOG_MARK, APLOG_EMERG, 0, r, "handler, r->handler=%s", r->handler);
94:
95: #ifdef STANDARD20_MODULE_STUFF
96: if(strcmp(r->handler, PARSER3_HANDLER))
97: return DECLINED;
98: #endif
99: // converting to parser version
100: pa_request_rec pr={
101: r,
102: r->pool,
103: r->header_only,
104: &r->status,
105: r->method,
106: r->headers_out,
107: r->subprocess_env,
108: &r->content_type,
109: r->uri,
110: r->filename,
111: r->path_info,
112: r->args,
113: #ifdef STANDARD20_MODULE_STUFF
114: r->finfo.filetype == 0
115: #else
116: r->finfo.st_mode == 0
117: #endif
1.1 moko 118: };
119:
120: // config
1.3 moko 121: Parser_module_config *dcfg=our_dconfig(r);
122:
123: return pa_parser_handler(&pr, dcfg);
1.1 moko 124: }
125:
126: /*
1.4 moko 127: * This function is called during process initialisation.
1.1 moko 128: */
129:
1.3 moko 130: #ifdef STANDARD20_MODULE_STUFF
131: static void parser_module_init(apr_pool_t *p, server_rec *s) {
132: #else
1.2 moko 133: static void parser_module_init(server_rec *s, apr_pool_t *p) {
134: ap_add_version_component(p, pa_version());
1.1 moko 135: #endif
1.3 moko 136: ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, p, "parser inited %d", getpid());
1.1 moko 137: pa_setup_module_cells();
138: }
139:
140: /*
1.2 moko 141: * All our process-death routine does is add its trace to the log.
142: */
143: static void parser_module_done(server_rec *s, apr_pool_t *p) {
1.1 moko 144: pa_destroy_module_cells();
145: }
146:
147: /*
1.2 moko 148: * This function gets called to create a per-directory configuration record.
1.1 moko 149: */
1.2 moko 150: static void *parser_create_dir_config(apr_pool_t *p, char *dirspec) {
1.1 moko 151: /*
1.2 moko 152: * Allocate the space for our record from the apr_pool_t supplied.
1.1 moko 153: */
1.5 ! moko 154: Parser_module_config *cfg= (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
1.1 moko 155: return (void *) cfg;
156: }
157:
158: /*
1.2 moko 159: * This function gets called to merge two per-directory configuration records.
1.1 moko 160: *
1.2 moko 161: * 20011126 paf: noticed, that this is called even on virtual root merge with something "parent",
162: * while thought that that is part of merge_server...
1.1 moko 163: *
1.2 moko 164: */
165: static void *parser_merge_dir_config(apr_pool_t *p, void *parent_conf, void *newloc_conf) {
166: Parser_module_config *merged_config = (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
1.1 moko 167: Parser_module_config *pconf = (Parser_module_config *) parent_conf;
168: Parser_module_config *nconf = (Parser_module_config *) newloc_conf;
169:
170: merged_config->parser_config_filespec = ap_pstrdup(p, nconf->parser_config_filespec?
171: nconf->parser_config_filespec:pconf->parser_config_filespec);
1.5 ! moko 172: merged_config->parser_status_allowed= pconf->parser_status_allowed || nconf->parser_status_allowed;
1.1 moko 173:
174: return (void *) merged_config;
175: }
176:
177: /*
1.2 moko 178: * This function gets called to create a per-server configuration record.
1.1 moko 179: */
1.2 moko 180: static void *parser_create_server_config(apr_pool_t *p, server_rec *s) {
1.1 moko 181: /*
182: * As with the parser_create_dir_config() routine, we allocate and fill
183: * in an empty record.
184: */
1.5 ! moko 185: Parser_module_config *cfg= (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
1.1 moko 186:
187: return (void *) cfg;
188: }
189:
190: /*
1.2 moko 191: * This function gets called to merge two per-server configuration records.
1.1 moko 192: */
1.2 moko 193: static void *parser_merge_server_config(apr_pool_t *p, void *server1_conf, void *server2_conf)
1.1 moko 194: {
1.2 moko 195: Parser_module_config *merged_config = (Parser_module_config *) ap_pcalloc(p, sizeof(Parser_module_config));
1.1 moko 196: Parser_module_config *s1conf = (Parser_module_config *) server1_conf;
197: Parser_module_config *s2conf = (Parser_module_config *) server2_conf;
198:
199: /*
200: * Our inheritance rules are our own, and part of our module's semantics.
201: * Basically, just note whence we came.
202: */
203: merged_config->parser_config_filespec = ap_pstrdup(p, s2conf->parser_config_filespec?
204: s2conf->parser_config_filespec:s1conf->parser_config_filespec);
1.5 ! moko 205: merged_config->parser_status_allowed= s1conf->parser_status_allowed || s2conf->parser_status_allowed;
1.1 moko 206:
207: return (void *) merged_config;
208: }
209:
210: /*
211: * List of directives specific to our module.
212: */
213: static const command_rec parser_cmds[] =
214: {
215: {
1.5 ! moko 216: "ParserConfig", /* directive name */
1.1 moko 217: (const char* (*)(void))((void *)cmd_parser_config), // config action routine
1.5 ! moko 218: (void*)0, /* argument to include in call */
! 219: (int)(OR_OPTIONS), /* where available */
! 220: TAKE1, /* arguments */
! 221: "Parser config filespec" // directive description
1.1 moko 222: },
223: {
1.5 ! moko 224: "ParserStatusAllowed", /* directive name */
1.1 moko 225: (const char* (*)(void))((void *)cmd_parser_status_allowed), // config action routine
1.5 ! moko 226: (void*)0, /* argument to include in call */
! 227: (int)(ACCESS_CONF), /* where available */
! 228: NO_ARGS, /* arguments */
1.1 moko 229: "Parser status class can be used" // directive description
230: },
231: {NULL}
232: };
233:
234: /*--------------------------------------------------------------------------*/
235: /* Now the list of content handlers available from this module. */
236: /*--------------------------------------------------------------------------*/
1.2 moko 237:
238: #ifndef STANDARD20_MODULE_STUFF
1.1 moko 239: static const handler_rec parser_handlers[] =
240: {
1.3 moko 241: {PARSER3_HANDLER, parser_handler},
1.1 moko 242: {NULL}
243: };
1.2 moko 244: #endif
1.1 moko 245:
246: /*--------------------------------------------------------------------------*/
247: /* Finally, the list of callback routines and data structures that */
248: /* provide the hooks into our module from the other parts of the server. */
249: /*--------------------------------------------------------------------------*/
1.2 moko 250:
251: #ifdef STANDARD20_MODULE_STUFF
252:
1.1 moko 253: /*
1.2 moko 254: * register hooks.
1.1 moko 255: */
1.2 moko 256: static void parser_register_hooks(apr_pool_t* pool)
257: {
1.3 moko 258: // ap_add_version_component(pool, pa_version());
1.2 moko 259: // ap_hook_post_config(parser_server_init, NULL, NULL, APR_HOOK_MIDDLE);
260: ap_hook_handler(parser_handler, NULL, NULL, APR_HOOK_MIDDLE);
1.3 moko 261: ap_hook_child_init(parser_module_init, NULL, NULL, APR_HOOK_MIDDLE);
1.2 moko 262: };
263:
264: module AP_MODULE_DECLARE_DATA parser3_module =
265: {
266: STANDARD20_MODULE_STUFF,
267: #else
1.1 moko 268: module MODULE_VAR_EXPORT parser3_module =
269: {
270: STANDARD_MODULE_STUFF,
1.5 ! moko 271: parser_module_init, /* module initializer */
1.2 moko 272: #endif
1.5 ! moko 273: parser_create_dir_config, /* per-directory config creator */
! 274: parser_merge_dir_config, /* dir config merger */
! 275: parser_create_server_config, /* server config creator */
! 276: parser_merge_server_config, /* server config merger */
! 277: parser_cmds, /* command apr_table_t */
1.2 moko 278: #ifdef STANDARD20_MODULE_STUFF
1.5 ! moko 279: parser_register_hooks /* register hooks */
1.2 moko 280: #else
1.5 ! moko 281: parser_handlers, /* [9] list of handlers */
! 282: 0, /* [2] filename-to-URI translation */
! 283: 0, /* [5] check/validate user_id */
! 284: 0, /* [6] check user_id is valid *here* */
! 285: 0, /* [4] check access by host address */
! 286: 0, /* [7] MIME type checker/setter */
! 287: 0, /* [8] fixups */
! 288: 0, /* [10] logger */
! 289: 0, /* [3] header parser */
! 290: 0, /* process initializer */
! 291: parser_module_done /* process exit/cleanup */
1.2 moko 292: #endif // STANDARD20_MODULE_STUFF
1.1 moko 293: };
294:
295: #if defined(_MSC_VER)
296: # define APACHE_WIN32_SRC "../../../../win32/apache13/src"
297: # ifdef _DEBUG
298: # pragma comment(lib, APACHE_WIN32_SRC "/CoreD/ApacheCore.lib")
299: # else
300: # pragma comment(lib, APACHE_WIN32_SRC "/CoreR/ApacheCore.lib")
301: # endif
302: #endif
303:
304:
305: // interface to C++
306:
1.4 moko 307: #define PA_APLOG_EMERG 0 /* system is unusable */
308: #define PA_APLOG_ALERT 1 /* action must be taken immediately */
309: #define PA_APLOG_CRIT 2 /* critical conditions */
310: #define PA_APLOG_ERR 3 /* error conditions */
1.1 moko 311: #define PA_APLOG_WARNING 4 /* warning conditions */
1.4 moko 312: #define PA_APLOG_NOTICE 5 /* normal but significant condition */
313: #define PA_APLOG_INFO 6 /* informational */
314: #define PA_APLOG_DEBUG 7 /* debug-level messages */
1.1 moko 315:
316: #define PA_APLOG_LEVELMASK 7 /* mask off the level value */
317:
1.4 moko 318: #define PA_APLOG_NOERRNO (PA_APLOG_LEVELMASK + 1)
1.1 moko 319:
320: #define PA_APLOG_MARK __FILE__,__LINE__
321:
1.2 moko 322: void pa_ap_log_rerror(const char *file, int line, int level, const pa_request_rec *s, const char *fmt, ...) {
1.1 moko 323: const char* str;
324: va_list l;
325: va_start(l, fmt);
326: str=va_arg(l, const char*);
327: va_end(l);
328:
329: ap_log_rerror(file, line, level,
1.2 moko 330: #ifdef STANDARD20_MODULE_STUFF
331: 0,
332: #endif
1.1 moko 333: (request_rec*)s->real_request_rec, "%s", str);
334: }
335:
336:
1.2 moko 337: void pa_ap_log_error(const char *file, int line, int level, const pa_server_rec *s, const char *fmt, ...) {
1.1 moko 338: const char* str;
339: va_list l;
340: va_start(l, fmt);
341: str=va_arg(l, const char*);
342: va_end(l);
343:
344: ap_log_error(file, line, level,
1.2 moko 345: #ifdef STANDARD20_MODULE_STUFF
346: 0,
347: #endif
1.1 moko 348: (server_rec*)s, "%s", str);
349: }
350:
351: // ap_alloc.h
352:
353: const char* pa_ap_table_get(const pa_table *t, const char *name) {
1.2 moko 354: return ap_table_get((const apr_table_t*)t, name);
1.1 moko 355: }
356: void pa_ap_table_addn(pa_table *t, const char *name, const char *val) {
1.2 moko 357: ap_table_addn((apr_table_t*)t, name, val);
1.1 moko 358: }
359:
360: int pa_ap_table_size(const pa_table *t) {
1.2 moko 361: return ap_table_elts((const apr_table_t*)t)->nelts;
1.1 moko 362: }
363:
1.2 moko 364: void pa_ap_table_do(int (*comp) (void *, const char *, const char *), void *rec, const pa_table *t, ...) {
365: ap_table_do(comp, rec, (apr_table_t*)t, 0);
1.1 moko 366: }
367:
368: char * pa_ap_pstrdup(pa_pool *p, const char *s) {
1.2 moko 369: return ap_pstrdup((apr_pool_t*)p, s);
1.1 moko 370: }
371:
372: // http_protocol.h
373:
374: int pa_ap_setup_client_block(pa_request_rec *r, int read_policy) {
375: return ap_setup_client_block((request_rec*)r->real_request_rec,
376: read_policy);
377: }
378: int pa_ap_should_client_block(pa_request_rec *r) {
379: return ap_should_client_block((request_rec*)r->real_request_rec);
380: }
381: long pa_ap_get_client_block(pa_request_rec *r, char *buffer, int bufsiz) {
382: return ap_get_client_block((request_rec*)r->real_request_rec,
383: buffer, bufsiz);
384: }
385: void pa_ap_send_http_header(pa_request_rec *r) {
1.2 moko 386: // Apache2 send headers before body automatically
387: #ifndef STANDARD20_MODULE_STUFF
1.1 moko 388: ap_send_http_header((request_rec*)r->real_request_rec);
1.2 moko 389: #endif
1.1 moko 390: }
391: int pa_ap_rwrite(const void *buf, int nbyte, pa_request_rec *r) {
392: return ap_rwrite(buf, nbyte, (request_rec*)r->real_request_rec);
393: }
394:
395: // http_main.h
396:
397: void pa_ap_hard_timeout(char *s, pa_request_rec *r) {
1.2 moko 398: // Apache 2 uses non-blocking I/O
399: #ifndef STANDARD20_MODULE_STUFF
1.1 moko 400: ap_hard_timeout(s, (request_rec*)r->real_request_rec);
1.2 moko 401: #endif
1.1 moko 402: }
403: void pa_ap_reset_timeout(pa_request_rec *r) {
1.2 moko 404: #ifndef STANDARD20_MODULE_STUFF
1.1 moko 405: ap_reset_timeout((request_rec*)r->real_request_rec);
1.2 moko 406: #endif
1.1 moko 407: }
408: void pa_ap_kill_timeout(pa_request_rec *r) {
1.2 moko 409: #ifndef STANDARD20_MODULE_STUFF
1.1 moko 410: ap_kill_timeout((request_rec*)r->real_request_rec);
1.2 moko 411: #endif
1.1 moko 412: }
413:
414: // util_script.h
415:
416: void pa_ap_add_cgi_vars(pa_request_rec *r) {
417: ap_add_cgi_vars((request_rec*)r->real_request_rec);
418: }
419: void pa_ap_add_common_vars(pa_request_rec *r) {
420: ap_add_common_vars((request_rec*)r->real_request_rec);
421: }
422:
1.2 moko 423: #ifndef WIN32
1.1 moko 424: // signal.h
425:
426: void (*pa_signal (int sig, void (*disp)(int)))(int) {
427: if(sig==PA_SIGPIPE && disp==PA_SIG_IGN)
428: return signal(SIGPIPE, SIG_IGN);
429:
430: return 0;
431: }
1.5 ! moko 432: #endif
E-mail: