From: Mladen Turk Date: Thu, 6 Nov 2008 06:51:32 +0000 (+0000) Subject: Always send body (zero size at least) whenever C-L is present in the request X-Git-Tag: 2.2.11~97 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1716add30205c587e9bdaeb07f03b0bab146d5d9;p=thirdparty%2Fapache%2Fhttpd.git Always send body (zero size at least) whenever C-L is present in the request Backport r696614 from truk git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@711779 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 98961266a97..c038ac32f9b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,14 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.11 + *) mod_proxy_ajp: Fix wrongly formatted requests where client + sets Content-Length header, but doesn't provide a body. + Servlet container always expects that next packet is + body whenever C-L is present in the headers. This can lead + to wrong interpretation of the packets. In this case + send the empty body packet, so container can deal with + that. [Mladen Turk] + *) Worker MPM: Crosscheck that idle workers are still available before using them and thus preventing an overflow of the worker queue which causes a SegFault. PR 45605 [Denis Ustimenko ] diff --git a/STATUS b/STATUS index 2fb549fab1c..1b3686f1dac 100644 --- a/STATUS +++ b/STATUS @@ -129,15 +129,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK: http://people.apache.org/~tdonovan/diffs/windows_odbc_22x_dsw.patch +1: tdonovan, wrowe, mturk - * mod_proxy_ajp: Always send body (zero size at least) whenever C-L is - present in the request. - Trunk version of patch: - http://svn.apache.org/viewvc?rev=696614&view=rev - http://svn.apache.org/viewvc?rev=707027&view=rev - Backport version for 2.2.x of patch: - Trunk version of patch works - +1: rpluem, jim, mturk - * mod_proxy_ajp: Don't discard previously set cookies from the output headers. Trunk version of patch: diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index e6f9499d2d4..ed0cf51e026 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -116,6 +116,27 @@ static int is_idempotent(request_rec *r) } } +static apr_off_t get_content_length(request_rec * r) +{ + apr_off_t len = 0; + + if (r->clength > 0) { + return r->clength; + } + else if (r->main == NULL) { + const char *clp = apr_table_get(r->headers_in, "Content-Length"); + + if (clp) { + char *errp; + if (apr_strtoff(&len, clp, &errp, 10) || *errp || len < 0) { + len = 0; /* parse error */ + } + } + } + + return len; +} + /* * XXX: AJP Auto Flushing * @@ -166,6 +187,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, ap_get_module_config(r->server->module_config, &proxy_module); apr_size_t maxsize = AJP_MSG_BUFFER_SZ; int send_body = 0; + apr_off_t content_length = 0; if (psf->io_buffer_size_set) maxsize = psf->io_buffer_size; @@ -221,6 +243,8 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: request is chunked"); } else { + /* Get client provided Content-Length header */ + content_length = get_content_length(r); status = ap_get_brigade(r->input_filters, input_brigade, AP_MODE_READBYTES, APR_BLOCK_READ, maxsize - AJP_HEADER_SZ); @@ -277,6 +301,27 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, conn->worker->s->transferred += bufsiz; send_body = 1; } + else if (content_length > 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: read zero bytes, expecting" + " %" APR_OFF_T_FMT " bytes", + content_length); + status = ajp_send_data_msg(conn->sock, msg, 0); + if (status != APR_SUCCESS) { + /* We had a failure: Close connection to backend */ + conn->close++; + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: send failed to %pI (%s)", + conn->worker->cp->addr, + conn->worker->hostname); + return HTTP_INTERNAL_SERVER_ERROR; + } + else { + /* Client send zero bytes with C-L > 0 + */ + return HTTP_BAD_REQUEST; + } + } } /* read the response */