[sr-dev] git:pd/websocket: modules/websocket: Improvements to handshake handler
Peter Dunkley
peter.dunkley at crocodile-rcs.com
Fri Jun 15 11:20:20 CEST 2012
Module: sip-router
Branch: pd/websocket
Commit: 407130579cb10620480e8800558375094aaf07be
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=407130579cb10620480e8800558375094aaf07be
Author: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Date: Fri Jun 15 10:17:06 2012 +0100
modules/websocket: Improvements to handshake handler
---
modules/websocket/ws_handshake.c | 81 +++++++++++++++++++++++++++++---------
1 files changed, 62 insertions(+), 19 deletions(-)
diff --git a/modules/websocket/ws_handshake.c b/modules/websocket/ws_handshake.c
index 313187c..b46094f 100644
--- a/modules/websocket/ws_handshake.c
+++ b/modules/websocket/ws_handshake.c
@@ -34,16 +34,29 @@
#define WS_VERSION (13)
-#define SEC_WEBSOCKET_KEY (1<<0)
-#define SEC_WEBSOCKET_PROTOCOL (1<<1)
-#define SEC_WEBSOCKET_VERSION (1<<2)
-
-#define REQUIRED_HEADERS (SEC_WEBSOCKET_KEY | SEC_WEBSOCKET_PROTOCOL\
- | SEC_WEBSOCKET_VERSION)
-
static str str_sip = str_init("sip");
+static str str_websocket = str_init("websocket");
static str str_ws_guid = str_init("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
+/* HTTP headers */
+static str str_connection = str_init("Connection");
+static str str_upgrade = str_init("Upgrade");
+static str str_sec_websocket_accept = str_init("Sec-WebSocket-Accept");
+static str str_sec_websocket_key = str_init("Sec-WebSocket-Key");
+static str str_sec_websocket_protocol = str_init("Sec-WebSocket-Protocol");
+static str str_sec_websocket_version = str_init("Sec-WebSocket-Init");
+#define CONNECTION (1<<0)
+#define UPGRADE (1<<1)
+#define SEC_WEBSOCKET_ACCEPT (1<<2)
+#define SEC_WEBSOCKET_KEY (1<<3)
+#define SEC_WEBSOCKET_PROTOCOL (1<<4)
+#define SEC_WEBSOCKET_VERSION (1<<5)
+
+#define REQUIRED_HEADERS (CONNECTION | UPGRADE | SEC_WEBSOCKET_KEY\
+ | SEC_WEBSOCKET_PROTOCOL\
+ | SEC_WEBSOCKET_VERSION)
+
+/* HTTP response text */
static str str_switching_protocols = str_init("Switching Protocols");
static str str_bad_request = str_init("Bad Request");
static str str_upgrade_required = str_init("Upgrade Required");
@@ -85,9 +98,26 @@ int ws_handle_handshake(struct sip_msg *msg)
while (hdr != NULL)
{
- /* Decode and validate Sec-WebSocket-Key */
+ /* Decode and validate Connection */
if (cmp_hdrname_strzn(&hdr->name,
- "Sec-WebSocket-Key", 17) == 0)
+ str_connection.s,
+ str_connection.len) == 0)
+ {
+ /* TODO: validate Connection body */
+ hdr_flags |= CONNECTION;
+ }
+ /* Decode and validate Upgrade */
+ else if (cmp_hdrname_strzn(&hdr->name,
+ str_upgrade.s,
+ str_upgrade.len) == 0)
+ {
+ /* TODO: validate Upgrade body */
+ hdr_flags |= UPGRADE;
+ }
+ /* Decode and validate Sec-WebSocket-Key */
+ else if (cmp_hdrname_strzn(&hdr->name,
+ str_sec_websocket_key.s,
+ str_sec_websocket_key.len) == 0)
{
if (hdr_flags & SEC_WEBSOCKET_KEY)
{
@@ -102,14 +132,17 @@ int ws_handle_handshake(struct sip_msg *msg)
}
/* Decode and validate Sec-WebSocket-Protocol */
else if (cmp_hdrname_strzn(&hdr->name,
- "Sec-WebSocket-Protocol", 22) == 0)
+ str_sec_websocket_protocol.s,
+ str_sec_websocket_protocol.len) == 0)
{
+ /* TODO: better validation of sip... */
if (str_search(&hdr->body, &str_sip) != NULL)
hdr_flags |= SEC_WEBSOCKET_PROTOCOL;
}
/* Decode and validate Sec-WebSocket-Version */
else if (cmp_hdrname_strzn(&hdr->name,
- "Sec-WebSocket-Version", 21) == 0)
+ str_sec_websocket_version.s,
+ str_sec_websocket_version.len) == 0)
{
if (hdr_flags & SEC_WEBSOCKET_VERSION)
{
@@ -127,7 +160,9 @@ int ws_handle_handshake(struct sip_msg *msg)
hdr->body.len, hdr->body.s);
headers.s = headers_buf;
headers.len = snprintf(headers.s, HDR_BUF_LEN,
- "Sec-WebSocket-Version: %u\r\n",
+ "%.*s: %d\r\n",
+ str_sec_websocket_version.len,
+ str_sec_websocket_version.s,
WS_VERSION);
ws_send_reply(msg, 426, &str_upgrade_required,
&headers);
@@ -143,7 +178,13 @@ int ws_handle_handshake(struct sip_msg *msg)
/* Final check that all required headers/values were found */
if (hdr_flags != REQUIRED_HEADERS)
{
- LM_WARN("all required headers not present\n");
+ LM_WARN("required headers not present\n");
+ headers.s = headers_buf;
+ headers.len = snprintf(headers.s, HDR_BUF_LEN,
+ "%.*s: %.*s\r\n"
+ "%.*s: %d\r\n",
+ str_sec_websocket_protocol.len, str_sec_websocket_protocol.s, str_sip.len, str_sip.s,
+ str_sec_websocket_version.len, str_sec_websocket_version.s, WS_VERSION);
ws_send_reply(msg, 400, &str_bad_request, NULL);
return 0;
}
@@ -169,12 +210,14 @@ int ws_handle_handshake(struct sip_msg *msg)
/* Build headers for reply */
headers.s = headers_buf;
headers.len = snprintf(headers.s, HDR_BUF_LEN,
- "Sec-WebSocket-Key: %.*s\r\n"
- "Sec-WebSocket-Protocol: %.*s\r\n"
- "Sec-WebSocket-Version: %u\r\n",
- reply_key.len, reply_key.s,
- str_sip.len, str_sip.s,
- WS_VERSION);
+ "%.*s: %.*s\r\n"
+ "%.*s: %.*s\r\n"
+ "%.*s: %.*s\r\n"
+ "%.*s: %.*s\r\n",
+ str_upgrade.len, str_upgrade.s, str_websocket.len, str_websocket.s,
+ str_connection.len, str_connection.s, str_upgrade.len, str_upgrade.s,
+ str_sec_websocket_accept.len, str_sec_websocket_accept.s, reply_key.len, reply_key.s,
+ str_sec_websocket_protocol.len, str_sec_websocket_protocol.s, str_sip.len, str_sip.s);
/* TODO: make sure Kamailio core sends future requests on this
connection directly to this module */
More information about the sr-dev
mailing list