diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c index 0b75721097..c8022e057b 100644 --- a/res/res_http_websocket.c +++ b/res/res_http_websocket.c @@ -578,7 +578,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha *opcode = buf[0] & 0xf; *payload_len = buf[1] & 0x7f; if (*opcode == AST_WEBSOCKET_OPCODE_TEXT || *opcode == AST_WEBSOCKET_OPCODE_BINARY || *opcode == AST_WEBSOCKET_OPCODE_CONTINUATION || - *opcode == AST_WEBSOCKET_OPCODE_PING || *opcode == AST_WEBSOCKET_OPCODE_PONG) { + *opcode == AST_WEBSOCKET_OPCODE_PING || *opcode == AST_WEBSOCKET_OPCODE_PONG || *opcode == AST_WEBSOCKET_OPCODE_CLOSE) { fin = (buf[0] >> 7) & 1; mask_present = (buf[1] >> 7) & 1; @@ -637,6 +637,22 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha return 0; } + /* Reply to CLOSE opcode with our own CLOSE and echo back the code */ + if (*opcode == AST_WEBSOCKET_OPCODE_CLOSE) { + uint16_t code = 0; + if (*payload_len >= 2) { + code = ntohs(get_unaligned_uint16(*payload)); + } + *payload_len = 0; + ast_websocket_close(session, code); + + if (session->stream) { + ast_iostream_close(session->stream); + session->stream = NULL; + } + return 0; + } + if (*payload_len) { if (!(new_payload = ast_realloc(session->payload, (session->payload_len + *payload_len)))) { ast_log(LOG_WARNING, "Failed allocation: %p, %zu, %"PRIu64"\n", @@ -676,28 +692,6 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha *payload = session->payload; session->payload_len = 0; } - } else if (*opcode == AST_WEBSOCKET_OPCODE_CLOSE) { - session->closing = 1; - - /* Make the payload available so the user can look at the reason code if they so desire */ - if (!*payload_len) { - return 0; - } - - if (!(new_payload = ast_realloc(session->payload, *payload_len))) { - ast_log(LOG_WARNING, "Failed allocation: %p, %"PRIu64"\n", - session->payload, *payload_len); - *payload_len = 0; - return -1; - } - - session->payload = new_payload; - if (ws_safe_read(session, &buf[frame_size], *payload_len, opcode)) { - return -1; - } - memcpy(session->payload, &buf[frame_size], *payload_len); - *payload = session->payload; - frame_size += *payload_len; } else { ast_log(LOG_WARNING, "WebSocket unknown opcode %u\n", *opcode); /* We received an opcode that we don't understand, the RFC states that 1003 is for a type of data that can't be accepted... opcodes