Merge "res_http_websocket: respond to CLOSE opcode"
This commit is contained in:
commit
ca5ca2e861
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue