[mod_wstunnel] better Sec-WebSocket-Protocol parse

Improve handling of Sec-WebSocket-Protocol: binary, base64 for RFC6455.
When client sends Sec-WebSocket-Protocol in request header, client
may expect Sec-WebSocket-Protocol response.  mod_wstunnel is basic
tunnel endpoint and supports "binary" and "text" modes for RFC6455,
conventionally requested by client browsers as "binary" or "base64"
personal/stbuehler/fix-fdevent
Glenn Strauss 5 years ago
parent 04d76e7afd
commit 6fb023d664

@ -164,6 +164,7 @@ typedef struct {
int hybivers;
time_t ping_ts;
int subproto;
server *srv; /*(for mod_wstunnel module-specific DEBUG_LOG() macro)*/
plugin_config conf;
@ -535,9 +536,30 @@ static handler_t wstunnel_handler_setup (server *srv, connection *con, plugin_da
if (!binary) {
data_string *ds = (data_string *)
array_get_element(con->request.headers, "Sec-WebSocket-Protocol");
binary = (NULL != ds
&& buffer_is_equal_caseless_string(ds->value,
CONST_STR_LEN("binary")));
if (NULL != ds) {
for (const char *s = ds->value->ptr; *s; ++s) {
while (*s==' '||*s=='\t'||*s=='\r'||*s=='\n') ++s;
if (0 == strncasecmp(s, "binary", sizeof("binary")-1)) {
s += sizeof("binary")-1;
while (*s==' '||*s=='\t'||*s=='\r'||*s=='\n') ++s;
if (*s==','||*s=='\0') {
hctx->subproto = 1;
binary = 1;
break;
}
}
else if (0 == strncasecmp(s, "base64", sizeof("base64")-1)) {
s += sizeof("base64")-1;
while (*s==' '||*s=='\t'||*s=='\r'||*s=='\n') ++s;
if (*s==','||*s=='\0') {
hctx->subproto = -1;
break;
}
}
s = strchr(s, ',');
if (NULL == s) break;
}
}
}
if (binary) {
@ -843,6 +865,9 @@ static int create_response_rfc_6455(handler_ctx *hctx) {
if (hctx->frame.type == MOD_WEBSOCKET_FRAME_TYPE_BIN)
array_set_key_value(hdrs, CONST_STR_LEN("Sec-WebSocket-Protocol"),
CONST_STR_LEN("binary"));
else if (-1 == hctx->subproto)
array_set_key_value(hdrs, CONST_STR_LEN("Sec-WebSocket-Protocol"),
CONST_STR_LEN("base64"));
return 0;
}

Loading…
Cancel
Save