From: Nick Kew Date: Tue, 9 Oct 2007 15:50:55 +0000 (+0000) Subject: mod_proxy_http: Remove Warning headers with wrong date X-Git-Tag: 2.2.7~320 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f1e0d94b3f7d683f36c43c11e75e5e5ab4071ac;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy_http: Remove Warning headers with wrong date PR 16138 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@583202 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 3d5f415672b..f9b82d270d6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.7 + *) mod_proxy_http: Remove Warning headers with wrong date + PR 16138 [Nick Kew] + *) mod_proxy_http: Correctly parse all Connection headers in proxy. PR 43509 [Nick Kew] diff --git a/STATUS b/STATUS index 2fd3bf24a42..a6940c27be2 100644 --- a/STATUS +++ b/STATUS @@ -79,18 +79,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_proxy_http: Remove Warning headers with wrong date - PR 16138 - trunk: http://svn.apache.org/viewvc?view=rev&revision=580782 - 2.2.x: http://people.apache.org/~niq/16138.patch - +1: niq, rpluem - niq: changed the name. Resisted temptation to use "pooltabletime". - rpluem says: Revision of name change is r581030. - -1: jim nasty conflict with r580457... backports should be - self contained - niq: separate 2.2.x patch fixes jim's objection - +1: jim - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index 7b867cd146d..34eef68c795 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -17,6 +17,7 @@ /* HTTP routines for Apache proxy */ #include "mod_proxy.h" +#include "ap_regex.h" module AP_MODULE_DECLARE_DATA proxy_http_module; @@ -101,7 +102,72 @@ static int proxy_http_canon(request_rec *r, char *url) typedef struct header_dptr { apr_pool_t *pool; apr_table_t *table; + apr_time_t time; } header_dptr; +static ap_regex_t *warn_rx; +static int clean_warning_headers(void *data, const char *key, const char *val) +{ + apr_table_t *headers = ((header_dptr*)data)->table; + apr_pool_t *pool = ((header_dptr*)data)->pool; + char *warning; + char *date; + apr_time_t warn_time; + const int nmatch = 3; + ap_regmatch_t pmatch[3]; + + if (headers == NULL) { + ((header_dptr*)data)->table = headers = apr_table_make(pool, 2); + } +/* + * Parse this, suckers! + * + * Warning = "Warning" ":" 1#warning-value + * + * warning-value = warn-code SP warn-agent SP warn-text + * [SP warn-date] + * + * warn-code = 3DIGIT + * warn-agent = ( host [ ":" port ] ) | pseudonym + * ; the name or pseudonym of the server adding + * ; the Warning header, for use in debugging + * warn-text = quoted-string + * warn-date = <"> HTTP-date <"> + * + * Buggrit, use a bloomin' regexp! + * (\d{3}\s+\S+\s+\".*?\"(\s+\"(.*?)\")?) --> whole in $1, date in $3 + */ + while (!ap_regexec(warn_rx, val, nmatch, pmatch, 0)) { + warning = apr_pstrndup(pool, val+pmatch[0].rm_so, + pmatch[0].rm_eo - pmatch[0].rm_so); + warn_time = 0; + if (pmatch[2].rm_eo > pmatch[2].rm_so) { + /* OK, we have a date here */ + date = apr_pstrndup(pool, val+pmatch[2].rm_so, + pmatch[2].rm_eo - pmatch[2].rm_so); + warn_time = apr_date_parse_http(date); + } + if (!warn_time || (warn_time == ((header_dptr*)data)->time)) { + apr_table_addn(headers, key, warning); + } + val += pmatch[0].rm_eo; + } + return 1; +} +static apr_table_t *ap_proxy_clean_warnings(apr_pool_t *p, apr_table_t *headers) +{ + header_dptr x; + x.pool = p; + x.table = NULL; + x.time = apr_date_parse_http(apr_table_get(headers, "Date")); + apr_table_do(clean_warning_headers, &x, headers, "Warning", NULL); + if (x.table != NULL) { + apr_table_unset(headers, "Warning"); + return apr_table_overlay(p, headers, x.table); + } + else { + return headers; + } +} static int clear_conn_headers(void *data, const char *key, const char *val) { apr_table_t *headers = ((header_dptr*)data)->table; @@ -1390,6 +1456,8 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, for (i=0; hop_by_hop_hdrs[i]; ++i) { apr_table_unset(r->headers_out, hop_by_hop_hdrs[i]); } + /* Delete warnings with wrong date */ + r->headers_out = ap_proxy_clean_warnings(p, r->headers_out); /* handle Via header in response */ if (conf->viaopt != via_off && conf->viaopt != via_block) { @@ -1772,11 +1840,17 @@ cleanup: } return status; } - +static apr_status_t warn_rx_free(void *p) +{ + ap_pregfree((apr_pool_t*)p, warn_rx); + return APR_SUCCESS; +} static void ap_proxy_http_register_hook(apr_pool_t *p) { proxy_hook_scheme_handler(proxy_http_handler, NULL, NULL, APR_HOOK_FIRST); proxy_hook_canon_handler(proxy_http_canon, NULL, NULL, APR_HOOK_FIRST); + warn_rx = ap_pregcomp(p, "[0-9]{3}[ \t]+[^ \t]+[ \t]+\"[^\"]*\"([ \t]+\"([^\"]+)\")?", 0); + apr_pool_cleanup_register(p, p, warn_rx_free, NULL); } module AP_MODULE_DECLARE_DATA proxy_http_module = {