Doesn't this depend on:
trunk patch: http://svn.apache.org/r1656259
http://svn.apache.org/r1656359 (CHANGES entry)
which, in STATUS, is tagged as still being worked?
> On Jun 27, 2016, at 4:23 AM, Stefan Eissing <[email protected]> wrote:
>
> 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 [email protected]:
>>
>> 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);
>>
>>
>