]> granicus.if.org Git - apache/commitdiff
mod_proxy_wstunnel: Avoid an empty response by failing with 502 (Bad Gateway)
authorYann Ylavic <ylavic@apache.org>
Thu, 26 Mar 2015 09:07:54 +0000 (09:07 +0000)
committerYann Ylavic <ylavic@apache.org>
Thu, 26 Mar 2015 09:07:54 +0000 (09:07 +0000)
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

CHANGES
modules/proxy/mod_proxy_wstunnel.c

diff --git a/CHANGES b/CHANGES
index 01b0b4df9d88ce0d6d9e98dbadea0b45a305ffbe..6646e29697d46e5deb5ee4b1d85dbbf5d0a169a9 100644 (file)
--- 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]
 
index 5f57059a9005cb6392fa70efdebd9f8203ca570e..11bc02d99b47640a41a812970292c369b50c8ac9 100644 (file)
@@ -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);