diff --git a/include/asterisk/http_websocket.h b/include/asterisk/http_websocket.h index 23492ff95563ee25e1625b3334e87316c28bfcb4..cd49dbe4825d577af6b44ee0f17dd0ea60523ecb 100644 --- a/include/asterisk/http_websocket.h +++ b/include/asterisk/http_websocket.h @@ -266,12 +266,12 @@ AST_OPTIONAL_API(int, ast_websocket_read_string, * \param session Pointer to the WebSocket session * \param opcode WebSocket operation code to place in the frame * \param payload Optional pointer to a payload to add to the frame - * \param actual_length Length of the payload (0 if no payload) + * \param payload_size Length of the payload (0 if no payload) * * \retval 0 if successfully written * \retval -1 if error occurred */ -AST_OPTIONAL_API(int, ast_websocket_write, (struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length), { errno = ENOSYS; return -1;}); +AST_OPTIONAL_API(int, ast_websocket_write, (struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t payload_size), { errno = ENOSYS; return -1;}); /*! * \brief Construct and transmit a WebSocket frame containing string data. diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c index c40aae6d2793884e581b45a5a0cef0530f7950f8..2654578549c3400f13eefa87d3f891302b36e855 100644 --- a/res/res_http_websocket.c +++ b/res/res_http_websocket.c @@ -332,18 +332,19 @@ static const char *websocket_opcode2str(enum ast_websocket_opcode opcode) } /*! \brief Write function for websocket traffic */ -int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length) +int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t payload_size) { size_t header_size = 2; /* The minimum size of a websocket frame is 2 bytes */ char *frame; uint64_t length; + uint64_t frame_size; ast_debug(3, "Writing websocket %s frame, length %" PRIu64 "\n", - websocket_opcode2str(opcode), actual_length); + websocket_opcode2str(opcode), payload_size); - if (actual_length < 126) { - length = actual_length; - } else if (actual_length < (1 << 16)) { + if (payload_size < 126) { + length = payload_size; + } else if (payload_size < (1 << 16)) { length = 126; /* We need an additional 2 bytes to store the extended length */ header_size += 2; @@ -353,37 +354,37 @@ int AST_OPTIONAL_API_NAME(ast_websocket_write)(struct ast_websocket *session, en header_size += 8; } - frame = ast_alloca(header_size); - memset(frame, 0, header_size); + frame_size = header_size + payload_size; + + frame = ast_alloca(frame_size + 1); + memset(frame, 0, frame_size + 1); frame[0] = opcode | 0x80; frame[1] = length; /* Use the additional available bytes to store the length */ if (length == 126) { - put_unaligned_uint16(&frame[2], htons(actual_length)); + put_unaligned_uint16(&frame[2], htons(payload_size)); } else if (length == 127) { - put_unaligned_uint64(&frame[2], htonll(actual_length)); + put_unaligned_uint64(&frame[2], htonll(payload_size)); } + memcpy(&frame[header_size], payload, payload_size); + ao2_lock(session); if (session->closing) { ao2_unlock(session); return -1; } - if (ast_careful_fwrite(session->f, session->fd, frame, header_size, session->timeout)) { - ao2_unlock(session); - /* 1011 - server terminating connection due to not being able to fulfill the request */ - ast_websocket_close(session, 1011); - return -1; - } - if (ast_careful_fwrite(session->f, session->fd, payload, actual_length, session->timeout)) { + if (ast_careful_fwrite(session->f, session->fd, frame, frame_size, session->timeout)) { ao2_unlock(session); /* 1011 - server terminating connection due to not being able to fulfill the request */ + ast_debug(1, "Closing WS with 1011 because we can't fulfill a write request\n"); ast_websocket_close(session, 1011); return -1; } + fflush(session->f); ao2_unlock(session);