X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=server%2Futil_script.c;h=703d16009472b34d73e0b36e64c9c9d63380dfa9;hb=36ab7eb1eb554444ac1d6c06d1988ed33857b6f7;hp=2d070816f0536ac49efecf2014dc106823523afe;hpb=6c6979ede6d856855c854119673ec40f40a7c0c7;p=apache diff --git a/server/util_script.c b/server/util_script.c index 2d070816f0..703d160094 100644 --- a/server/util_script.c +++ b/server/util_script.c @@ -49,10 +49,9 @@ * where there don't have to be). */ -#define MALFORMED_MESSAGE "malformed header from script. Bad header=" -#define MALFORMED_HEADER_LENGTH_TO_SHOW 30 - -APLOG_USE_MODULE(core); +/* we know core's module_index is 0 */ +#undef APLOG_MODULE_INDEX +#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX static char *http2env(request_rec *r, const char *w) { @@ -145,6 +144,7 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r) const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts; int i; apr_port_t rport; + char *q; /* use a temporary apr_table_t which we'll overlap onto * r->subprocess_env later @@ -230,18 +230,28 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r) apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r)); apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_banner()); apr_table_addn(e, "SERVER_NAME", - ap_escape_html(r->pool, ap_get_server_name(r))); + ap_escape_html(r->pool, ap_get_server_name_for_url(r))); apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */ apr_table_addn(e, "SERVER_PORT", apr_psprintf(r->pool, "%u", ap_get_server_port(r))); add_unless_null(e, "REMOTE_HOST", ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL)); - apr_table_addn(e, "REMOTE_ADDR", c->remote_ip); + apr_table_addn(e, "REMOTE_ADDR", r->useragent_ip); apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r)); /* Apache */ + apr_table_setn(e, "REQUEST_SCHEME", ap_http_scheme(r)); + apr_table_addn(e, "CONTEXT_PREFIX", ap_context_prefix(r)); + apr_table_addn(e, "CONTEXT_DOCUMENT_ROOT", ap_context_document_root(r)); apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */ - apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */ + if (apr_table_get(r->notes, "proxy-noquery") && (q = ap_strchr(r->filename, '?'))) { + *q = '\0'; + apr_table_addn(e, "SCRIPT_FILENAME", apr_pstrdup(r->pool, r->filename)); + *q = '?'; + } + else { + apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */ + } - rport = c->remote_addr->port; + rport = c->client_addr->port; apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport)); if (r->user) { @@ -337,7 +347,6 @@ AP_DECLARE(void) ap_add_cgi_vars(request_rec *r) apr_table_setn(e, "GATEWAY_INTERFACE", "CGI/1.1"); apr_table_setn(e, "SERVER_PROTOCOL", r->protocol); apr_table_setn(e, "REQUEST_METHOD", r->method); - apr_table_setn(e, "REQUEST_SCHEME", ap_http_scheme(r)); apr_table_setn(e, "QUERY_STRING", r->args ? r->args : ""); apr_table_setn(e, "REQUEST_URI", original_uri(r)); @@ -397,10 +406,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; @@ -408,6 +419,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'; @@ -430,13 +443,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; @@ -475,7 +491,7 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, /* PR#38070: This fails because it gets confused when a * CGI Status header overrides ap_meets_conditions. - * + * * We can fix that by dropping ap_meets_conditions when * Status has been set. Since this is the only place * cgi_status gets used, let's test it explicitly. @@ -498,6 +514,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 @@ -517,7 +541,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; @@ -527,22 +551,16 @@ AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, } #endif /*APR_CHARSET_EBCDIC*/ if (!(l = strchr(w, ':'))) { - char malformed[(sizeof MALFORMED_MESSAGE) + 1 - + MALFORMED_HEADER_LENGTH_TO_SHOW]; - - strcpy(malformed, MALFORMED_MESSAGE); - strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW); - if (!buffer) { /* Soak up all the script output - may save an outright kill */ - while ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data)) { + while ((*getsfunc)(w, MAX_STRING_LEN - 1, getsfunc_data) > 0) { continue; } } - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, - "%s: %s", malformed, - apr_filepath_name_get(r->filename)); + 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; } @@ -571,6 +589,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), l); + else + ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r, + "Status line from script '%s': %s", + apr_filepath_name_get(r->filename), l); r->status_line = apr_pstrdup(r->pool, l); } else if (!strcasecmp(w, "Location")) { @@ -602,11 +628,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; @@ -615,9 +651,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; @@ -627,7 +672,8 @@ static int getsfunc_BRIGADE(char *buf, int len, void *arg) apr_status_t rv; int done = 0; - while ((dst < dst_end) && !done && !APR_BUCKET_IS_EOS(e)) { + while ((dst < dst_end) && !done && e != APR_BRIGADE_SENTINEL(bb) + && !APR_BUCKET_IS_EOS(e)) { const char *bucket_data; apr_size_t bucket_data_len; const char *src; @@ -637,6 +683,7 @@ static int getsfunc_BRIGADE(char *buf, int len, void *arg) rv = apr_bucket_read(e, &bucket_data, &bucket_data_len, APR_BLOCK_READ); if (rv != APR_SUCCESS || (bucket_data_len == 0)) { + *dst = '\0'; return APR_STATUS_IS_TIMEUP(rv) ? -1 : 0; } src = bucket_data; @@ -660,16 +707,27 @@ static int getsfunc_BRIGADE(char *buf, int len, void *arg) e = next; } *dst = 0; - return 1; + return done; } 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; @@ -682,8 +740,10 @@ static int getsfunc_STRING(char *w, int len, void *pvastrs) const char *p; int t; - if (!strs->curpos || !*strs->curpos) + if (!strs->curpos || !*strs->curpos) { + w[0] = '\0'; return 0; + } p = ap_strchr_c(strs->curpos, '\n'); if (p) ++p; @@ -708,6 +768,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, @@ -719,7 +801,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) @@ -728,7 +811,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) { @@ -739,7 +821,7 @@ argstr_to_table(char *str, apr_table_t *parms) if (str == NULL) { return; } - + key = apr_strtok(str, "&", &strtok_state); while (key) { value = strchr(key, '=');