diff --git a/docs/manual/mod/mod_proxy_wstunnel.html.en b/docs/manual/mod/mod_proxy_wstunnel.html.en
index 9f2c120..61ff7de 100644
--- a/docs/manual/mod/mod_proxy_wstunnel.html.en
+++ b/docs/manual/mod/mod_proxy_wstunnel.html.en
@@ -83,6 +83,7 @@ in the response Upgrade
Upgrade
WebSocket requests as in httpd 2.4.46 and earlier.
Description: | Sets the maximum amount of time to wait for data on the websockets tunnel |
---|---|
Syntax: | ProxyWebsocketIdleTimeout num[ms] |
Default: | ProxyWebsocketIdleTimeout 0 |
Context: | server config, virtual host |
Status: | Extension |
Module: | mod_proxy_wstunnel |
This directive imposes a maximum amount of time for the tunnel to be + left open while idle. The timeout is considered in seconds by default, but + it is possible to increase the time resolution to milliseconds + adding the ms suffix.
+ +Available Languages: en | diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c index bcbba42..c29ded1 100644 --- a/modules/proxy/mod_proxy_wstunnel.c +++ b/modules/proxy/mod_proxy_wstunnel.c @@ -22,6 +22,7 @@ module AP_MODULE_DECLARE_DATA proxy_wstunnel_module; typedef struct { unsigned int fallback_to_proxy_http :1, fallback_to_proxy_http_set :1; + apr_time_t idle_timeout; } proxyws_dir_conf; static int can_fallback_to_proxy_http; @@ -152,6 +153,8 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r, conn_rec *c = r->connection; apr_socket_t *sock = conn->sock; conn_rec *backconn = conn->connection; + proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config, + &proxy_wstunnel_module); char *buf; apr_bucket_brigade *header_brigade; apr_bucket *e; @@ -229,10 +232,13 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r, c->keepalive = AP_CONN_CLOSE; do { /* Loop until done (one side closes the connection, or an error) */ - rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled); + rv = apr_pollset_poll(pollset, dconf->idle_timeout, &pollcnt, &signalled); if (rv != APR_SUCCESS) { if (APR_STATUS_IS_EINTR(rv)) { continue; + } else if(APR_STATUS_IS_TIMEUP(rv)){ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "RH: the connection has timed out"); + return HTTP_REQUEST_TIME_OUT; } ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02444) "error apr_poll()"); return HTTP_INTERNAL_SERVER_ERROR; @@ -418,11 +424,26 @@ cleanup: return status; } +static const char * proxyws_set_idle(cmd_parms *cmd, void *conf, const char *val) +{ + proxyws_dir_conf *dconf = conf; + if (ap_timeout_parameter_parse(val, &(dconf->idle_timeout), "s") != APR_SUCCESS) + return "ProxyWebsocketIdleTimeout timeout has wrong format"; + + if (dconf->idle_timeout < 0) + return "ProxyWebsocketIdleTimeout timeout has to be a non-negative number"; + + if (!dconf->idle_timeout) dconf->idle_timeout = -1; /* loop indefinitely */ + + return NULL; +} + static void *create_proxyws_dir_config(apr_pool_t *p, char *dummy) { proxyws_dir_conf *new = (proxyws_dir_conf *) apr_pcalloc(p, sizeof(proxyws_dir_conf)); + new->idle_timeout = -1; /* no timeout */ new->fallback_to_proxy_http = 1; return (void *) new; @@ -465,7 +486,8 @@ static const command_rec ws_proxy_cmds[] = proxyws_fallback_to_proxy_http, NULL, RSRC_CONF|ACCESS_CONF, "whether to let mod_proxy_http handle the upgrade and tunneling, " "On by default"), - + AP_INIT_TAKE1("ProxyWebsocketIdleTimeout", proxyws_set_idle, NULL, RSRC_CONF|ACCESS_CONF, + "timeout for activity in either direction, unlimited by default."), {NULL} };