diff --git a/docs/manual/mod/mod_proxy_wstunnel.html.en b/docs/manual/mod/mod_proxy_wstunnel.html.en index 7506ccb..8867578 100644 --- a/docs/manual/mod/mod_proxy_wstunnel.html.en +++ b/docs/manual/mod/mod_proxy_wstunnel.html.en @@ -60,14 +60,33 @@ NONE means you bypass the check for the header but still upgrade to WebSocket. ANY means that Upgrade will read in the request headers and use in the response Upgrade

-
Support Apache!

Directives

-

This module provides no - directives.

+

Directives

+ +

Bugfix checklist

See also

+
top
+

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 fb53fe6..73da758 100644 --- a/modules/proxy/mod_proxy_wstunnel.c +++ b/modules/proxy/mod_proxy_wstunnel.c @@ -18,6 +18,10 @@ module AP_MODULE_DECLARE_DATA proxy_wstunnel_module; +typedef struct { + apr_time_t idle_timeout; +} proxyws_dir_conf; + /* * Canonicalise http-like URLs. * scheme is the scheme for the URL @@ -111,6 +115,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; @@ -188,10 +194,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; @@ -366,6 +375,38 @@ 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 */ + + return (void *) new; +} + +static const command_rec ws_proxy_cmds[] = +{ + AP_INIT_TAKE1("ProxyWebsocketIdleTimeout", proxyws_set_idle, NULL, RSRC_CONF|ACCESS_CONF, + "timeout for activity in either direction, unlimited by default."), + + {NULL} +}; + static void ap_proxy_http_register_hook(apr_pool_t *p) { proxy_hook_scheme_handler(proxy_wstunnel_handler, NULL, NULL, APR_HOOK_FIRST); @@ -374,10 +415,10 @@ static void ap_proxy_http_register_hook(apr_pool_t *p) AP_DECLARE_MODULE(proxy_wstunnel) = { STANDARD20_MODULE_STUFF, - NULL, /* create per-directory config structure */ + create_proxyws_dir_config, /* create per-directory config structure */ NULL, /* merge per-directory config structures */ NULL, /* create per-server config structure */ NULL, /* merge per-server config structures */ - NULL, /* command apr_table_t */ + ws_proxy_cmds, /* command apr_table_t */ ap_proxy_http_register_hook /* register hooks */ };