This looks nice for HTTP/1.1, but what about other protocols? Do I read it correctly that any pending data downstream will reopen the connection?
> Am 27.06.2016 um 10:00 schrieb yla...@apache.org: > > Author: ylavic > Date: Mon Jun 27 08:00:30 2016 > New Revision: 1750301 > > URL: http://svn.apache.org/viewvc?rev=1750301&view=rev > Log: > mod_proxy: don't reuse backend connections with data available before the > request is sent. PR 57832. > > Modified: > httpd/httpd/trunk/modules/proxy/mod_proxy.h > httpd/httpd/trunk/modules/proxy/proxy_util.c > > Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.h > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.h?rev=1750301&r1=1750300&r2=1750301&view=diff > ============================================================================== > --- httpd/httpd/trunk/modules/proxy/mod_proxy.h (original) > +++ httpd/httpd/trunk/modules/proxy/mod_proxy.h Mon Jun 27 08:00:30 2016 > @@ -271,6 +271,7 @@ typedef struct { > unsigned int inreslist:1; /* connection in apr_reslist? */ > const char *uds_path; /* Unix domain socket path */ > const char *ssl_hostname;/* Hostname (SNI) in use by SSL connection */ > + apr_bucket_brigade *tmp_bb; > } proxy_conn_rec; > > typedef struct { > > Modified: httpd/httpd/trunk/modules/proxy/proxy_util.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/proxy_util.c?rev=1750301&r1=1750300&r2=1750301&view=diff > ============================================================================== > --- httpd/httpd/trunk/modules/proxy/proxy_util.c (original) > +++ httpd/httpd/trunk/modules/proxy/proxy_util.c Mon Jun 27 08:00:30 2016 > @@ -2487,7 +2487,7 @@ ap_proxy_determine_connection(apr_pool_t > #endif > > #if USE_ALTERNATE_IS_CONNECTED && defined(APR_MSG_PEEK) > -PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket) > +static int get_socket_connected(apr_socket_t *socket) > { > apr_pollfd_t pfds[1]; > apr_status_t status; > @@ -2514,7 +2514,7 @@ PROXY_DECLARE(int) ap_proxy_is_socket_co > status = apr_socket_recvfrom(&unused, socket, APR_MSG_PEEK, > &buf[0], &len); > if (status == APR_SUCCESS && len) > - return 1; > + return 2; > else > return 0; > } > @@ -2525,7 +2525,7 @@ PROXY_DECLARE(int) ap_proxy_is_socket_co > > } > #else > -PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket) > +static int is_socket_connnected(apr_socket_t *socket) > > { > apr_size_t buffer_len = 1; > @@ -2544,12 +2544,19 @@ PROXY_DECLARE(int) ap_proxy_is_socket_co > || APR_STATUS_IS_ECONNRESET(socket_status)) { > return 0; > } > + else if (status == APR_SUCCESS && buffer_len) { > + return 2; > + } > else { > return 1; > } > } > #endif /* USE_ALTERNATE_IS_CONNECTED */ > > +PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket) > +{ > + return get_socket_connected(socket) != 0; > +} > > /* > * Send a HTTP CONNECT request to a forward proxy. > @@ -2716,7 +2723,35 @@ PROXY_DECLARE(int) ap_proxy_connect_back > (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); > > if (conn->sock) { > - if (!(connected = ap_proxy_is_socket_connected(conn->sock))) { > + conn_rec *c = conn->connection; > + if (!c) { > + connected = get_socket_connected(conn->sock); > + } > + else { > + if (conn->tmp_bb == NULL) { > + conn->tmp_bb = apr_brigade_create(c->pool, c->bucket_alloc); > + } > + rv = ap_get_brigade(c->input_filters, conn->tmp_bb, > + AP_MODE_SPECULATIVE, APR_NONBLOCK_READ, 1); > + if (rv == APR_SUCCESS) { > + apr_off_t len = 0; > + apr_brigade_length(conn->tmp_bb, 0, &len); > + if (len) { > + connected = 2; > + } > + else { > + connected = 1; > + } > + } > + else if (APR_STATUS_IS_EAGAIN(rv)) { > + connected = 1; > + } > + else { > + connected = 0; > + } > + apr_brigade_cleanup(conn->tmp_bb); > + } > + if (connected != 1) { > /* This clears conn->scpool (and associated data), so backup and > * restore any ssl_hostname for this connection set earlier by > * ap_proxy_determine_connection(). > @@ -2728,9 +2763,17 @@ PROXY_DECLARE(int) ap_proxy_connect_back > } > > socket_cleanup(conn); > - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00951) > - "%s: backend socket is disconnected.", > - proxy_function); > + if (!connected) { > + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00951) > + "%s: backend socket is disconnected.", > + proxy_function); > + } > + else { > + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO() > + "%s: reusable backend connection is not empty: " > + "forcibly closed", proxy_function); > + connected = 0; > + } > > if (ssl_hostname[0]) { > conn->ssl_hostname = apr_pstrdup(conn->scpool, ssl_hostname); > >