Thanks, here is the latest patch.
Note I changed :
-
conn->keepalive = AP_CONN_CLOSE; according to Rüdiger's remark,
- APR_ENOTIMPL => APR_EGENERAL so that ap_map_http_request_error() returns
400 and not 501,
- APLOG_WARNING => APLOG_INFO when "using closed connection".
but didn't changed :
- the APLOGNO(01586) of an existing but modified log, what to do in this
case?
Regards,
Yann.
<PATCH>
Index: server/protocol.c
===================================================================
--- server/protocol.c (revision 1524578)
+++ server/protocol.c (working copy)
@@ -1091,6 +1091,8 @@
}
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_INFO, 0, r, APLOGNO(00567)
@@ -1102,14 +1104,34 @@
goto traceout;
}
- if (apr_table_get(r->headers_in, "Transfer-Encoding")
- && apr_table_get(r->headers_in, "Content-Length")) {
- /*
http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23#page-31
- * "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"
+ 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, APLOGNO()
+ "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);
+ goto traceout;
+ }
+
+ /*
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");
}
}
Index: modules/http/http_filters.c
===================================================================
--- modules/http/http_filters.c (revision 1524578)
+++ modules/http/http_filters.c (working copy)
@@ -224,25 +224,32 @@
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 encodings, 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_INFO, 0, f->r, APLOGNO(01585)
"Unknown Transfer-Encoding: %s", tenc);
- return APR_ENOTIMPL;
+ APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01586)
"Unknown Transfer-Encoding: %s; using closed connection", tenc);
+ tenc = NULL;
}
else {
+ /* Something that isn't a HTTP request, unless some future
+ * edition defines new transfer encodings, is unsupported.
+ */
ap_log_rerror(
- APLOG_MARK, APLOG_WARNING, 0, f->r, APLOGNO(01586)
"Unknown Transfer-Encoding: %s; using Content-Length", tenc);
- tenc = NULL;
+ APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01585)
"Unknown Transfer-Encoding: %s", tenc);
+ return APR_EGENERAL;
}
+ lenp = NULL;
}
- if (lenp && !tenc) {
+ else if (lenp) {
char *endstr;
ctx->state = BODY_LENGTH;
</PATCH>
trunk-draft_ietf_httpbis_p1_messaging_23_section_3.3.3.3.patch
Description: Binary data
