1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-16 00:00:07 +01:00

protocol selection: enable FILTER_PROTOCOL_CONNECTION to choose and set a protocol

So far agreeable protocol names were limited to what struct libwebsocket_protocols
had to offer.

With the wildcard matching of protocol name in an earlier commit, FILTER_PROTOCOL_CONNECTION
can now inspect and parse the WSI_TOKEN_PROTOCOL header, and explicitly
set a protocol by calling libwebsocket_set_protocol(wsi, name, <optional struct libwebsocket_protocols *>)

The Sec-WebSocket-Protocol: reply will contain only the default or matched
protocol name as selected in FILTER_PROTOCOL_CONNECTION.

The current protocol name can be accessed via
const char *libwebsockets_get_protocol_name(struct libwebsocket *wsi).

A LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION callback would do roughly this:

lws_hdr_copy(wsi, protocols, sizeof protocols, WSI_TOKEN_PROTOCOL);
..inspect protocols and choose a proto name and struct libwebsocket_protocols:
..call libwebsocket_set_protocol(wsi,name, <opt proto if not default>);

Also deals with issue #147 (incorrect Sec-WebSocket-Protocol: reply).
This commit is contained in:
Michael Haberler 2014-08-10 12:30:01 +02:00
parent d197e1fb17
commit 529d96dc60
5 changed files with 33 additions and 4 deletions

View file

@ -669,6 +669,14 @@ libwebsockets_get_protocol(struct libwebsocket *wsi)
return wsi->protocol;
}
LWS_VISIBLE const char *
libwebsockets_get_protocol_name(struct libwebsocket *wsi)
{
if (wsi->selected_protocol)
return wsi->selected_protocol;
return wsi->protocol->name;
}
LWS_VISIBLE int
libwebsocket_is_final_fragment(struct libwebsocket *wsi)
{

View file

@ -1036,6 +1036,11 @@ LWS_VISIBLE LWS_EXTERN void
libwebsocket_set_timeout(struct libwebsocket *wsi,
enum pending_timeout reason, int secs);
LWS_VISIBLE LWS_EXTERN void
libwebsocket_set_protocol(struct libwebsocket *wsi,
char *protocol_name,
struct libwebsocket_protocols *proto);
/*
* IMPORTANT NOTICE!
*
@ -1095,6 +1100,9 @@ LWS_VISIBLE LWS_EXTERN int libwebsockets_return_http_status(
LWS_VISIBLE LWS_EXTERN const struct libwebsocket_protocols *
libwebsockets_get_protocol(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN const char *
libwebsockets_get_protocol_name(struct libwebsocket *wsi);
LWS_VISIBLE LWS_EXTERN int
libwebsocket_callback_on_writable(struct libwebsocket_context *context,
struct libwebsocket *wsi);

View file

@ -576,6 +576,7 @@ struct libwebsocket {
struct lws_io_watcher w_write;
#endif /* LWS_USE_LIBEV */
const struct libwebsocket_protocols *protocol;
char *selected_protocol;
#ifndef LWS_NO_EXTENSIONS
struct libwebsocket_extension *
active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];

View file

@ -217,10 +217,11 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi)
if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL)) {
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
n = lws_hdr_copy(wsi, p, 128, WSI_TOKEN_PROTOCOL);
if (n < 0)
goto bail;
p += n;
const char *proto = wsi->selected_protocol ? wsi->selected_protocol :
wsi->protocol->name;
lwsl_debug("replying with selected proto='%s'\n", proto);
strcpy(p, proto);
p += strlen(proto);
}
#ifndef LWS_NO_EXTENSIONS

View file

@ -950,3 +950,14 @@ lws_server_get_canonical_hostname(struct libwebsocket_context *context,
lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname);
}
LWS_VISIBLE void
libwebsocket_set_protocol(struct libwebsocket *wsi,
char *protocol_name,
struct libwebsocket_protocols *proto)
{
wsi->selected_protocol = protocol_name;
if (proto)
wsi->protocol = proto;
}