74bbdf | 2018-09-28 | Henrik Grubbström (Grubba) | |
inherit "module";
#include <module.h>
#include <request_trace.h>
constant cvs_version = "$Id$";
constant thread_safe = 1;
constant module_name = "WebSockets: Protocol support";
constant module_type = MODULE_FIRST;
constant module_doc = "Adds support for the HTTP extension defined "
"in <a href='http://rfc.roxen.com/6455'>RFC 6455 (WebSocket)</a>.";
constant module_unique = 1;
#ifdef WS_DEBUG
#define WS_WERROR(X...) werror(X)
#else /* !WS_DEBUG */
#define WS_WERROR(X...)
#endif /* WS_DEBUG */
Configuration conf;
void create()
{
}
void start(int q, Configuration c)
{
conf = c;
}
|
1be79b | 2018-10-01 | Henrik Grubbström (Grubba) | | protected int is_connection_upgrade(string path, RequestID id)
{
return has_value(lower_case(id->request_headers->connection||"")/",",
"upgrade");
}
protected int is_upgrade_websocket(string path, RequestID id)
{
return has_value(lower_case(id->request_headers->upgrade||"")/",",
"websocket");
}
protected int is_websocket_version_13(string path, RequestID id)
{
return id->request_headers["sec-websocket-version"] == "13";
}
protected int has_valid_websocket_key(string path, RequestID id)
{
string raw_key = "";
catch {
raw_key = MIME.decode_base64(id->request_headers["sec-websocket-key"]);
};
return sizeof(raw_key) >= 16;
}
|
74bbdf | 2018-09-28 | Henrik Grubbström (Grubba) | |
mapping(string:mixed)|int(-1..0) first_try(RequestID id)
{
TRACE_ENTER("Checking if this is a valid websocket request...", this);
if (id->misc->internal_get) {
TRACE_LEAVE("No - internal request.");
return 0;
}
if (id->method != "GET") {
TRACE_LEAVE("No - wrong method.");
return 0;
}
|
1be79b | 2018-10-01 | Henrik Grubbström (Grubba) | | id->register_vary_callback("connection", is_connection_upgrade);
|
74bbdf | 2018-09-28 | Henrik Grubbström (Grubba) | |
|
1be79b | 2018-10-01 | Henrik Grubbström (Grubba) | | if (!is_connection_upgrade("", id)) {
|
74bbdf | 2018-09-28 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("No - no connection: upgrade.");
return 0;
}
|
1be79b | 2018-10-01 | Henrik Grubbström (Grubba) | | id->register_vary_callback("connection", is_upgrade_websocket);
if (!is_upgrade_websocket("", id)) {
|
74bbdf | 2018-09-28 | Henrik Grubbström (Grubba) | |
id->misc->error_code = id->misc->error_code || Protocols.HTTP.HTTP_BAD;
TRACE_LEAVE("No - Unsupported or missing upgrade header.");
return 0;
}
|
1be79b | 2018-10-01 | Henrik Grubbström (Grubba) | | id->register_vary_callback("sec-websocket-version", is_websocket_version_13);
if (!is_websocket_version_13("", id)) {
|
74bbdf | 2018-09-28 | Henrik Grubbström (Grubba) | |
TRACE_LEAVE("No - Unsupported websocket version.");
return Roxen.http_status(Protocols.HTTP.HTTP_BAD,
"Unsupported WebSocket version.") + ([
"extra_heads": ([
"Sec-WebSocket-Version": (string)13,
]),
]);
}
|
1be79b | 2018-10-01 | Henrik Grubbström (Grubba) | | id->register_vary_callback("sec-websocket-key", has_valid_websocket_key);
if (!has_valid_websocket_key("", id)) {
|
74bbdf | 2018-09-28 | Henrik Grubbström (Grubba) | |
TRACE_LEAVE("No - Invalid Sec-WebSocket-Key.");
return Roxen.http_status(Protocols.HTTP.HTTP_BAD,
"Invalid Sec-WebSocket-Key.");
}
|
1be79b | 2018-10-01 | Henrik Grubbström (Grubba) | |
if (!has_prefix(id->prot, "HTTP/") ||
(id->prot[sizeof("HTTP/")..] < "1.1")) {
NOCACHE();
TRACE_LEAVE("No - not HTTP/1.1 or later.");
return 0;
}
|
74bbdf | 2018-09-28 | Henrik Grubbström (Grubba) | | TRACE_LEAVE("Yes.");
id->method = "WebSocketOpen";
id->misc->error_code = Protocols.HTTP.HTTP_BAD;
return 0;
}
|