diff --git a/docs/manual/mod/mod_proxy_wstunnel.html.en b/docs/manual/mod/mod_proxy_wstunnel.html.en index c5004b8..a0ae3c8 100644 --- a/docs/manual/mod/mod_proxy_wstunnel.html.en +++ b/docs/manual/mod/mod_proxy_wstunnel.html.en @@ -96,6 +96,7 @@ WebSocket always happens.
Support Apache!

Directives

Bugfix checklist

See also

+ +

ProxyWebsocketIdleTimeout Directive

+ + + + + + + +
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 30ba1b4..e27e6f8 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; @@ -176,6 +177,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; @@ -253,10 +256,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; @@ -442,11 +448,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; @@ -489,7 +510,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} };