From: Stefan Fritsch Date: Sat, 16 Jul 2011 21:53:18 +0000 (+0000) Subject: Add more (trace) logging to the ap_scan_script_header*() functions X-Git-Tag: 2.3.14^2~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=beb3ea9c11ef0fb6396403120f29d9ab2cae3215;p=thirdparty%2Fapache%2Fhttpd.git Add more (trace) logging to the ap_scan_script_header*() functions Add ap_scan_script_header*_ex() functions that take a module index for logging. Make mod_cgi, mod_cgid, mod_proxy_fcgi, mod_proxy_scgi, mod_isapi use the new functions. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1147493 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index b46fe3c5f7a..408ab07b7cf 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,13 @@ Changes with Apache 2.3.14 + *) core: Add more logging to ap_scan_script_header_err* functions. Add + ap_scan_script_header_err*_ex functions that take a module index for + logging. + mod_cgi, mod_cgid, mod_proxy_fcgi, mod_proxy_scgi, mod_isapi: Use the + new functions in order to make logging configurable per-module. + [Stefan Fritsch] + *) mod_dir: Add DirectoryIndexRedirect to send an external redirect to the proper index. [Eric Covener] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 8bba1240794..66a4e166226 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -337,9 +337,10 @@ * add ap_start_lingering_close(), * add conn_state_e:CONN_STATE_LINGER_NORMAL and CONN_STATE_LINGER_SHORT * 20110619.1 (2.3.13-dev) add ap_str_toupper() - * 20110702.0 (2.3.13-dev) make ap_expr_parse_cmd() macro wrapper for new + * 20110702.0 (2.3.14-dev) make ap_expr_parse_cmd() macro wrapper for new * ap_expr_parse_cmd_mi() function, add ap_expr_str_*() functions, * rename AP_EXPR_FLAGS_* -> AP_EXPR_FLAG_* + * 20110702.1 (2.3.14-dev) Add ap_scan_script_header_err*_ex functions */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -347,7 +348,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20110702 #endif -#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/util_script.h b/include/util_script.h index e019aaefd80..e7fe61740b4 100644 --- a/include/util_script.h +++ b/include/util_script.h @@ -90,6 +90,21 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r); */ AP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f, char *buffer); +/** + * Read headers output from a script, ensuring that the output is valid. If + * the output is valid, then the headers are added to the headers out of the + * current request + * @param r The current request + * @param f The file to read from + * @param buffer Empty when calling the function. On output, if there was an + * error, the string that cause the error is stored here. + * @param module_index The module index to be used for logging + * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise + */ +AP_DECLARE(int) ap_scan_script_header_err_ex(request_rec *r, apr_file_t *f, + char *buffer, int module_index); + + /** * Read headers output from a script, ensuring that the output is valid. If * the output is valid, then the headers are added to the headers out of the @@ -105,6 +120,22 @@ AP_DECLARE(int) ap_scan_script_header_err_brigade(request_rec *r, apr_bucket_brigade *bb, char *buffer); +/** + * Read headers output from a script, ensuring that the output is valid. If + * the output is valid, then the headers are added to the headers out of the + * current request + * @param r The current request + * @param bb The brigade from which to read + * @param buffer Empty when calling the function. On output, if there was an + * error, the string that cause the error is stored here. + * @param module_index The module index to be used for logging + * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise + */ +AP_DECLARE(int) ap_scan_script_header_err_brigade_ex(request_rec *r, + apr_bucket_brigade *bb, + char *buffer, + int module_index); + /** * Read headers strings from a script, ensuring that the output is valid. If * the output is valid, then the headers are added to the headers out of the @@ -126,6 +157,30 @@ AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r, int *termarg, ...) ap_func_attr_sentinel; +/** + * Read headers strings from a script, ensuring that the output is valid. If + * the output is valid, then the headers are added to the headers out of the + * current request + * @param r The current request + * @param buffer Empty when calling the function. On output, if there was an + * error, the string that cause the error is stored here. + * @param module_index The module index to be used for logging + * @param termch Pointer to the last character parsed. + * @param termarg Pointer to an int to capture the last argument parsed. + * + * The varargs are string arguments to parse consecutively for headers, + * with a NULL argument to terminate the list. + * + * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise + */ +AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs_ex(request_rec *r, + char *buffer, + int module_index, + const char **termch, + int *termarg, ...) + ap_func_attr_sentinel; + + /** * Read headers output from a script, ensuring that the output is valid. If * the output is valid, then the headers are added to the headers out of the @@ -142,6 +197,24 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, int (*getsfunc) (char *, int, void *), void *getsfunc_data); +/** + * Read headers output from a script, ensuring that the output is valid. If + * the output is valid, then the headers are added to the headers out of the + * current request + * @param r The current request + * @param buffer Empty when calling the function. On output, if there was an + * error, the string that cause the error is stored here. + * @param getsfunc Function to read the headers from. This function should + act like gets() + * @param getsfunc_data The place to read from + * @param module_index The module index to be used for logging + * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise + */ +AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer, + int (*getsfunc) (char *, int, void *), + void *getsfunc_data, int module_index); + + /** * Parse query args for the request and store in a new table allocated * from the request pool. diff --git a/modules/arch/win32/mod_isapi.c b/modules/arch/win32/mod_isapi.c index 682bd6411d0..71a2881ae21 100644 --- a/modules/arch/win32/mod_isapi.c +++ b/modules/arch/win32/mod_isapi.c @@ -714,12 +714,12 @@ static apr_ssize_t send_response_header(isapi_cid *cid, old_status = cid->r->status; if (stat) { - res = ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg, - stat, head, NULL); + res = ap_scan_script_header_err_strs_ex(cid->r, NULL, + APLOG_MODULE_INDEX, &termch, &termarg, stat, head, NULL); } else { - res = ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg, - head, NULL); + res = ap_scan_script_header_err_strs_ex(cid->r, NULL, + APLOG_MODULE_INDEX, &termch, &termarg, head, NULL); } /* Set our status. */ diff --git a/modules/generators/mod_asis.c b/modules/generators/mod_asis.c index 0809a8446bd..5c724c020e3 100644 --- a/modules/generators/mod_asis.c +++ b/modules/generators/mod_asis.c @@ -56,7 +56,7 @@ static int asis_handler(request_rec *r) return HTTP_FORBIDDEN; } - ap_scan_script_header_err(r, f, NULL); + ap_scan_script_header_err_ex(r, f, NULL, APLOG_MODULE_INDEX); location = apr_table_get(r->headers_out, "Location"); if (location && location[0] == '/' && diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c index 29eca51f267..02a5700f16b 100644 --- a/modules/generators/mod_cgi.c +++ b/modules/generators/mod_cgi.c @@ -940,7 +940,9 @@ static int cgi_handler(request_rec *r) char sbuf[MAX_STRING_LEN]; int ret; - if ((ret = ap_scan_script_header_err_brigade(r, bb, sbuf))) { + if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, + APLOG_MODULE_INDEX))) + { ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err); /* diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 148ff534d4d..a18fa21e1b9 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -1543,7 +1543,9 @@ static int cgid_handler(request_rec *r) b = apr_bucket_eos_create(c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); - if ((ret = ap_scan_script_header_err_brigade(r, bb, sbuf))) { + if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, + APLOG_MODULE_INDEX))) + { ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL); /* diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c index e0f264bf629..050021878c4 100644 --- a/modules/proxy/mod_proxy_fcgi.c +++ b/modules/proxy/mod_proxy_fcgi.c @@ -741,8 +741,8 @@ recv_again: int status; seen_end_of_headers = 1; - status = ap_scan_script_header_err_brigade(r, ob, - NULL); + status = ap_scan_script_header_err_brigade_ex(r, ob, + NULL, APLOG_MODULE_INDEX); /* suck in all the rest */ if (status != OK) { apr_bucket *tmp_b; diff --git a/modules/proxy/mod_proxy_scgi.c b/modules/proxy/mod_proxy_scgi.c index cdd33eb8d95..fc7e488c59c 100644 --- a/modules/proxy/mod_proxy_scgi.c +++ b/modules/proxy/mod_proxy_scgi.c @@ -369,7 +369,8 @@ static int pass_response(request_rec *r, proxy_conn_rec *conn) b = apr_bucket_eos_create(r->connection->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); - status = ap_scan_script_header_err_brigade(r, bb, NULL); + status = ap_scan_script_header_err_brigade_ex(r, bb, NULL, + APLOG_MODULE_INDEX); if (status != OK) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: " PROXY_FUNCTION ": error reading response " diff --git a/server/util_script.c b/server/util_script.c index 03926943d41..648e0bff974 100644 --- a/server/util_script.c +++ b/server/util_script.c @@ -398,10 +398,12 @@ static int set_cookie_doo_doo(void *v, const char *key, const char *val) } #define HTTP_UNSET (-HTTP_OK) +#define SCRIPT_LOG_MARK __FILE__,__LINE__,module_index -AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, +AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer, int (*getsfunc) (char *, int, void *), - void *getsfunc_data) + void *getsfunc_data, + int module_index) { char x[MAX_STRING_LEN]; char *w, *l; @@ -409,6 +411,8 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, int cgi_status = HTTP_UNSET; apr_table_t *merge; apr_table_t *cookie_table; + int trace_log = APLOG_R_MODULE_IS_LEVEL(r, module_index, APLOG_TRACE1); + int first_header = 1; if (buffer) { *buffer = '\0'; @@ -431,13 +435,16 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, int rv = (*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data); if (rv == 0) { - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, - "Premature end of script headers: %s", + const char *msg = "Premature end of script headers"; + if (first_header) + msg = "End of script output before headers"; + ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, + "%s: %s", msg, apr_filepath_name_get(r->filename)); return HTTP_INTERNAL_SERVER_ERROR; } else if (rv == -1) { - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, + ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, "Script timed out before returning headers: %s", apr_filepath_name_get(r->filename)); return HTTP_GATEWAY_TIME_OUT; @@ -499,6 +506,14 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, return cond_status; } + if (trace_log) { + if (first_header) + ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE4, 0, r, + "Headers from script '%s':", + apr_filepath_name_get(r->filename)); + ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE4, 0, r, " %s", w); + } + /* if we see a bogus header don't ignore it. Shout and scream */ #if APR_CHARSET_EBCDIC @@ -518,7 +533,7 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, ++maybeASCII; } if (maybeASCII > maybeEBCDIC) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + ap_log_error(SCRIPT_LOG_MARK, APLOG_ERR, 0, r->server, "CGI Interface Error: Script headers apparently ASCII: (CGI = %s)", r->filename); inbytes_left = outbytes_left = cp - w; @@ -535,8 +550,8 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, } } - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, - "malformed header from script: %s; Bad header: %.30s", + ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, + "malformed header from script '%s': Bad header: %.30s", apr_filepath_name_get(r->filename), w); return HTTP_INTERNAL_SERVER_ERROR; } @@ -566,6 +581,14 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, */ else if (!strcasecmp(w, "Status")) { r->status = cgi_status = atoi(l); + if (!ap_is_HTTP_VALID_RESPONSE(cgi_status)) + ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, + "Invalid status line from script '%s': %s", + apr_filepath_name_get(r->filename), w); + else + ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r, + "Status line from script '%s': %s", + apr_filepath_name_get(r->filename), w); r->status_line = apr_pstrdup(r->pool, l); } else if (!strcasecmp(w, "Location")) { @@ -597,11 +620,21 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, else { apr_table_add(merge, w, l); } + first_header = 0; } /* never reached - we leave this function within the while loop above */ return OK; } +AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, + int (*getsfunc) (char *, int, void *), + void *getsfunc_data) +{ + return ap_scan_script_header_err_core_ex(r, buffer, getsfunc, + getsfunc_data, + APLOG_MODULE_INDEX); +} + static int getsfunc_FILE(char *buf, int len, void *f) { return apr_file_gets(buf, len, (apr_file_t *) f) == APR_SUCCESS; @@ -610,9 +643,18 @@ static int getsfunc_FILE(char *buf, int len, void *f) AP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f, char *buffer) { - return ap_scan_script_header_err_core(r, buffer, getsfunc_FILE, f); + return ap_scan_script_header_err_core_ex(r, buffer, getsfunc_FILE, f, + APLOG_MODULE_INDEX); +} + +AP_DECLARE(int) ap_scan_script_header_err_ex(request_rec *r, apr_file_t *f, + char *buffer, int module_index) +{ + return ap_scan_script_header_err_core_ex(r, buffer, getsfunc_FILE, f, + module_index); } + static int getsfunc_BRIGADE(char *buf, int len, void *arg) { apr_bucket_brigade *bb = (apr_bucket_brigade *)arg; @@ -662,9 +704,20 @@ AP_DECLARE(int) ap_scan_script_header_err_brigade(request_rec *r, apr_bucket_brigade *bb, char *buffer) { - return ap_scan_script_header_err_core(r, buffer, getsfunc_BRIGADE, bb); + return ap_scan_script_header_err_core_ex(r, buffer, getsfunc_BRIGADE, bb, + APLOG_MODULE_INDEX); +} + +AP_DECLARE(int) ap_scan_script_header_err_brigade_ex(request_rec *r, + apr_bucket_brigade *bb, + char *buffer, + int module_index) +{ + return ap_scan_script_header_err_core_ex(r, buffer, getsfunc_BRIGADE, bb, + module_index); } + struct vastrs { va_list args; int arg; @@ -703,6 +756,28 @@ static int getsfunc_STRING(char *w, int len, void *pvastrs) * character is returned to **arg, **data. (The first optional arg is * counted as 0.) */ +AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs_ex(request_rec *r, + char *buffer, + int module_index, + const char **termch, + int *termarg, ...) +{ + struct vastrs strs; + int res; + + va_start(strs.args, termarg); + strs.arg = 0; + strs.curpos = va_arg(strs.args, char*); + res = ap_scan_script_header_err_core_ex(r, buffer, getsfunc_STRING, + (void *) &strs, module_index); + if (termch) + *termch = strs.curpos; + if (termarg) + *termarg = strs.arg; + va_end(strs.args); + return res; +} + AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r, char *buffer, const char **termch, @@ -714,7 +789,8 @@ AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r, va_start(strs.args, termarg); strs.arg = 0; strs.curpos = va_arg(strs.args, char*); - res = ap_scan_script_header_err_core(r, buffer, getsfunc_STRING, (void *) &strs); + res = ap_scan_script_header_err_core_ex(r, buffer, getsfunc_STRING, + (void *) &strs, APLOG_MODULE_INDEX); if (termch) *termch = strs.curpos; if (termarg) @@ -723,7 +799,6 @@ AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r, return res; } - static void argstr_to_table(char *str, apr_table_t *parms) {