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

1.1       moko        1: /** @file
1.2       moko        2:        Parser: apache 1.3 and 2.2 module
1.1       moko        3: 
1.20      moko        4:        Copyright (c) 2001-2020 Art. Lebedev Studio (http://www.artlebedev.com)
1.1       moko        5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
                      6: */
                      7: 
                      8: #include "httpd.h"
                      9: #include "http_config.h"
                     10: #include "http_core.h"
                     11: #include "http_log.h"
                     12: #include "http_main.h"
                     13: #include "http_protocol.h"
                     14: #include "util_script.h"
1.2       moko       15: 
                     16: #include "pa_httpd.h"
                     17: 
1.21    ! moko       18: volatile const char * IDENT_MOD_PARSER3_C="$Id: mod_parser3.c,v 1.20 2020/12/15 17:10:37 moko Exp $" IDENT_PA_HTTPD_H;
1.12      moko       19: 
1.3       moko       20: #define PARSER3_HANDLER "parser3-handler"
                     21: 
1.2       moko       22: /*
                     23: * To Ease Compatibility
                     24: */
                     25: #ifdef STANDARD20_MODULE_STUFF
                     26: 
                     27: #include "apr_strings.h"
1.14      moko       28: #include "ap_mpm.h"
1.2       moko       29: 
                     30: #define ap_pcalloc     apr_pcalloc
                     31: #define ap_pstrdup     apr_pstrdup
                     32: 
                     33: #define ap_table_get   apr_table_get
                     34: #define ap_table_elts  apr_table_elts
                     35: #define ap_table_addn  apr_table_addn
                     36: #define ap_table_do    apr_table_do
                     37: 
                     38: #else
                     39: 
1.1       moko       40: #include "ap_alloc.h"
                     41: 
1.2       moko       42: #define apr_pool_t pool
                     43: #define apr_table_t table
                     44: 
                     45: #endif /* STANDARD20_MODULE_STUFF */
1.1       moko       46: 
                     47: /*
                     48: * Declare ourselves so the configuration routines can find and know us.
                     49: * We'll fill it in at the end of the module.
                     50: */
1.2       moko       51: 
                     52: #ifdef STANDARD20_MODULE_STUFF
                     53: module AP_MODULE_DECLARE_DATA parser3_module;
1.14      moko       54: static int is_threaded = 0;
1.2       moko       55: #else
                     56: module MODULE_VAR_EXPORT parser3_module;
                     57: #endif
1.1       moko       58: 
                     59: /*
                     60: * Locate our directory configuration record for the current request.
                     61: */
                     62: static Parser_module_config *our_dconfig(request_rec *r) {
1.5       moko       63:        return (Parser_module_config *) ap_get_module_config(r->per_dir_config, &parser3_module);
1.1       moko       64: }
                     65: 
1.9       moko       66: static const char* cmd_parser_config(cmd_parms *cmd, void *mconfig, const char *file_spec) {
1.1       moko       67:        Parser_module_config *cfg = (Parser_module_config *) mconfig;
                     68:        cfg->parser_config_filespec=file_spec;
                     69:        return NULL;
                     70: }
                     71: 
                     72: /* 
1.2       moko       73: * Now let's declare routines for each of the callback phase in order.
1.1       moko       74: */
                     75: 
1.3       moko       76: static int parser_handler(request_rec *r) {
                     77: #ifdef STANDARD20_MODULE_STUFF
                     78:        if(strcmp(r->handler, PARSER3_HANDLER))
                     79:                return DECLINED;
1.14      moko       80: 
                     81:        if(is_threaded){
1.21    ! moko       82:                const char *message="Parser3 module requires libapache2-mpm-itk";
1.14      moko       83:                r->status=HTTP_INTERNAL_SERVER_ERROR;
                     84:                r->content_type="text/plain";
                     85:                ap_rwrite(message, strlen(message), r);
                     86:                return OK;
                     87:        }
1.3       moko       88: #endif
1.13      moko       89: 
                     90:        // we setup module here to avoid GPF on init with php5-xsl installed
                     91:        pa_setup_module_cells();
                     92: 
1.16      moko       93:        {
                     94:                // converting to parser version
                     95:                pa_request_rec pr={
                     96:                        r,
                     97:                        r->pool,
                     98:                        r->header_only,
                     99:                        &r->status,
                    100:                        r->method,
                    101:                        r->headers_out,
                    102:                        r->subprocess_env,
                    103:                        &r->content_type,
                    104:                        r->uri,
                    105:                        r->filename,
                    106:                        r->path_info,
                    107:                        r->args,
1.3       moko      108: #ifdef STANDARD20_MODULE_STUFF
1.16      moko      109:                        r->finfo.filetype == 0
1.3       moko      110: #else          
1.16      moko      111:                        r->finfo.st_mode == 0
1.3       moko      112: #endif
1.16      moko      113:                };
                    114:                return pa_parser_handler(&pr, our_dconfig(r));
                    115:        }
1.1       moko      116: }
                    117: 
                    118: /* 
1.4       moko      119: * This function is called during process initialisation.
1.1       moko      120: */
                    121: 
