]> granicus.if.org Git - apache/commitdiff
mod_proxy_connect: Don't issue AH02447 on sockets hangups, let the read
authorYann Ylavic <ylavic@apache.org>
Fri, 31 Oct 2014 00:07:06 +0000 (00:07 +0000)
committerYann Ylavic <ylavic@apache.org>
Fri, 31 Oct 2014 00:07:06 +0000 (00:07 +0000)
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
modules/proxy/mod_proxy_connect.c

diff --git a/CHANGES b/CHANGES
index 35bb47bdf645209b66dfa5d29f195ed288cfc54d..a238ebdbb3891c96a9657b4e52f653d4d02181ec 100644 (file)
--- 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]
 
index 1d3e41613d018c9d65264719ea9c2dfb4309660d..08bb0f4a4968a5ec20603be3495d7947f649ea0a 100644 (file)
@@ -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;