From a7becdbf75d2e6882e3c8cf5bbbd3e92d245b9fe Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Fri, 31 Oct 2014 00:07:06 +0000 Subject: [PATCH] mod_proxy_connect: Don't issue AH02447 on sockets hangups, let the read determine whether it is a normal close or a real error. PR 57168. Abort the client or backend connection on polling errors, but don't forcibly abort the client side at the end (the core filters will do that otherwise when necessary), so that lingering close and SSL shutdown can occur on normal close. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1635645 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ modules/proxy/mod_proxy_connect.c | 30 ++++++++++++++++-------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 35bb47bdf6..a238ebdbb3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_proxy_connect: Don't issue AH02447 on sockets hangups, let the read + determine whether it is a normal close or a real error. PR 57168. [Yann + Ylavic] + *) mod_proxy_wstunnel: abort backend connection on polling error to avoid further processing. [Yann Ylavic] diff --git a/modules/proxy/mod_proxy_connect.c b/modules/proxy/mod_proxy_connect.c index 1d3e41613d..08bb0f4a49 100644 --- a/modules/proxy/mod_proxy_connect.c +++ b/modules/proxy/mod_proxy_connect.c @@ -210,7 +210,6 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, char buffer[HUGE_STRING_LEN]; apr_socket_t *client_socket = ap_get_conn_socket(c); int failed, rc; - int client_error = 0; apr_pollset_t *pollset; apr_pollfd_t pollfd; const apr_pollfd_t *signalled; @@ -320,7 +319,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, /* Add client side to the poll */ pollfd.p = r->pool; pollfd.desc_type = APR_POLL_SOCKET; - pollfd.reqevents = APR_POLLIN; + pollfd.reqevents = APR_POLLIN | APR_POLLHUP; pollfd.desc.s = client_socket; pollfd.client_data = NULL; apr_pollset_add(pollset, &pollfd); @@ -434,31 +433,35 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, if (cur->desc.s == sock) { pollevent = cur->rtnevents; - if (pollevent & APR_POLLIN) { + if (pollevent & (APR_POLLIN | APR_POLLHUP)) { #ifdef DEBUGGING ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01025) "sock was readable"); #endif rv = proxy_connect_transfer(r, backconn, c, bb, "sock"); - } - else if ((pollevent & APR_POLLERR) - || (pollevent & APR_POLLHUP)) { - rv = APR_EPIPE; - ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026) - "err/hup on backconn"); } - if (rv != APR_SUCCESS) - client_error = 1; + else if (pollevent & APR_POLLERR) { + rv = APR_EPIPE; + backconn->aborted = 1; + ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026) + "err on backconn"); + } } else if (cur->desc.s == client_socket) { pollevent = cur->rtnevents; - if (pollevent & APR_POLLIN) { + if (pollevent & (APR_POLLIN | APR_POLLHUP)) { #ifdef DEBUGGING ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01027) "client was readable"); #endif rv = proxy_connect_transfer(r, c, backconn, bb, "client"); } + else if (pollevent & APR_POLLERR) { + rv = APR_EPIPE; + c->aborted = 1; + ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(01026) + "err on client"); + } } else { rv = APR_EBADF; @@ -481,12 +484,11 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, * Close the socket and clean up */ - if (client_error) + if (backconn->aborted) apr_socket_close(sock); else ap_lingering_close(backconn); - c->aborted = 1; c->keepalive = AP_CONN_CLOSE; return OK; -- 2.40.0