[Asterisk-code-review] res http websocket: respond to CLOSE opcode (asterisk[13])

Jeremy Lainé asteriskteam at digium.com
Mon Jan 7 08:26:42 CST 2019


Jeremy Lainé has uploaded this change for review. ( https://gerrit.asterisk.org/10856


Change subject: res_http_websocket: respond to CLOSE opcode
......................................................................

res_http_websocket: respond to CLOSE opcode

This ensures that Asterisk responds properly to frames received from a
client with opcode 8 (CLOSE) by:

- responding with its own CLOSE frame, echoing back the status code
- closing the connection

ASTERISK-28231 #close

Change-Id: Icb1b60205fc77ee970ddc91d1f545671781344cf
---
M res/res_http_websocket.c
1 file changed, 17 insertions(+), 23 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/56/10856/1

diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index d52e6b3..28e7233 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -566,7 +566,7 @@
 	*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;
 
@@ -622,6 +622,22 @@
 			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",
@@ -661,28 +677,6 @@
 			*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

-- 
To view, visit https://gerrit.asterisk.org/10856
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icb1b60205fc77ee970ddc91d1f545671781344cf
Gerrit-Change-Number: 10856
Gerrit-PatchSet: 1
Gerrit-Owner: Jeremy Lainé <jeremy.laine at m4x.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20190107/dba66a88/attachment.html>


More information about the asterisk-code-review mailing list