Skip to content

Commit f38e8f5

Browse files
committed
extmod/modwebsocket: Record current fragment type (binary/text/etc.)
Also, handle continuation frames (untested).
1 parent 5b1c221 commit f38e8f5

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

extmod/modwebsocket.c

+24
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
#if MICROPY_PY_WEBSOCKET
3838

3939
enum { FRAME_HEADER, FRAME_OPT, PAYLOAD };
40+
#define FRAME_OPCODE_MASK 0x0f
41+
enum {
42+
FRAME_CONT, FRAME_TXT, FRAME_BIN,
43+
FRAME_CLOSE = 0x8, FRAME_PING, FRAME_PONG
44+
};
45+
4046
enum { BLOCKING_WRITE = 1 };
4147

4248
typedef struct _mp_obj_websocket_t {
@@ -50,6 +56,8 @@ typedef struct _mp_obj_websocket_t {
5056
byte buf_pos;
5157
byte buf[6];
5258
byte opts;
59+
// Copy of current frame's flags
60+
byte ws_flags;
5361
} mp_obj_websocket_t;
5462

5563
STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
@@ -87,8 +95,24 @@ STATIC mp_uint_t websocket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int
8795

8896
switch (self->state) {
8997
case FRAME_HEADER: {
98+
// TODO: Split frame handling below is untested so far, so conservatively disable it
9099
assert(self->buf[0] & 0x80);
91100

101+
// "Control frames MAY be injected in the middle of a fragmented message."
102+
// So, they must be processed before data frames (and not alter
103+
// self->ws_flags)
104+
if ((self->buf[0] & FRAME_OPCODE_MASK) >= FRAME_CLOSE) {
105+
// TODO: implement
106+
assert(0);
107+
}
108+
109+
if ((self->buf[0] & FRAME_OPCODE_MASK) == FRAME_CONT) {
110+
// Preserve previous frame type
111+
self->ws_flags = (self->ws_flags & FRAME_OPCODE_MASK) | (self->buf[0] & ~FRAME_OPCODE_MASK);
112+
} else {
113+
self->ws_flags = self->buf[0];
114+
}
115+
92116
// Reset mask in case someone will use "simplified" protocol
93117
// without masks.
94118
memset(self->mask, 0, sizeof(self->mask));

0 commit comments

Comments
 (0)