Annotation of parser3/src/targets/apache/mod_parser3.c, revision 1.2

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

E-mail: