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

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

E-mail: