MINOR: h1: reject websocket handshake if missing key
If a request is identified as a WebSocket handshake, it must contains a
websocket key header or else it can be reject, following the rfc6455.
A new flag H1_MF_UPG_WEBSOCKET is set on such messages. For the request
te be identified as a WebSocket handshake, it must contains the headers:
Connection: upgrade
Upgrade: websocket
This commit is a compagnon of
"MEDIUM: h1: generate WebSocket key on response if needed" and
"MEDIUM: h1: add a WebSocket key on handshake if needed".
Indeed, it ensures that a WebSocket key is added only from a http/2 side
and not for a http/1 bogus peer.
diff --git a/src/h1.c b/src/h1.c
index bb8acfb..ca39d97 100644
--- a/src/h1.c
+++ b/src/h1.c
@@ -186,6 +186,38 @@
}
}
+/* Parse the Upgrade: header of an HTTP/1 request.
+ * If "websocket" is found, set H1_MF_UPG_WEBSOCKET flag
+ */
+void h1_parse_upgrade_header(struct h1m *h1m, struct ist value)
+{
+ char *e, *n;
+ struct ist word;
+
+ h1m->flags &= ~H1_MF_UPG_WEBSOCKET;
+
+ word.ptr = value.ptr - 1; // -1 for next loop's pre-increment
+ e = value.ptr + value.len;
+
+ while (++word.ptr < e) {
+ /* skip leading delimiter and blanks */
+ if (HTTP_IS_LWS(*word.ptr))
+ continue;
+
+ n = http_find_hdr_value_end(word.ptr, e); // next comma or end of line
+ word.len = n - word.ptr;
+
+ /* trim trailing blanks */
+ while (word.len && HTTP_IS_LWS(word.ptr[word.len-1]))
+ word.len--;
+
+ if (isteqi(word, ist("websocket")))
+ h1m->flags |= H1_MF_UPG_WEBSOCKET;
+
+ word.ptr = n;
+ }
+}
+
/* Macros used in the HTTP/1 parser, to check for the expected presence of
* certain bytes (ef: LF) or to skip to next byte and yield in case of failure.
*/
@@ -828,6 +860,9 @@
break;
}
}
+ else if (isteqi(n, ist("upgrade"))) {
+ h1_parse_upgrade_header(h1m, v);
+ }
else if (!(h1m->flags & (H1_MF_HDRS_ONLY|H1_MF_RESP)) && isteqi(n, ist("host"))) {
if (host_idx == -1) {
struct ist authority;