diff options
author | Eric Covener <covener@apache.org> | 2023-01-10 13:20:09 +0000 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2023-01-10 13:20:09 +0000 |
commit | 8b6d55f6a047acf62675e32606b037f5eea8ccc7 (patch) | |
tree | bb3a341cc111792e88c82c0e7b4135b3749cdf88 /modules | |
parent | 78a2d92b267b43e946599190cbac948904edf5b2 (diff) | |
download | httpd-8b6d55f6a047acf62675e32606b037f5eea8ccc7.tar.gz |
Merge r1906539 from trunk:
fail on bad header
Submitted By: covener
Reviewed By: covener, rpluem, gbechis
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1906541 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r-- | modules/proxy/mod_proxy_http.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index d74ae054ac..ec4e7fb06b 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -788,7 +788,7 @@ static void process_proxy_header(request_rec *r, proxy_dir_conf *c, * any sense at all, since we depend on buffer still containing * what was read by ap_getline() upon return. */ -static void ap_proxy_read_headers(request_rec *r, request_rec *rr, +static apr_status_t ap_proxy_read_headers(request_rec *r, request_rec *rr, char *buffer, int size, conn_rec *c, int *pread_len) { @@ -820,19 +820,26 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr, rc = ap_proxygetline(tmp_bb, buffer, size, rr, AP_GETLINE_FOLD | AP_GETLINE_NOSPC_EOL, &len); - if (len <= 0) - break; - if (APR_STATUS_IS_ENOSPC(rc)) { - /* The header could not fit in the provided buffer, warn. - * XXX: falls through with the truncated header, 5xx instead? - */ - int trunc = (len > 128 ? 128 : len) / 2; - ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10124) - "header size is over the limit allowed by " - "ResponseFieldSize (%d bytes). " - "Bad response header: '%.*s[...]%s'", - size, trunc, buffer, buffer + len - trunc); + if (rc != APR_SUCCESS) { + if (APR_STATUS_IS_ENOSPC(rc)) { + int trunc = (len > 128 ? 128 : len) / 2; + ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10124) + "header size is over the limit allowed by " + "ResponseFieldSize (%d bytes). " + "Bad response header: '%.*s[...]%s'", + size, trunc, buffer, buffer + len - trunc); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10404) + "Error reading headers from backend"); + } + r->headers_out = NULL; + return rc; + } + + if (len <= 0) { + break; } else { ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "%s", buffer); @@ -855,7 +862,7 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr, if (psc->badopt == bad_error) { /* Nope, it wasn't even an extra HTTP header. Give up. */ r->headers_out = NULL; - return; + return APR_EINVAL; } else if (psc->badopt == bad_body) { /* if we've already started loading headers_out, then @@ -869,13 +876,13 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr, "in headers returned by %s (%s)", r->uri, r->method); *pread_len = len; - return; + return APR_SUCCESS; } else { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01099) "No HTTP headers returned by %s (%s)", r->uri, r->method); - return; + return APR_SUCCESS; } } } @@ -905,6 +912,7 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr, process_proxy_header(r, dconf, buffer, value); saw_headers = 1; } + return APR_SUCCESS; } @@ -1218,10 +1226,10 @@ int ap_proxy_http_process_response(proxy_http_req_t *req) "Set-Cookie", NULL); /* shove the headers direct into r->headers_out */ - ap_proxy_read_headers(r, backend->r, buffer, response_field_size, - origin, &pread_len); + rc = ap_proxy_read_headers(r, backend->r, buffer, response_field_size, + origin, &pread_len); - if (r->headers_out == NULL) { + if (rc != APR_SUCCESS || r->headers_out == NULL) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01106) "bad HTTP/%d.%d header returned by %s (%s)", major, minor, r->uri, r->method); |