From a891aa59a77e10fd8b7fb67b2c36da9697fc699c Mon Sep 17 00:00:00 2001 From: Ruediger Pluem Date: Wed, 12 Mar 2014 12:18:51 +0000 Subject: [PATCH] Merge r1524192, r1524770, r1527925 from trunk: Update rationale draft-ietf-httpbis-p1-messaging-23 fixes regarding interactions between TE and content-length in the same req/resp. PR 55616 (add missing APLOGNO), part 1 Reviewed by: rpluem, ylavic, wrowe git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1576708 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ STATUS | 9 --------- modules/http/http_filters.c | 32 ++++++++++++++++++++------------ server/protocol.c | 36 ++++++++++++++++++++++++++++++------ 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index c64ba375405..b0f67ad6218 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.27 + *) core: draft-ietf-httpbis-p1-messaging-23 corrections regarding + TE/CL conflicts. [Yann Ylavic , Jim Jagielski] + *) mod_proxy_http: Core dumped under high load. PR 50335. [Jan Kaluza ] diff --git a/STATUS b/STATUS index 15bcb0d25ea..ccb79bc35bd 100644 --- a/STATUS +++ b/STATUS @@ -97,15 +97,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - - *) core: draft-ietf-httpbis-p1-messaging-23 corrections regarding - TE/CL conflicts. [Yann Ylavic , Jim Jagielski] - trunk patch: https://svn.apache.org/viewvc?view=revision&revision=1524192 - https://svn.apache.org/viewvc?view=revision&revision=1524770 - N/A: https://svn.apache.org/viewvc?view=revision&revision=1527925 - 2.2.x patch (plus CHANGES entry above): - http://people.apache.org/~wrowe/httpd-2.2-r1524192-r1524770-TE-CL.patch - +1: rpluem, ylavic, wrowe * back port some bugfix that have already been included in 2.4.x. CHANGES has been upgraded with the corresponding entries. diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index 1aed70b29c0..8b6e371c474 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -251,25 +251,33 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, lenp = apr_table_get(f->r->headers_in, "Content-Length"); if (tenc) { - if (!strcasecmp(tenc, "chunked")) { + if (strcasecmp(tenc, "chunked") == 0 /* fast path */ + || ap_find_last_token(f->r->pool, tenc, "chunked")) { ctx->state = BODY_CHUNK; } - /* test lenp, because it gives another case we can handle */ - else if (!lenp) { - /* Something that isn't in HTTP, unless some future - * edition defines new transfer ecodings, is unsupported. + else if (f->r->proxyreq == PROXYREQ_RESPONSE) { + /* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23 + * Section 3.3.3.3: "If a Transfer-Encoding header field is + * present in a response and the chunked transfer coding is not + * the final encoding, the message body length is determined by + * reading the connection until it is closed by the server." */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, - "Unknown Transfer-Encoding: %s", tenc); - return bail_out_on_error(ctx, f, HTTP_NOT_IMPLEMENTED); + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, + "Unknown Transfer-Encoding: %s; " + "using read-until-close", tenc); + tenc = NULL; } else { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, f->r, - "Unknown Transfer-Encoding: %s; using Content-Length", tenc); - tenc = NULL; + /* Something that isn't a HTTP request, unless some future + * edition defines new transfer encodings, is unsupported. + */ + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, + "Unknown Transfer-Encoding: %s", tenc); + return bail_out_on_error(ctx, f, HTTP_NOT_IMPLEMENTED); } + lenp = NULL; } - if (lenp && !tenc) { + if (lenp) { char *endstr; ctx->state = BODY_LENGTH; diff --git a/server/protocol.c b/server/protocol.c index 796ae587baa..ac03082d302 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -953,6 +953,8 @@ request_rec *ap_read_request(conn_rec *conn) } if (!r->assbackwards) { + const char *tenc; + ap_get_mime_headers_core(r, tmp_bb); if (r->status != HTTP_OK) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, @@ -964,12 +966,34 @@ request_rec *ap_read_request(conn_rec *conn) return r; } - if (apr_table_get(r->headers_in, "Transfer-Encoding") - && apr_table_get(r->headers_in, "Content-Length")) { - /* 2616 section 4.4, point 3: "if both Transfer-Encoding - * and Content-Length are received, the latter MUST be - * ignored"; so unset it here to prevent any confusion - * later. */ + tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); + if (tenc) { + /* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23 + * Section 3.3.3.3: "If a Transfer-Encoding header field is + * present in a request and the chunked transfer coding is not + * the final encoding ...; the server MUST respond with the 400 + * (Bad Request) status code and then close the connection". + */ + if (!(strcasecmp(tenc, "chunked") == 0 /* fast path */ + || ap_find_last_token(r->pool, tenc, "chunked"))) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, + "client sent unknown Transfer-Encoding " + "(%s): %s", tenc, r->uri); + r->status = HTTP_BAD_REQUEST; + conn->keepalive = AP_CONN_CLOSE; + ap_send_error_response(r, 0); + ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); + ap_run_log_transaction(r); + apr_brigade_destroy(tmp_bb); + return r; + } + + /* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23 + * Section 3.3.3.3: "If a message is received with both a + * Transfer-Encoding and a Content-Length header field, the + * Transfer-Encoding overrides the Content-Length. ... A sender + * MUST remove the received Content-Length field". + */ apr_table_unset(r->headers_in, "Content-Length"); } } -- 2.47.2