mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 03:20:57 +00:00
res_http_websocket: respond to CLOSE opcode
This ensures that Asterisk responds properly to frames received from a client with opcode 8 (CLOSE) by echoing back the status code in its own CLOSE frame. Handling of the CLOSE opcode is moved up with the rest of the opcodes so that unmasking gets applied. The payload is no longer returned to the caller, but neither ARI nor the chan_sip nor pjsip made use of the payload, which is a good thing since it was masked. ASTERISK-28231 #close Change-Id: Icb1b60205fc77ee970ddc91d1f545671781344cf
This commit is contained in:
committed by
Sean Bright
parent
58b55f2a30
commit
0b8867f7d6
@@ -99,6 +99,7 @@ struct ast_websocket {
|
||||
unsigned int close_sent:1; /*!< Bit to indicate that the session close opcode has been sent and no further data will be sent */
|
||||
struct websocket_client *client; /*!< Client object when connected as a client websocket */
|
||||
char session_id[AST_UUID_STR_LEN]; /*!< The identifier for the websocket session */
|
||||
uint16_t close_status_code; /*!< Status code sent in a CLOSE frame upon shutdown */
|
||||
};
|
||||
|
||||
/*! \brief Hashing function for protocols */
|
||||
@@ -173,7 +174,7 @@ static void session_destroy_fn(void *obj)
|
||||
struct ast_websocket *session = obj;
|
||||
|
||||
if (session->stream) {
|
||||
ast_websocket_close(session, 0);
|
||||
ast_websocket_close(session, session->close_status_code);
|
||||
if (session->stream) {
|
||||
ast_iostream_close(session->stream);
|
||||
session->stream = NULL;
|
||||
@@ -578,7 +579,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 +638,16 @@ int AST_OPTIONAL_API_NAME(ast_websocket_read)(struct ast_websocket *session, cha
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save the CLOSE status code which will be sent in our own CLOSE in the destructor */
|
||||
if (*opcode == AST_WEBSOCKET_OPCODE_CLOSE) {
|
||||
session->closing = 1;
|
||||
if (*payload_len >= 2) {
|
||||
session->close_status_code = ntohs(get_unaligned_uint16(*payload));
|
||||
}
|
||||
*payload_len = 0;
|
||||
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 +687,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
|
||||
|
Reference in New Issue
Block a user