diff options
author | Eric Covener <covener@apache.org> | 2016-12-08 20:34:54 +0100 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2016-12-08 20:34:54 +0100 |
commit | 8f418b2e628fb3dcca4467f26baf702acdc0c9fc (patch) | |
tree | 64af6659ee2669c4b77391281c051e2f4786f1cc /modules | |
parent | Rebuild (diff) | |
download | apache2-8f418b2e628fb3dcca4467f26baf702acdc0c9fc.tar.xz apache2-8f418b2e628fb3dcca4467f26baf702acdc0c9fc.zip |
change error handling for bad resp headers
- avoid looping between ap_die and the http filter
- remove the header that failed the check
- keep calling apr_table_do until our fn stops matching
This is still not great. We get the original body, a 500 status
code and status line.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1773285 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r-- | modules/http/http_filters.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index ce922ff8f4..a7a55223f2 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -632,6 +632,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, struct check_header_ctx { request_rec *r; int strict; + const char *badheader; }; /* check a single header, to be used with apr_table_do() */ @@ -657,6 +658,7 @@ static int check_header(void *arg, const char *name, const char *val) "Response header name '%s' contains invalid " "characters, aborting request", name); + ctx->badheader = name; return 0; } @@ -666,6 +668,7 @@ static int check_header(void *arg, const char *name, const char *val) "Response header '%s' value of '%s' contains invalid " "characters, aborting request", name, val); + ctx->badheader = name; return 0; } return 1; @@ -680,13 +683,21 @@ static APR_INLINE int check_headers(request_rec *r) struct check_header_ctx ctx; core_server_config *conf = ap_get_core_module_config(r->server->module_config); + int rv = 1; ctx.r = r; ctx.strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE); - if (!apr_table_do(check_header, &ctx, r->headers_out, NULL)) - return 0; /* problem has been logged by check_header() */ + ctx.badheader = NULL; - return 1; + while (!apr_table_do(check_header, &ctx, r->headers_out, NULL)){ + if (ctx.badheader) { + apr_table_unset(r->headers_out, ctx.badheader); + apr_table_unset(r->err_headers_out, ctx.badheader); + } + rv = 0; /* problem has been logged by check_header() */ + } + + return rv; } typedef struct header_struct { @@ -1249,8 +1260,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, } if (!check_headers(r)) { - ap_die(HTTP_INTERNAL_SERVER_ERROR, r); - return AP_FILTER_ERROR; + r->status = 500; } /* |