From: Eric Covener Date: Sun, 13 Apr 2014 17:21:50 +0000 (+0000) Subject: cleanup wstunnel error handling X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63ad2361f7849ceee393d7d9348d51a055feee5c;p=thirdparty%2Fapache%2Fhttpd.git cleanup wstunnel error handling Submitted By: covener, ylavic, Edward Lu Commited By: covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1587053 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 83ba0d121de..a3fb8c64a5b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_proxy_wstunnel: Don't issue AH02447 and log a 500 on routine + hangups from websockets origin servers. PR 56299 + [Yann Ylavic, Edward Lu , Eric Covener] + *) mod_proxy_wstunnel: Don't pool backend websockets connections, because we need to handshake every time. PR 55890. [Eric Covener] diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c index 5b64f192b3e..8dcd4e72531 100644 --- a/modules/proxy/mod_proxy_wstunnel.c +++ b/modules/proxy/mod_proxy_wstunnel.c @@ -34,7 +34,6 @@ static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o, apr_bucket_brigade *bb, char *name); static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout) { - int client_error = 0; request_rec *r = baton->r; conn_rec *c = r->connection; proxy_conn_rec *conn = baton->proxy_connrec; @@ -72,38 +71,34 @@ static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout) { if (cur->desc.s == sock) { pollevent = cur->rtnevents; - if (pollevent & APR_POLLIN) { + if (pollevent & (APR_POLLIN | APR_POLLHUP)) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02446) "sock was readable"); rv = proxy_wstunnel_transfer(r, backconn, c, bb, "sock"); } - else if ((pollevent & APR_POLLERR) - || (pollevent & APR_POLLHUP)) { + else if (pollevent & APR_POLLERR) { rv = APR_EPIPE; ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447) - "err/hup on backconn"); + "error on backconn"); } else { rv = APR_EGENERAL; ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02605) "unknown event on backconn %d", pollevent); } - if (rv != APR_SUCCESS) - client_error = 1; } else if (cur->desc.s == client_socket) { pollevent = cur->rtnevents; - if (pollevent & APR_POLLIN) { + if (pollevent & (APR_POLLIN | APR_POLLHUP)) { ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02448) "client was readable"); rv = proxy_wstunnel_transfer(r, c, backconn, bb, "client"); } - else if ((pollevent & APR_POLLERR) - || (pollevent & APR_POLLHUP)) { + else if (pollevent & APR_POLLERR) { rv = APR_EPIPE; c->aborted = 1; ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02607) - "err/hup on client conn"); + "error on client conn"); } else { rv = APR_EGENERAL; @@ -126,9 +121,6 @@ static int proxy_wstunnel_pump(ws_baton_t *baton, apr_time_t timeout) { ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "finished with poll() - cleaning up"); - if (client_error) { - return HTTP_INTERNAL_SERVER_ERROR; - } return OK; } @@ -239,10 +231,12 @@ static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o, rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES, APR_NONBLOCK_READ, AP_IOBUFSIZE); if (rv == APR_SUCCESS) { - if (c_o->aborted) + if (c_o->aborted) { return APR_EPIPE; - if (APR_BRIGADE_EMPTY(bb)) + } + if (APR_BRIGADE_EMPTY(bb)) { break; + } #ifdef DEBUGGING len = -1; apr_brigade_length(bb, 0, &len); @@ -359,7 +353,7 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r, pollfd.p = p; pollfd.desc_type = APR_POLL_SOCKET; - pollfd.reqevents = APR_POLLIN; + pollfd.reqevents = APR_POLLIN | APR_POLLHUP; pollfd.desc.s = sock; pollfd.client_data = NULL; apr_pollset_add(pollset, &pollfd); @@ -374,6 +368,9 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r, r->proto_output_filters = c->output_filters; r->input_filters = c->input_filters; r->proto_input_filters = c->input_filters; + /* This handler should take care of the entire connection; make it so that + * nothing else is attempted on the connection after returning. */ + c->keepalive = AP_CONN_CLOSE; baton->r = r;