diff options
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | include/ap_mmn.h | 5 | ||||
-rw-r--r-- | include/util_script.h | 73 | ||||
-rw-r--r-- | modules/arch/win32/mod_isapi.c | 8 | ||||
-rw-r--r-- | modules/generators/mod_asis.c | 2 | ||||
-rw-r--r-- | modules/generators/mod_cgi.c | 4 | ||||
-rw-r--r-- | modules/generators/mod_cgid.c | 4 | ||||
-rw-r--r-- | modules/proxy/mod_proxy_fcgi.c | 4 | ||||
-rw-r--r-- | modules/proxy/mod_proxy_scgi.c | 3 | ||||
-rw-r--r-- | server/util_script.c | 99 |
10 files changed, 185 insertions, 24 deletions
@@ -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 8bba124079..66a4e16622 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 e019aaefd8..e7fe61740b 100644 --- a/include/util_script.h +++ b/include/util_script.h @@ -95,6 +95,21 @@ AP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f, char *b * 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 + * 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. @@ -106,6 +121,22 @@ AP_DECLARE(int) ap_scan_script_header_err_brigade(request_rec *r, 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 * current request @@ -127,6 +158,30 @@ AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r, 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 * current request @@ -143,6 +198,24 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, 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. * For args with no value, "1" will be used instead. diff --git a/modules/arch/win32/mod_isapi.c b/modules/arch/win32/mod_isapi.c index 682bd6411d..71a2881ae2 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 0809a8446b..5c724c020e 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 29eca51f26..02a5700f16 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 148ff534d4..a18fa21e1b 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 e0f264bf62..050021878c 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 cdd33eb8d9..fc7e488c59 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 03926943d4..648e0bff97 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) { |