From a10a8937ac809ec26beef5beec1146338a37e553 Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Tue, 17 Sep 2013 18:37:18 +0000 Subject: [PATCH] RFC2616 issue git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1524161 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ docs/log-message-tags/next-number | 2 +- modules/http/http_filters.c | 25 ++++++++++++--------- server/protocol.c | 36 ++++++++++++++++++++++++++----- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index 5b82f041e4..6a81e556a0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + * core: Fix RFC2616 compliance issue with 'identity' transfer-encoding. + [Yann Ylavic , Jim Jagielski] + *) WinNT MPM: If ap_run_pre_connection() fails or sets c->aborted, don't save the socket for reuse by the next worker as if it were an APR_SO_DISCONNECTED socket. Restores 2.2 behavior. [Eric Covener] diff --git a/docs/log-message-tags/next-number b/docs/log-message-tags/next-number index 6a5bdca5ee..983711d6f2 100644 --- a/docs/log-message-tags/next-number +++ b/docs/log-message-tags/next-number @@ -1 +1 @@ -2536 +2540 diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index a4beb26bc9..f708e02a62 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -227,19 +227,24 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, if (!strcasecmp(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 encodings, is unsupported. - */ + /* RFC 2616 Section 4.4 states that if the message does + * include a non-identity transfer-coding, the Content-Length + * MUST be ignored. + */ + else if (lenp) { ap_log_rerror( - APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01585) "Unknown Transfer-Encoding: %s", tenc); - return APR_ENOTIMPL; + APLOG_MARK, APLOG_INFO, 0, f->r, + APLOGNO(01586) "Identity or Unknown Transfer-Encoding (%s); using Content-Length", tenc); + tenc = NULL; } else { - ap_log_rerror( - APLOG_MARK, APLOG_WARNING, 0, f->r, APLOGNO(01586) "Unknown Transfer-Encoding: %s; using Content-Length", tenc); - tenc = NULL; + /* Something that isn't in HTTP, unless some future + * edition defines new transfer encodings, is unsupported. + */ + ap_log_rerror( + APLOG_MARK, APLOG_INFO, 0, f->r, + APLOGNO(01585) "Unknown Transfer-Encoding: %s", tenc); + return APR_ENOTIMPL; } } if (lenp && !tenc) { diff --git a/server/protocol.c b/server/protocol.c index c1ecae705b..1a8aa44760 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -1091,6 +1091,8 @@ request_rec *ap_read_request(conn_rec *conn) } if (!r->assbackwards) { + const char *tenc, *clen; + ap_get_mime_headers_core(r, tmp_bb); if (r->status != HTTP_OK) { ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00567) @@ -1102,13 +1104,37 @@ request_rec *ap_read_request(conn_rec *conn) goto traceout; } - if (apr_table_get(r->headers_in, "Transfer-Encoding") - && apr_table_get(r->headers_in, "Content-Length")) { + if ((tenc = apr_table_get(r->headers_in, "Transfer-Encoding"))) { /* 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. */ - apr_table_unset(r->headers_in, "Content-Length"); + * ignored"; unless the former is "identity". So unset + * the one concerned here to prevent any confusion later. + */ + if ((clen = apr_table_get(r->headers_in, "Content-Length"))) { + if (strcasecmp(tenc, "chunked") == 0) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(2537) + "client sent both Transfer-Encoding (chunked)" + " and Content-Length; using TE"); + apr_table_unset(r->headers_in, "Content-Length"); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(2538) + "client sent identity or unknown Transfer-Encoding (%s);" + " using Content-Length", tenc); + apr_table_unset(r->headers_in, "Transfer-Encoding"); + } + } + else if (strcasecmp(tenc, "chunked") != 0) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(2539) + "client sent unknown Transfer-Encoding;" + " not implemented: %s", tenc); + r->status = HTTP_NOT_IMPLEMENTED; + 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); + goto traceout; + } } } else { -- 2.40.0