1.3       moko      122: #ifdef STANDARD20_MODULE_STUFF
1.10      moko      123: static void parser_child_init(apr_pool_t *p, server_rec *s) {
1.3       moko      124: #else
1.2       moko      125: static void parser_module_init(server_rec *s, apr_pool_t *p) {
1.1       moko      126: #endif 
1.13      moko      127: //     ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, p, "parser inited %d", getpid());
1.1       moko      128: }
                    129: 
                    130: /* 
1.2       moko      131: * All our process-death routine does is add its trace to the log.
                    132: */
                    133: static void parser_module_done(server_rec *s, apr_pool_t *p) {
1.1       moko      134:        pa_destroy_module_cells();
                    135: }
                    136: 
                    137: /*
1.2       moko      138: * This function gets called to create a per-directory configuration record.
1.1       moko      139: */
1.2       moko      140: static void *parser_create_dir_config(apr_pool_t *p, char *dirspec) {
1.6       moko      141:        Parser_module_config *cfg= ap_pcalloc(p, sizeof(Parser_module_config));
                    142:        cfg->parser_config_filespec=NULL;
                    143:        return cfg;
1.1       moko      144: }
                    145: 
                    146: /*
1.2       moko      147: * This function gets called to create a per-server configuration record.
1.1       moko      148: */
1.2       moko      149: static void *parser_create_server_config(apr_pool_t *p, server_rec *s) {
1.6       moko      150:        Parser_module_config *cfg= ap_pcalloc(p, sizeof(Parser_module_config));
                    151:        cfg->parser_config_filespec=NULL;
                    152:        return cfg;
1.1       moko      153: }
                    154: 
                    155: /* 
                    156: * List of directives specific to our module.
                    157: */
                    158: static const command_rec parser_cmds[] =
                    159: {
1.11      moko      160:        {"ParserConfig", (const char *(*)())cmd_parser_config, 0, OR_OPTIONS, TAKE1, "Parser config filespec"},
1.10      moko      161:        {NULL}
1.1       moko      162: };
                    163: 
                    164: /*--------------------------------------------------------------------------*/
                    165: /* Now the list of content handlers available from this module.             */
                    166: /*--------------------------------------------------------------------------*/
1.2       moko      167: 
                    168: #ifndef STANDARD20_MODULE_STUFF
1.1       moko      169: static const handler_rec parser_handlers[] =
                    170: {
1.3       moko      171:        {PARSER3_HANDLER, parser_handler},
1.1       moko      172:        {NULL}
                    173: };
1.2       moko      174: #endif
1.1       moko      175: 
                    176: /*--------------------------------------------------------------------------*/
                    177: /* Finally, the list of callback routines and data structures that          */
                    178: /* provide the hooks into our module from the other parts of the server.    */
                    179: /*--------------------------------------------------------------------------*/
1.2       moko      180: 
                    181: #ifdef STANDARD20_MODULE_STUFF
                    182: 
1.1       moko      183: /* 
1.2       moko      184: * register hooks.
1.1       moko      185: */
1.2       moko      186: static void parser_register_hooks(apr_pool_t* pool)
                    187: {
1.14      moko      188:        int mpm_query_info;
                    189:        is_threaded = ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_query_info) == APR_SUCCESS && mpm_query_info != AP_MPMQ_NOT_SUPPORTED;
1.2       moko      190:        ap_hook_handler(parser_handler, NULL, NULL, APR_HOOK_MIDDLE);
1.10      moko      191:        ap_hook_child_init(parser_child_init, NULL, NULL, APR_HOOK_MIDDLE);
1.2       moko      192: };
                    193: 
                    194: module AP_MODULE_DECLARE_DATA parser3_module =
                    195: {
                    196:        STANDARD20_MODULE_STUFF,
                    197: #else
1.1       moko      198: module MODULE_VAR_EXPORT parser3_module =
                    199: {
                    200:        STANDARD_MODULE_STUFF,
1.5       moko      201:        parser_module_init,             /* module initializer */
1.2       moko      202: #endif
1.5       moko      203:        parser_create_dir_config,       /* per-directory config creator */
1.6       moko      204:        0,                              /* dir config merger */
1.5       moko      205:        parser_create_server_config,    /* server config creator */
1.6       moko      206:        0,                              /* server config merger */
1.5       moko      207:        parser_cmds,                    /* command apr_table_t */
1.2       moko      208: #ifdef STANDARD20_MODULE_STUFF
1.5       moko      209:        parser_register_hooks           /* register hooks */
1.2       moko      210: #else
1.5       moko      211:        parser_handlers,                /* [9] list of handlers */
                    212:        0,                              /* [2] filename-to-URI translation */
                    213:        0,                              /* [5] check/validate user_id */
                    214:        0,                              /* [6] check user_id is valid *here* */
                    215:        0,                              /* [4] check access by host address */
                    216:        0,                              /* [7] MIME type checker/setter */
                    217:        0,                              /* [8] fixups */
                    218:        0,                              /* [10] logger */
                    219:        0,                              /* [3] header parser */
                    220:        0,                              /* process initializer */
                    221:        parser_module_done              /* process exit/cleanup */
1.2       moko      222: #endif // STANDARD20_MODULE_STUFF
1.1       moko      223: };
                    224: 
                    225: #if defined(_MSC_VER)
1.15      moko      226: #      define APACHE_WIN32_SRC "../../../../win32/apache22/"
1.1       moko      227: #      ifdef _DEBUG
1.15      moko      228: #              pragma comment(lib, APACHE_WIN32_SRC "srclib/apr/Debug/libapr-1.lib")
                    229: #              pragma comment(lib, APACHE_WIN32_SRC "Debug/libhttpd.lib")
1.1       moko      230: #      else
1.15      moko      231: #              pragma comment(lib, APACHE_WIN32_SRC "srclib/apr/Release/libapr-1.lib")
                    232: #              pragma comment(lib, APACHE_WIN32_SRC "Release/libhttpd.lib")
1.1       moko      233: #      endif
                    234: #endif
                    235: 
                    236: 
                    237: // interface to C++
                    238: 
1.2       moko      239: void pa_ap_log_rerror(const char *file, int line, int level, const pa_request_rec *s, const char *fmt, ...) {
1.1       moko      240:        const char* str;
                    241:        va_list l;
                    242:        va_start(l, fmt); 
                    243:        str=va_arg(l, const char*);
                    244:        va_end(l); 
                    245: 
1.17      moko      246:        ap_log_rerror(file, line,
                    247: #if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER >= 4)
                    248:                        APLOG_MODULE_INDEX,
                    249: #endif
                    250:                        level,
1.2       moko      251: #ifdef STANDARD20_MODULE_STUFF
1.10      moko      252:                        0,
1.2       moko      253: #endif
1.10      moko      254:                        (request_rec*)s->real_request_rec, "%s", str);
1.1       moko      255: }
                    256: 
                    257: 
1.2       moko      258: void pa_ap_log_error(const char *file, int line, int level, const pa_server_rec *s, const char *fmt, ...) {
1.1       moko      259:        const char* str;
                    260:        va_list l;
                    261:        va_start(l, fmt); 
                    262:        str=va_arg(l, const char*);
                    263:        va_end(l); 
                    264: 
1.17      moko      265:        ap_log_error(file, line,
                    266: #if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER >= 4)
                    267:                        APLOG_MODULE_INDEX,
                    268: #endif
                    269:                        level,
1.2       moko      270: #ifdef STANDARD20_MODULE_STUFF
1.10      moko      271:                        0,
1.2       moko      272: #endif
1.10      moko      273:                        (server_rec*)s, "%s", str);
1.1       moko      274: }
                    275: 
                    276: // ap_alloc.h
                    277: 
                    278: const char* pa_ap_table_get(const pa_table *t, const char *name) {
1.2       moko      279:        return ap_table_get((const apr_table_t*)t, name);
1.1       moko      280: }
                    281: void pa_ap_table_addn(pa_table *t, const char *name, const char *val) {
1.2       moko      282:        ap_table_addn((apr_table_t*)t, name, val);
1.1       moko      283: }
                    284: 
                    285: int pa_ap_table_size(const pa_table *t) {
1.2       moko      286:        return ap_table_elts((const apr_table_t*)t)->nelts;
1.1       moko      287: }
                    288: 
1.2       moko      289: void pa_ap_table_do(int (*comp) (void *, const char *, const char *), void *rec, const pa_table *t, ...) {
1.14      moko      290:        ap_table_do(comp, rec, (apr_table_t*)t, NULL);
1.1       moko      291: }
                    292: 
                    293: char * pa_ap_pstrdup(pa_pool *p, const char *s) {
1.2       moko      294:        return ap_pstrdup((apr_pool_t*)p, s);
1.1       moko      295: }
                    296: 
                    297: // http_protocol.h
                    298: 
                    299: int pa_ap_setup_client_block(pa_request_rec *r, int read_policy) {
                    300:        return ap_setup_client_block((request_rec*)r->real_request_rec,
                    301:                read_policy);
                    302: }
                    303: int pa_ap_should_client_block(pa_request_rec *r) {
                    304:        return ap_should_client_block((request_rec*)r->real_request_rec);
                    305: }
                    306: long pa_ap_get_client_block(pa_request_rec *r, char *buffer, int bufsiz) {
                    307:        return ap_get_client_block((request_rec*)r->real_request_rec,
                    308:                buffer, bufsiz);
                    309: }
                    310: void pa_ap_send_http_header(pa_request_rec *r) {
1.2       moko      311: // Apache2 send headers before body automatically
                    312: #ifndef STANDARD20_MODULE_STUFF
1.1       moko      313:        ap_send_http_header((request_rec*)r->real_request_rec);
1.2       moko      314: #endif
1.1       moko      315: }
                    316: int pa_ap_rwrite(const void *buf, int nbyte, pa_request_rec *r) {
                    317:        return ap_rwrite(buf, nbyte, (request_rec*)r->real_request_rec);
                    318: }
                    319: 
                    320: // http_main.h
                    321: 
1.7       moko      322: void pa_ap_hard_timeout(const char *s, pa_request_rec *r) {
1.2       moko      323: // Apache 2 uses non-blocking I/O
                    324: #ifndef STANDARD20_MODULE_STUFF
1.11      moko      325:        ap_hard_timeout((char *)s, (request_rec*)r->real_request_rec);
1.2       moko      326: #endif
1.1       moko      327: }
                    328: void pa_ap_reset_timeout(pa_request_rec *r) {
1.2       moko      329: #ifndef STANDARD20_MODULE_STUFF
1.1       moko      330:        ap_reset_timeout((request_rec*)r->real_request_rec);
1.2       moko      331: #endif
1.1       moko      332: }
                    333: void pa_ap_kill_timeout(pa_request_rec *r) {
1.2       moko      334: #ifndef STANDARD20_MODULE_STUFF
1.1       moko      335:        ap_kill_timeout((request_rec*)r->real_request_rec);
1.2       moko      336: #endif
1.1       moko      337: }
                    338: 
                    339: // util_script.h
                    340: 
                    341: void pa_ap_add_cgi_vars(pa_request_rec *r) {
                    342:        ap_add_cgi_vars((request_rec*)r->real_request_rec);
                    343: }
                    344: void pa_ap_add_common_vars(pa_request_rec *r) {
                    345:        ap_add_common_vars((request_rec*)r->real_request_rec);
                    346: }
                    347: 
                    348: // signal.h
                    349: 
                    350: void (*pa_signal (int sig, void (*disp)(int)))(int) {
1.15      moko      351: #ifndef _MSC_VER
1.1       moko      352:        if(sig==PA_SIGPIPE && disp==PA_SIG_IGN)
                    353:                return signal(SIGPIPE, SIG_IGN);
1.15      moko      354: #endif
1.1       moko      355:        return 0;
                    356: }

E-mail: