From: Ruediger Pluem Date: Sat, 17 May 2008 19:47:38 +0000 (+0000) Subject: Merge r645813 from trunk: X-Git-Tag: 2.2.9~152 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e8c308735a870c7a0afd098814dc13d461d8bac;p=thirdparty%2Fapache%2Fhttpd.git Merge r645813 from trunk: * In the case that we fail to read the response line from the backend and if we are a reverse proxy request shutdown the connection WITHOUT ANY response to trigger a retry by the client if allowed (as for idempotent requests). BUT currently we should not do this if the request is the first request on a keepalive connection as browsers like seamonkey only display an empty page in this case and do not do a retry. Related to PR 37770 Submitted by: rpluem Reviewed by: rpluem, jim, fielding git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@657443 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index e9dc95f3daf..b057d26990d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.9 + *) mod_proxy: Trigger a retry by the client in the case we fail to read the + response line from the backend by closing the connection to the client. + PR 37770 [Ruediger Pluem] + *) gen_test_char: add double-quote to the list of T_HTTP_TOKEN_STOP. PR 9727 [Ville Skytt ] diff --git a/STATUS b/STATUS index b5639f1c90e..dcfe18261db 100644 --- a/STATUS +++ b/STATUS @@ -90,16 +90,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_proxy: In the case that we fail to read the response line - from the backend and if we are a reverse proxy request, shutdown - the connection WITHOUT ANY response to trigger a retry by the client - if allowed (as for idempotent requests). - Trunk version of patch: - http://svn.apache.org/viewvc?view=rev&revision=645813 - Backport version for 2.2.x of patch: - Trunk version works - +1: rpluem, jim, fielding - * mod_ssl: Fix a memory leak with connections that have zlib compression turned on. PR 44975 [Joe Orton, Amund Elstad , Dr Stephen Henson ] diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index 83e8fb34328..2a8761c7764 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -39,6 +39,7 @@ #include "http_main.h" #include "http_request.h" #include "http_vhost.h" +#include "http_connection.h" #include "http_log.h" /* For errors detected in basic auth common * support code... */ #include "apr_date.h" /* For apr_date_parse_http and APR_DATE_BAD */ @@ -1091,6 +1092,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, header_struct h; header_filter_ctx *ctx = f->ctx; const char *ctype; + ap_bucket_error *eb = NULL; AP_DEBUG_ASSERT(!r->main); @@ -1108,12 +1110,22 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, e != APR_BRIGADE_SENTINEL(b); e = APR_BUCKET_NEXT(e)) { - if (AP_BUCKET_IS_ERROR(e)) { - ap_bucket_error *eb = e->data; - - ap_die(eb->status, r); - return AP_FILTER_ERROR; + if (AP_BUCKET_IS_ERROR(e) && !eb) { + eb = e->data; + continue; } + /* + * If we see an EOC bucket it is a signal that we should get out + * of the way doing nothing. + */ + if (AP_BUCKET_IS_EOC(e)) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, b); + } + } + if (eb) { + ap_die(eb->status, r); + return AP_FILTER_ERROR; } if (r->assbackwards) { diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c index cc490de5873..5356f161e16 100644 --- a/modules/proxy/mod_proxy_http.c +++ b/modules/proxy/mod_proxy_http.c @@ -1365,6 +1365,38 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "proxy: error reading status line from remote " "server %s", backend->hostname); + /* + * If we are a reverse proxy request shutdown the connection + * WITHOUT ANY response to trigger a retry by the client + * if allowed (as for idempotent requests). + * BUT currently we should not do this if the request is the + * first request on a keepalive connection as browsers like + * seamonkey only display an empty page in this case and do + * not do a retry. + */ + if (r->proxyreq == PROXYREQ_REVERSE && c->keepalives) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "proxy: Closing connection to client because" + " reading from backend server %s failed. Number" + " of keepalives %i", backend->hostname, + c->keepalives); + ap_proxy_backend_broke(r, bb); + /* + * Add an EOC bucket to signal the ap_http_header_filter + * that it should get out of our way + */ + e = ap_bucket_eoc_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + ap_pass_brigade(r->output_filters, bb); + /* Need to return OK to avoid sending an error message */ + return OK; + } + else if (!c->keepalives) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "proxy: NOT Closing connection to client" + " although reading from backend server %s" + " failed.", backend->hostname); + } return ap_proxyerror(r, HTTP_BAD_GATEWAY, "Error reading from remote server"); }