mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-03 13:28:44 +00:00
Fix handling of WS handshake error response
Check response code, make sure it's 101. Pass http_message to the client to keep it appraised. This represents a slight change in the API - in case of an error MG_EV_WEBSOCKET_HANDSHAKE_DONE will now be delivered where previosuly connection would just hang. Clients that do not examine the argument may for a moment think handshake has succeeded but in fact connection will be closed immediately. CL: mg: Fix handling of WS handshake error response PUBLISHED_FROM=645a43d9e5bee216e54411f85827c9b974e9a7d1
This commit is contained in:
1 parent
148d3f0562
commit
1e9fabe1ca
8 files changed
+108
-58
No files matched your search
+50
-30
@@ -2540,32 +2540,6 @@ static const char *test_http_range(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void cb3(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct websocket_message *wm = (struct websocket_message *) ev_data;
|
||||
|
||||
if (ev == MG_EV_WEBSOCKET_FRAME) {
|
||||
const char *reply = wm->size == 2 && !memcmp(wm->data, "hi", 2) ? "A" : "B";
|
||||
mg_printf_websocket_frame(nc, WEBSOCKET_OP_TEXT, "%s", reply);
|
||||
}
|
||||
}
|
||||
|
||||
static void cb4(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct websocket_message *wm = (struct websocket_message *) ev_data;
|
||||
|
||||
if (ev == MG_EV_WEBSOCKET_FRAME) {
|
||||
memcpy(nc->user_data, wm->data, wm->size);
|
||||
mg_send_websocket_frame(nc, WEBSOCKET_OP_CLOSE, NULL, 0);
|
||||
} else if (ev == MG_EV_WEBSOCKET_HANDSHAKE_DONE) {
|
||||
/* Send "hi" to server. server must reply "A". */
|
||||
struct mg_str h[2];
|
||||
h[0].p = "h";
|
||||
h[0].len = 1;
|
||||
h[1].p = "i";
|
||||
h[1].len = 1;
|
||||
mg_send_websocket_framev(nc, WEBSOCKET_OP_TEXT, h, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void cb_ws_server(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct websocket_message *wm = (struct websocket_message *) ev_data;
|
||||
|
||||
@@ -2780,6 +2754,38 @@ static const char *test_websocket(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void cb3(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
struct websocket_message *wm = (struct websocket_message *) ev_data;
|
||||
if (ev != MG_EV_WEBSOCKET_FRAME) return;
|
||||
DBG(("server data '%.*s'", (int) wm->size, wm->data));
|
||||
const char *reply = wm->size == 2 && !memcmp(wm->data, "hi", 2) ? "A" : "B";
|
||||
mg_printf_websocket_frame(nc, WEBSOCKET_OP_TEXT, "%s", reply);
|
||||
}
|
||||
|
||||
static void cb4(struct mg_connection *nc, int ev, void *ev_data) {
|
||||
char *buf = (char *) nc->user_data;
|
||||
if (ev == MG_EV_WEBSOCKET_FRAME) {
|
||||
struct websocket_message *wm = (struct websocket_message *) ev_data;
|
||||
DBG(("client data '%.*s'", (int) wm->size, wm->data));
|
||||
memcpy(buf, wm->data, wm->size);
|
||||
mg_send_websocket_frame(nc, WEBSOCKET_OP_CLOSE, NULL, 0);
|
||||
} else if (ev == MG_EV_WEBSOCKET_HANDSHAKE_DONE) {
|
||||
struct http_message *hm = (struct http_message *) ev_data;
|
||||
DBG(("code %d", hm->resp_code));
|
||||
if (hm->resp_code == 101) {
|
||||
/* Send "hi" to server. server must reply "A". */
|
||||
struct mg_str h[2];
|
||||
h[0].p = "h";
|
||||
h[0].len = 1;
|
||||
h[1].p = "i";
|
||||
h[1].len = 1;
|
||||
mg_send_websocket_framev(nc, WEBSOCKET_OP_TEXT, h, 2);
|
||||
} else {
|
||||
snprintf(buf, 20, "code %d", hm->resp_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cbwep(struct mg_connection *c, int ev, void *ev_data) {
|
||||
struct websocket_message *wm = (struct websocket_message *) ev_data;
|
||||
char *buf = (char *) c->user_data;
|
||||
@@ -2787,6 +2793,9 @@ static void cbwep(struct mg_connection *c, int ev, void *ev_data) {
|
||||
switch (ev) {
|
||||
case MG_EV_WEBSOCKET_HANDSHAKE_REQUEST:
|
||||
strcat(buf, "R");
|
||||
if (buf[0] != '0') {
|
||||
mg_http_send_error(c, 403, "I don't like you");
|
||||
}
|
||||
break;
|
||||
case MG_EV_WEBSOCKET_HANDSHAKE_DONE:
|
||||
strcat(buf, "D");
|
||||
@@ -2803,7 +2812,7 @@ static const char *test_websocket_endpoint(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *nc;
|
||||
const char *local_addr = "127.0.0.1:7798";
|
||||
char buf[20] = "", buf2[20] = "";
|
||||
char buf[20] = "", buf2[20] = "0";
|
||||
|
||||
mg_mgr_init(&mgr, NULL);
|
||||
/* mgr.hexdump_file = "-"; */
|
||||
@@ -2818,10 +2827,21 @@ static const char *test_websocket_endpoint(void) {
|
||||
nc->user_data = buf;
|
||||
mg_send_websocket_handshake(nc, "/boo", NULL);
|
||||
poll_until(&mgr, 1, c_str_ne, buf, (void *) "");
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
/* Check that test buffer has been filled by the callback properly. */
|
||||
ASSERT_STREQ(buf, "RDF|hi");
|
||||
ASSERT_STREQ(buf, "0RDF|hi");
|
||||
|
||||
/* Test handshake failure */
|
||||
ASSERT((nc = mg_connect(&mgr, local_addr, cb4)) != NULL);
|
||||
mg_set_protocol_http_websocket(nc);
|
||||
buf[0] = '\0';
|
||||
buf2[0] = '1';
|
||||
buf2[1] = '\0';
|
||||
nc->user_data = buf;
|
||||
mg_send_websocket_handshake(nc, "/boo", NULL);
|
||||
poll_until(&mgr, 1, c_str_ne, buf, (void *) "");
|
||||
ASSERT_STREQ(buf, "code 403");
|
||||
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user