</summary>
<seealso><module>mod_proxy</module></seealso>
+
+<directivesynopsis>
+<name>ProxyWebsocketFallbackToProxyHttp</name>
+<description>Instructs this module to let <module>mod_proxy_http</module> handle the request</description>
+<syntax>ProxyWebsocketFallbackToProxyHttp On|Off</syntax>
+<default>ProxyWebsocketFallbackToProxyHttp On</default>
+<compatibility>Available in httpd 2.4.48 and later</compatibility>
+<contextlist><context>server config</context>
+<context>virtual host</context>
+</contextlist>
+
+<usage>
+ <p>Since httpd 2.4.47, <module>mod_proxy_http</module> can handle WebSocket
+ upgrading and tunneling in accordance to RFC 7230, this directive controls
+ whether <module>mod_proxy_wstunnel</module> should hand over to
+ <module>mod_proxy_http</module> to this, which is the case by default.</p>
+ <p>Setting to <em>Off</em> lets <module>mod_proxy_wstunnel</module> handle
+ WebSocket requests as in httpd 2.4.46 and earlier.</p>
+</usage>
+</directivesynopsis>
+
</modulesynopsis>
module AP_MODULE_DECLARE_DATA proxy_wstunnel_module;
-static int fallback_to_mod_proxy_http;
+typedef struct {
+ unsigned int fallback_to_proxy_http :1,
+ fallback_to_proxy_http_set :1;
+} proxyws_dir_conf;
+
+static int can_fallback_to_proxy_http;
static int proxy_wstunnel_check_trans(request_rec *r, const char *url)
{
- if (fallback_to_mod_proxy_http) {
+ proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &proxy_wstunnel_module);
+
+ if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "check_trans fallback");
return DECLINED;
}
*/
static int proxy_wstunnel_canon(request_rec *r, char *url)
{
+ proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &proxy_wstunnel_module);
char *host, *path, sport[7];
char *search = NULL;
const char *err;
char *scheme;
apr_port_t port, def_port;
- if (fallback_to_mod_proxy_http) {
+ if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "canon fallback");
return DECLINED;
}
char *url, const char *proxyname,
apr_port_t proxyport)
{
+ proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &proxy_wstunnel_module);
int status;
char server_portstr[32];
proxy_conn_rec *backend = NULL;
apr_uri_t *uri;
int is_ssl = 0;
- if (fallback_to_mod_proxy_http) {
+ if (can_fallback_to_proxy_http && dconf->fallback_to_proxy_http) {
ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "handler fallback");
return DECLINED;
}
return status;
}
+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->fallback_to_proxy_http = 1;
+
+ return (void *) new;
+}
+
+static void *merge_proxyws_dir_config(apr_pool_t *p, void *vbase, void *vadd)
+{
+ proxyws_dir_conf *new = apr_pcalloc(p, sizeof(proxyws_dir_conf)),
+ *add = vadd, *base = vbase;
+
+ new->fallback_to_proxy_http = (add->fallback_to_proxy_http_set)
+ ? add->fallback_to_proxy_http
+ : base->fallback_to_proxy_http;
+ new->fallback_to_proxy_http_set = (add->fallback_to_proxy_http_set
+ || base->fallback_to_proxy_http_set);
+
+ return new;
+}
+
+static const char * proxyws_fallback_to_proxy_http(cmd_parms *cmd, void *conf, int arg)
+{
+ proxyws_dir_conf *dconf = conf;
+ dconf->fallback_to_proxy_http = !!arg;
+ dconf->fallback_to_proxy_http_set = 1;
+ return NULL;
+}
+
static int proxy_wstunnel_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s)
{
- fallback_to_mod_proxy_http =
+ can_fallback_to_proxy_http =
(ap_find_linked_module("mod_proxy_http.c") != NULL);
return OK;
}
+static const command_rec ws_proxy_cmds[] =
+{
+ AP_INIT_FLAG("ProxyWebsocketFallbackToProxyHttp",
+ proxyws_fallback_to_proxy_http, NULL, RSRC_CONF|ACCESS_CONF,
+ "whether to let mod_proxy_http handle the upgrade and tunneling, "
+ "On by default"),
+
+ {NULL}
+};
+
static void ws_proxy_hooks(apr_pool_t *p)
{
static const char * const aszSucc[] = { "mod_proxy_http.c", NULL};
AP_DECLARE_MODULE(proxy_wstunnel) = {
STANDARD20_MODULE_STUFF,
- NULL, /* create per-directory config structure */
- NULL, /* merge per-directory config structures */
+ create_proxyws_dir_config, /* create per-directory config structure */
+ merge_proxyws_dir_config, /* 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 */
ws_proxy_hooks /* register hooks */
};