http_server: websocket server to support async send

This commit is contained in:
David Cermak
2020-03-11 10:03:12 +01:00
committed by bot
parent d7b3a051f0
commit 1b842ce1a8
9 changed files with 111 additions and 29 deletions
@@ -690,7 +690,9 @@ static void init_req_aux(struct httpd_req_aux *ra, httpd_config_t *config)
ra->first_chunk_sent = 0;
ra->req_hdrs_count = 0;
ra->resp_hdrs_count = 0;
#if CONFIG_HTTPD_WS_SUPPORT
ra->ws_handshake_detect = false;
#endif
memset(ra->resp_hdrs, 0, config->max_resp_headers * sizeof(struct resp_hdr));
}
@@ -703,11 +705,13 @@ static void httpd_req_cleanup(httpd_req_t *r)
httpd_sess_free_ctx(ra->sd->ctx, ra->sd->free_ctx);
}
#if CONFIG_HTTPD_WS_SUPPORT
/* Close the socket when a WebSocket Close request is received */
if (ra->sd->ws_close) {
ESP_LOGD(TAG, LOG_FMT("Try closing WS connection at FD: %d"), ra->sd->fd);
httpd_sess_trigger_close(r->handle, ra->sd->fd);
}
#endif
/* Retrieve session info from the request into the socket database. */
ra->sd->ctx = r->sess_ctx;
+1 -1
View File
@@ -279,7 +279,6 @@ esp_err_t httpd_uri(struct httpd_data *hd)
{
httpd_uri_t *uri = NULL;
httpd_req_t *req = &hd->hd_req;
struct httpd_req_aux *aux = req->aux;
struct http_parser_url *res = &hd->hd_req_aux.url_parse_res;
/* For conveying URI not found/method not allowed */
@@ -313,6 +312,7 @@ esp_err_t httpd_uri(struct httpd_data *hd)
/* Final step for a WebSocket handshake verification */
#ifdef CONFIG_HTTPD_WS_SUPPORT
struct httpd_req_aux *aux = req->aux;
if (uri->is_websocket && aux->ws_handshake_detect && uri->method == HTTP_GET) {
ESP_LOGD(TAG, LOG_FMT("Responding WS handshake to sock %d"), aux->sd->fd);
esp_err_t ret = httpd_ws_respond_server_handshake(&hd->hd_req);
+13 -3
View File
@@ -26,7 +26,7 @@
#ifdef CONFIG_HTTPD_WS_SUPPORT
#define TAG "httpd_ws"
static const char *TAG="httpd_ws";
/*
* Bit masks for WebSocket frames.
@@ -266,6 +266,11 @@ esp_err_t httpd_ws_send_frame(httpd_req_t *req, httpd_ws_frame_t *frame)
if (ret != ESP_OK) {
return ret;
}
return httpd_ws_send_frame_async(req->handle, httpd_req_to_sockfd(req), frame);
}
esp_err_t httpd_ws_send_frame_async(httpd_handle_t hd, int fd, httpd_ws_frame_t *frame)
{
if (!frame) {
ESP_LOGW(TAG, LOG_FMT("Argument is invalid"));
return ESP_ERR_INVALID_ARG;
@@ -299,15 +304,20 @@ esp_err_t httpd_ws_send_frame(httpd_req_t *req, httpd_ws_frame_t *frame)
/* WebSocket server does not required to mask response payload, so leave the MASK bit as 0. */
header_buf[1] &= (~HTTPD_WS_MASK_BIT);
struct sock_db *sess = httpd_sess_get(hd, fd);
if (!sess) {
return ESP_ERR_INVALID_ARG;
}
/* Send off header */
if (httpd_send(req, (const char *)header_buf, tx_len) < 0) {
if (sess->send_fn(hd, fd, (const char *)header_buf, tx_len, 0) < 0) {
ESP_LOGW(TAG, LOG_FMT("Failed to send WS header"));
return ESP_FAIL;
}
/* Send off payload */
if(frame->len > 0 && frame->payload != NULL) {
if (httpd_send(req, (const char *)frame->payload, frame->len) < 0) {
if (sess->send_fn(hd, fd, (const char *)frame->payload, frame->len, 0) < 0) {
ESP_LOGW(TAG, LOG_FMT("Failed to send WS payload"));
return ESP_FAIL;
}