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);
> 
> 

Reply via email to