diff --git a/lib/roles/ws/client-ws.c b/lib/roles/ws/client-ws.c index 0d88f4709..463a788cf 100644 --- a/lib/roles/ws/client-ws.c +++ b/lib/roles/ws/client-ws.c @@ -204,10 +204,12 @@ lws_generate_client_ws_handshake(struct lws *wsi, char *p, const char *conn1) int lws_client_ws_upgrade(struct lws *wsi, const char **cce) { - int n, len, okay = 0; struct lws_context *context = wsi->context; + struct lws_tokenize ts; + int n, len, okay = 0; + lws_tokenize_elem e; + char *p, buf[64]; const char *pc; - char *p; #if !defined(LWS_WITHOUT_EXTENSIONS) struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; char *sb = (char *)&pt->serv_buf[0]; @@ -262,18 +264,31 @@ lws_client_ws_upgrade(struct lws *wsi, const char **cce) goto bail3; } - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_CONNECTION); - if (!p) { - lwsl_info("no Connection hdr\n"); - *cce = "HS: CONNECTION missing"; - goto bail3; - } - strtolower(p); - if (strcmp(p, "upgrade")) { - lwsl_warn("lws_client_int_s_hs: bad header %s\n", p); - *cce = "HS: UPGRADE malformed"; - goto bail3; - } + /* connection: must have "upgrade" */ + + lws_tokenize_init(&ts, buf, LWS_TOKENIZE_F_COMMA_SEP_LIST | + LWS_TOKENIZE_F_MINUS_NONTERM); + ts.len = lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_CONNECTION); + if (ts.len <= 0) /* won't fit, or absent */ + goto bad_conn_format; + + do { + e = lws_tokenize(&ts); + switch (e) { + case LWS_TOKZE_TOKEN: + if (!strcasecmp(ts.token, "upgrade")) + e = LWS_TOKZE_ENDED; + break; + + case LWS_TOKZE_DELIMITER: + break; + + default: /* includes ENDED */ +bad_conn_format: + *cce = "HS: UPGRADE malformed"; + goto bail3; + } + } while (e > 0); pc = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS); if (!pc) { diff --git a/lib/roles/ws/server-ws.c b/lib/roles/ws/server-ws.c index 2d6df724c..db5d8ee08 100644 --- a/lib/roles/ws/server-ws.c +++ b/lib/roles/ws/server-ws.c @@ -304,10 +304,9 @@ lws_process_ws_upgrade(struct lws *wsi) break; case LWS_TOKZE_DELIMITER: - case LWS_TOKZE_ENDED: break; - default: + default: /* includes ENDED */ bad_conn_format: lwsl_err("%s: malformed or absent connection hdr\n", __func__); @@ -334,7 +333,8 @@ check_protocol: */ lws_tokenize_init(&ts, buf, LWS_TOKENIZE_F_COMMA_SEP_LIST | - LWS_TOKENIZE_F_MINUS_NONTERM); + LWS_TOKENIZE_F_MINUS_NONTERM | + LWS_TOKENIZE_F_RFC7230_DELIMS); ts.len = lws_hdr_copy(wsi, buf, sizeof(buf) - 1, WSI_TOKEN_PROTOCOL); if (ts.len < 0) { lwsl_err("%s: protocol list too long\n", __func__); diff --git a/minimal-examples/dbus-client/minimal-dbus-ws-proxy-testclient/minimal-dbus-ws-proxy-testclient.c b/minimal-examples/dbus-client/minimal-dbus-ws-proxy-testclient/minimal-dbus-ws-proxy-testclient.c index 294a5566d..8e688f403 100644 --- a/minimal-examples/dbus-client/minimal-dbus-ws-proxy-testclient/minimal-dbus-ws-proxy-testclient.c +++ b/minimal-examples/dbus-client/minimal-dbus-ws-proxy-testclient/minimal-dbus-ws-proxy-testclient.c @@ -259,7 +259,7 @@ bail: static int remote_method_call(struct lws_dbus_ctx_wsproxy_client *dcwc) { - const char *uri = "wss://libwebsockets.org/"; + const char *uri = "wss://libwebsockets.org/?mirror=dbt"; const char *subprotocol = "lws-mirror-protocol"; DBusMessage *msg; int ret = 1;