Add upgrade parameter to mod_proxy_wstunnel.
That allows to upgrade to jboss-remoting for example
or to run an HTTP/1.1 backend that needs to upgrade to
WebSocket.
See also:
https://issues.jboss.org/browse/JBCS-254
https://issues.jboss.org/browse/JBCS-291
whitespace only
Submitted By: jfclere
Reviewed By: covener, jim, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@
1797650 13f79535-47bb-0310-9956-
ffa450edef68
Changes with Apache 2.4.26
+ *) mod_proxy_wstunnel: Add "upgrade" parameter to allow upgrade to other
+ protocols. [Jean-Frederic Clere]
+
*) MPMs unix: Place signals handlers and helpers out of DSOs to avoid
a possible crash if a signal is caught during (graceful) restart.
PR 60487. [Yann Ylavic]
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- *) proxy_wstunnel: Restore ability to process other Upgrade: protocols which was
- blocked in r1674632/r1674661.
- trunk patch: http://svn.apache.org/r1792092
- http://svn.apache.org/r1796864
- 2.4.x patch: svn merge -c 1792092,1796864 ^/httpd/httpd/trunk .
- +1: covener, jim, ylavic
-
*) worker, prefork: save some cycles by not copying the listener's pollfds
for each pollset operation
trunk patch: http://svn.apache.org/r1662437
<td><p>Name of the provider used by <module>mod_proxy_fdpass</module>.
See the documentation of this module for more details.</p>
</td></tr>
+ <tr><td>secret</td>
+ <td>-</td>
+ <td><p>Value of secret used by <module>mod_proxy_ajp</module>.
+ See the documentation of this module for more details.</p>
+ </td></tr>
+ <tr><td>upgrade</td>
+ <td>WebSocket</td>
+ <td><p>Protocol accepted in the Upgrade header by <module>mod_proxy_wstunnel</module>.
+ See the documentation of this module for more details.</p>
+ </td></tr>
</table>
</highlight>
<p>Load balancing for multiple backends can be achieved using <module>mod_proxy_balancer</module>.</p>
+
+<p>In fact the module can be used to upgrade to other protocols, you can set the <code>upgrade</code>
+parameter in the <directive type="ProxyPass" module="mod_proxy">ProxyPass</directive>
+directive to allow the module to accept other protocol.
+NONE means you bypass the check for the header but still upgrade to WebSocket.</p>
</summary>
<seealso><module>mod_proxy</module></seealso>
(int)sizeof(worker->s->flusher));
PROXY_STRNCPY(worker->s->flusher, val);
}
+ else if (!strcasecmp(key, "upgrade")) {
+ if (PROXY_STRNCPY(worker->s->upgrade, val) != APR_SUCCESS) {
+ return apr_psprintf(p, "upgrade protocol length must be < %d characters",
+ (int)sizeof(worker->s->upgrade));
+ }
+ }
else {
if (set_worker_hc_param_f) {
return set_worker_hc_param_f(p, s, worker, key, val, NULL);
int fcount; /* current count of failures */
hcmethod_t method; /* method to use for health check */
apr_interval_time_t interval;
+ char upgrade[PROXY_WORKER_MAX_SCHEME_SIZE];/* upgrade protocol used by mod_proxy_wstunnel */
} proxy_worker_shared;
#define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared)))
apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
apr_socket_t *client_socket = ap_get_conn_socket(c);
int done = 0, replied = 0;
+ const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
header_brigade = apr_brigade_create(p, backconn->bucket_alloc);
return rv;
}
- buf = apr_pstrdup(p, "Upgrade: WebSocket" CRLF "Connection: Upgrade" CRLF CRLF);
+ if (ap_cstr_casecmp(upgrade_method, "NONE") == 0) {
+ buf = apr_pstrdup(p, "Upgrade: WebSocket" CRLF "Connection: Upgrade" CRLF CRLF);
+ } else {
+ buf = apr_pstrcat(p, "Upgrade: ", upgrade_method, CRLF "Connection: Upgrade" CRLF CRLF, NULL);
+ }
ap_xlate_proto_to_ascii(buf, strlen(buf));
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(header_brigade, e);
int status;
char server_portstr[32];
proxy_conn_rec *backend = NULL;
- const char *upgrade;
char *scheme;
int retry;
conn_rec *c = r->connection;
apr_pool_t *p = r->pool;
apr_uri_t *uri;
int is_ssl = 0;
+ const char *upgrade_method = *worker->s->upgrade ? worker->s->upgrade : "WebSocket";
if (strncasecmp(url, "wss:", 4) == 0) {
scheme = "WSS";
return DECLINED;
}
- upgrade = apr_table_get(r->headers_in, "Upgrade");
- if (!upgrade || strcasecmp(upgrade, "WebSocket") != 0) {
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02900)
- "declining URL %s (not WebSocket)", url);
- return DECLINED;
+ if (ap_cstr_casecmp(upgrade_method, "NONE") != 0) {
+ const char *upgrade;
+ upgrade = apr_table_get(r->headers_in, "Upgrade");
+ if (!upgrade || ap_cstr_casecmp(upgrade, upgrade_method) != 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02900)
+ "declining URL %s (not %s, Upgrade: header is %s)",
+ url, upgrade_method, upgrade ? upgrade : "missing");
+ return DECLINED;
+ }
}
uri = apr_palloc(p, sizeof(*uri));