From 8547a782750c12a163e0cd022fefc2aaaa4b1bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20D=C3=B6rre?= Date: Wed, 28 Jun 2023 21:46:37 +0000 Subject: [PATCH] extmod/modwebsocket: Fix websocket to send correct close frame. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the websocket closes currently, it does not send a proper "close"-frame, but rather encodes the 0x8800-sequence inside a binary packet, which is wrong. The close packet is a different kind of websocket frame, according to https://www.rfc-editor.org/rfc/rfc6455. This change resolves an error in Firefox when the websocket closes. Signed-off-by: Felix Dörre --- extmod/modwebsocket.c | 10 ++++++++-- tests/extmod/websocket_basic.py.exp | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c index d2cb720396..3645b771a5 100644 --- a/extmod/modwebsocket.c +++ b/extmod/modwebsocket.c @@ -56,6 +56,7 @@ typedef struct _mp_obj_websocket_t { } mp_obj_websocket_t; STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode); +STATIC mp_uint_t websocket_write_raw(mp_obj_t self_in, const byte *header, int hdr_sz, const void *buf, mp_uint_t size, int *errcode); 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) { mp_arg_check_num(n_args, n_kw, 1, 2, false); @@ -193,9 +194,9 @@ STATIC mp_uint_t websocket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int if (last_state == CONTROL) { byte frame_type = self->last_flags & FRAME_OPCODE_MASK; if (frame_type == FRAME_CLOSE) { - static const char close_resp[2] = {0x88, 0}; + static const byte close_resp[2] = {0x88, 0}; int err; - websocket_write(self_in, close_resp, sizeof(close_resp), &err); + websocket_write_raw(self_in, close_resp, sizeof(close_resp), close_resp, 0, &err); return 0; } @@ -230,6 +231,11 @@ STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t si hdr_sz = 4; } + return websocket_write_raw(self_in, header, hdr_sz, buf, size, errcode); +} +STATIC mp_uint_t websocket_write_raw(mp_obj_t self_in, const byte *header, int hdr_sz, const void *buf, mp_uint_t size, int *errcode) { + mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_t dest[3]; if (self->opts & BLOCKING_WRITE) { mp_load_method(self->sock, MP_QSTR_setblocking, dest); diff --git a/tests/extmod/websocket_basic.py.exp b/tests/extmod/websocket_basic.py.exp index 2d7657b535..152aae836d 100644 --- a/tests/extmod/websocket_basic.py.exp +++ b/tests/extmod/websocket_basic.py.exp @@ -5,7 +5,7 @@ b'pingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpi b'\x81~\x00\x80pongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpong' b'\x00\x00\x00\x00' b'' -b'\x81\x02\x88\x00' +b'\x88\x00' b'ping' b'pong' 0