From: Rainer Jung Date: Thu, 8 Sep 2011 10:18:14 +0000 (+0000) Subject: mod_proxy_ajp: Respect "reuse" flag in X-Git-Tag: 2.2.21~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f09b8bb73edc24040340c7d167a89f4afb4f929a;p=thirdparty%2Fapache%2Fhttpd.git mod_proxy_ajp: Respect "reuse" flag in END_REPONSE packets. Backport of r1152379 from trunk. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1166606 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index a181cb1f172..d8948175f62 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,9 @@ Changes with Apache 2.2.21 before returning the entire resource, with a default limit of 200. [Eric Covener] + *) mod_proxy_ajp: Respect "reuse" flag in END_REPONSE packets. + [Rainer Jung] + Changes with Apache 2.2.20 *) SECURITY: CVE-2011-3192 (cve.mitre.org) diff --git a/STATUS b/STATUS index c2f0420a2e4..884b42ddbeb 100644 --- a/STATUS +++ b/STATUS @@ -102,11 +102,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: (Accept-Range: changeset in separate proposal below) +1: covener, wrowe, rpluem - * mod_proxy_ajp: Respect "reuse" flag in END_RESPONSE - Trunk patch: http://svn.apache.org/viewvc?rev=1152379&view=rev - 2.2.x patch: http://people.apache.org/~rjung/patches/mod_proxy_ajp_reuse_flag.patch - +1: rjung, jim, jfclere - * mod_proxy_ajp: Ignore flushing if headers have not been sent. Trunk patch: http://svn.apache.org/viewvc?rev=1153531&view=rev 2.2.x patch: http://people.apache.org/~rpluem/patches/51608.diff diff --git a/modules/proxy/ajp.h b/modules/proxy/ajp.h index 8327e8d454c..eb039705345 100644 --- a/modules/proxy/ajp.h +++ b/modules/proxy/ajp.h @@ -482,6 +482,17 @@ apr_status_t ajp_parse_data(request_rec *r, ajp_msg_t *msg, apr_uint16_t *len, char **ptr); +/** + * Check the reuse flag in CMD_AJP13_END_RESPONSE + * @param r current request + * @param msg AJP message + * @param reuse returned reuse flag + * @return APR_SUCCESS or error + */ +apr_status_t ajp_parse_reuse(request_rec *r, ajp_msg_t *msg, + apr_byte_t *reuse); + + /** * Handle the CPING/CPONG messages * @param sock backend socket diff --git a/modules/proxy/ajp_header.c b/modules/proxy/ajp_header.c index 90a5a074d94..5aed7d2912b 100644 --- a/modules/proxy/ajp_header.c +++ b/modules/proxy/ajp_header.c @@ -714,7 +714,8 @@ apr_status_t ajp_parse_header(request_rec *r, proxy_dir_conf *conf, } if (result != CMD_AJP13_SEND_HEADERS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, - "ajp_parse_headers: wrong type %02x expecting 0x04", result); + "ajp_parse_headers: wrong type 0x%02x expecting 0x%02x", + result, CMD_AJP13_SEND_HEADERS); return AJP_EBAD_HEADER; } return ajp_unmarshal_response(msg, r, conf); @@ -736,7 +737,8 @@ apr_status_t ajp_parse_data(request_rec *r, ajp_msg_t *msg, } if (result != CMD_AJP13_SEND_BODY_CHUNK) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, - "ajp_parse_data: wrong type %02x expecting 0x03", result); + "ajp_parse_data: wrong type 0x%02x expecting 0x%02x", + result, CMD_AJP13_SEND_BODY_CHUNK); return AJP_EBAD_HEADER; } rc = ajp_msg_get_uint16(msg, len); @@ -764,6 +766,28 @@ apr_status_t ajp_parse_data(request_rec *r, ajp_msg_t *msg, return APR_SUCCESS; } +/* Check the reuse flag in CMD_AJP13_END_RESPONSE */ +apr_status_t ajp_parse_reuse(request_rec *r, ajp_msg_t *msg, + apr_byte_t *reuse) +{ + apr_byte_t result; + apr_status_t rc; + + rc = ajp_msg_get_uint8(msg, &result); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_parse_reuse: ajp_msg_get_byte failed"); + return rc; + } + if (result != CMD_AJP13_END_RESPONSE) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_parse_reuse: wrong type 0x%02x expecting 0x%02x", + result, CMD_AJP13_END_RESPONSE); + return AJP_EBAD_HEADER; + } + return ajp_msg_get_uint8(msg, reuse); +} + /* * Allocate a msg to send data */ diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index ccb0783fc52..1b1fdf650e2 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -174,6 +174,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, char *buff; char *send_body_chunk_buff; apr_uint16_t size; + apr_byte_t conn_reuse = 0; const char *tenc; int havebody = 1; int output_failed = 0; @@ -485,6 +486,10 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, } break; case CMD_AJP13_END_RESPONSE: + status = ajp_parse_reuse(r, conn->data, &conn_reuse); + if (status != APR_SUCCESS) { + backend_failed = 1; + } e = apr_bucket_eos_create(r->connection->bucket_alloc); APR_BRIGADE_INSERT_TAIL(output_brigade, e); if (ap_pass_brigade(r->output_filters, @@ -564,6 +569,10 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, rv = DONE; } } + else if (!conn_reuse) { + /* Our backend signalled connection close */ + conn->close++; + } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: got response from %pI (%s)",