mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-27 12:26:24 +00:00
Validate WebSocket continuation frame sequencing
This commit is contained in:
1 parent
bbee8ae61f
commit
60c75a22b8
4 files changed
+31
-6
No files matched your search
@@ -27032,6 +27032,12 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data) {
|
||||
op = msg.flags & 15;
|
||||
// MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op,
|
||||
// (int) m.data.len, (int) m.data.len, m.data.buf));
|
||||
if ((op == WEBSOCKET_OP_CONTINUE && ofs == 0) ||
|
||||
((op == WEBSOCKET_OP_TEXT || op == WEBSOCKET_OP_BINARY) &&
|
||||
ofs != 0)) {
|
||||
mg_error(c, "invalid WS fragment sequence");
|
||||
return;
|
||||
}
|
||||
switch (op) {
|
||||
case WEBSOCKET_OP_CONTINUE:
|
||||
mg_call(c, MG_EV_WS_CTL, &m);
|
||||
|
||||
+4
-5
@@ -2838,9 +2838,9 @@ int mg_http_status(const struct mg_http_message *hm);
|
||||
// Streams a POST/PUT body to a callback as it arrives, without buffering it.
|
||||
// Call it from your connection handler on every event.
|
||||
//
|
||||
// Callback cb(hm, data, &user_data) is called:
|
||||
// - at start: hm is set, data is NULL. Open the file, set *user_data.
|
||||
// - per chunk: hm is NULL, data is set. Chunks are multiples of 512 bytes,
|
||||
// Callback upload_fn(hm, data, user_data) is called:
|
||||
// - at start: hm is set, data is NULL. Open the file, set user_data.
|
||||
// - per chunk: hm is NULL, data is set. Chunks are 512 bytes aligned
|
||||
// except the last one.
|
||||
// - at end: both NULL. Close the file.
|
||||
// After the last chunk, "200 ok" is sent and the connection is drained.
|
||||
@@ -2852,8 +2852,7 @@ int mg_http_status(const struct mg_http_message *hm);
|
||||
// mg_http_start_upload(), mg_http_start_ota()
|
||||
// Notes:
|
||||
// Requires Content-Length, chunked bodies are not streamed. user_data is
|
||||
// c->fn_data. While streaming, c->pfn is NULL, so guard your own
|
||||
// MG_EV_HTTP_MSG handling with c->pfn != NULL.
|
||||
// &c->fn_data. While streaming, c->pfn is NULL
|
||||
void mg_http_stream_body(struct mg_connection *c, int ev, void *ev_data,
|
||||
struct mg_str uri_pattern,
|
||||
void (*upload_fn)(struct mg_http_message *,
|
||||
|
||||
@@ -182,6 +182,12 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data) {
|
||||
op = msg.flags & 15;
|
||||
// MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op,
|
||||
// (int) m.data.len, (int) m.data.len, m.data.buf));
|
||||
if ((op == WEBSOCKET_OP_CONTINUE && ofs == 0) ||
|
||||
((op == WEBSOCKET_OP_TEXT || op == WEBSOCKET_OP_BINARY) &&
|
||||
ofs != 0)) {
|
||||
mg_error(c, "invalid WS fragment sequence");
|
||||
return;
|
||||
}
|
||||
switch (op) {
|
||||
case WEBSOCKET_OP_CONTINUE:
|
||||
mg_call(c, MG_EV_WS_CTL, &m);
|
||||
|
||||
+15
-1
@@ -967,7 +967,7 @@ static void wcb(struct mg_connection *c, int ev, void *ev_data) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
struct mg_str *wsproto = mg_http_get_header(hm, "Sec-WebSocket-Protocol");
|
||||
ASSERT(wsproto != NULL);
|
||||
mg_ws_send(c, "hello", 0, 0);
|
||||
mg_ws_send(c, "", 0, WEBSOCKET_OP_TEXT);
|
||||
mg_ws_printf(c, WEBSOCKET_OP_BINARY, "%.3s", "boo!!!!");
|
||||
mg_ws_printf(c, WEBSOCKET_OP_BINARY, "%s", "foobar");
|
||||
mg_ws_send(c, "", 0, WEBSOCKET_OP_PING);
|
||||
@@ -983,6 +983,15 @@ static void wcb(struct mg_connection *c, int ev, void *ev_data) {
|
||||
}
|
||||
}
|
||||
|
||||
static void wbad(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev == MG_EV_WS_OPEN) {
|
||||
mg_ws_send(c, "ABC", 3, WEBSOCKET_OP_CONTINUE);
|
||||
} else if (ev == MG_EV_CLOSE) {
|
||||
*(int *) c->fn_data = 1;
|
||||
}
|
||||
(void) ev_data;
|
||||
}
|
||||
|
||||
static void ew2(struct mg_connection *c, int ev, void *ev_data) {
|
||||
size_t size = 65 * 1024 + 737;
|
||||
if (ev == MG_EV_WS_OPEN) {
|
||||
@@ -1028,6 +1037,11 @@ static void test_ws(void) {
|
||||
for (i = 0; i < 1000 && done == 0; i++) mg_mgr_poll(&mgr, 1);
|
||||
ASSERT(done == 1);
|
||||
|
||||
done = 0;
|
||||
mg_ws_connect(&mgr, url, wbad, &done, NULL);
|
||||
for (i = 0; i < 30 && done == 0; i++) mg_mgr_poll(&mgr, 1);
|
||||
ASSERT(done == 1);
|
||||
|
||||
mg_mgr_free(&mgr);
|
||||
ASSERT(mgr.conns == NULL);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user