From: Yann Ylavic Date: Thu, 26 Mar 2015 09:07:54 +0000 (+0000) Subject: mod_proxy_wstunnel: Avoid an empty response by failing with 502 (Bad Gateway) X-Git-Tag: 2.5.0-alpha~3352 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=94610cc166174ec8356862165b7e5dcf97affcc9;p=apache mod_proxy_wstunnel: Avoid an empty response by failing with 502 (Bad Gateway) when no response is ever received from the backend. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1669299 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 01b0b4df9d..6646e29697 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_proxy_wstunnel: Avoid an empty response by failing with 502 (Bad + Gateway) when no response is ever received from the backend. + [Jan Kaluza] + *) core_filters: restore/disable TCP_NOPUSH option after non-blocking sendfile. [Yann Ylavic] diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c index 5f57059a90..11bc02d99b 100644 --- a/modules/proxy/mod_proxy_wstunnel.c +++ b/modules/proxy/mod_proxy_wstunnel.c @@ -36,8 +36,10 @@ typedef struct ws_baton_t { char *scheme; /* required to release the proxy connection */ } ws_baton_t; -static apr_status_t proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o, - apr_bucket_brigade *bb, char *name); +static apr_status_t proxy_wstunnel_transfer(request_rec *r, + conn_rec *c_i, conn_rec *c_o, + apr_bucket_brigade *bb, + const char *name, int *sent); static void proxy_wstunnel_callback(void *b); static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout, int try_async) { @@ -53,7 +55,7 @@ static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout, int try_as apr_socket_t *client_socket = baton->client_soc; apr_status_t rv; apr_bucket_brigade *bb = baton->bb; - int done = 0; + int done = 0, replied = 0; do { rv = apr_pollset_poll(pollset, timeout, &pollcnt, &signalled); @@ -87,8 +89,8 @@ static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout, int try_as if (pollevent & (APR_POLLIN | APR_POLLHUP)) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02446) "sock was readable"); - done |= proxy_wstunnel_transfer(r, backconn, c, bb, - "sock") != APR_SUCCESS; + done |= proxy_wstunnel_transfer(r, backconn, c, bb, "sock", + NULL) != APR_SUCCESS; } else if (pollevent & APR_POLLERR) { ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447) @@ -107,8 +109,8 @@ static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout, int try_as if (pollevent & (APR_POLLIN | APR_POLLHUP)) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02448) "client was readable"); - done |= proxy_wstunnel_transfer(r, c, backconn, bb, - "client") != APR_SUCCESS; + done |= proxy_wstunnel_transfer(r, c, backconn, bb, "client", + &replied) != APR_SUCCESS; } else if (pollevent & APR_POLLERR) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02607) @@ -134,7 +136,12 @@ static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout, int try_as ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "finished with poll() - cleaning up"); - return OK; + if (!replied) { + return HTTP_BAD_GATEWAY; + } + else { + return OK; + } } static void proxy_wstunnel_finish(ws_baton_t *baton) { @@ -261,8 +268,10 @@ static int proxy_wstunnel_canon(request_rec *r, char *url) } -static apr_status_t proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o, - apr_bucket_brigade *bb, char *name) +static apr_status_t proxy_wstunnel_transfer(request_rec *r, + conn_rec *c_i, conn_rec *c_o, + apr_bucket_brigade *bb, + const char *name, int *sent) { apr_status_t rv; #ifdef DEBUGGING @@ -287,6 +296,9 @@ static apr_status_t proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_ "read %" APR_OFF_T_FMT " bytes from %s", len, name); #endif + if (sent) { + *sent = 1; + } rv = ap_pass_brigade(c_o->output_filters, bb); if (rv == APR_SUCCESS) { ap_fflush(c_o->output_filters, bb);