diff --git a/components/esp_http_server/src/httpd_parse.c b/components/esp_http_server/src/httpd_parse.c index 6df2e4cb26..0979da0632 100644 --- a/components/esp_http_server/src/httpd_parse.c +++ b/components/esp_http_server/src/httpd_parse.c @@ -753,6 +753,12 @@ esp_err_t httpd_req_new(struct httpd_data *hd, struct sock_db *sd) sd->ws_handler != NULL ? "Yes" : "No", sd->ws_close ? "Yes" : "No"); if (sd->ws_handshake_done && sd->ws_handler != NULL) { + if (sd->ws_close == true) { + /* WS was marked as close state, do not deal with this socket */ + ESP_LOGD(TAG, LOG_FMT("WS was marked close")); + return ESP_OK; + } + ret = httpd_ws_get_frame_type(r); ESP_LOGD(TAG, LOG_FMT("New WS request from existing socket, ws_type=%d"), ra->ws_type); diff --git a/components/esp_http_server/src/httpd_ws.c b/components/esp_http_server/src/httpd_ws.c index 4a4c2373df..86b8f05ee4 100644 --- a/components/esp_http_server/src/httpd_ws.c +++ b/components/esp_http_server/src/httpd_ws.c @@ -482,6 +482,25 @@ esp_err_t httpd_ws_get_frame_type(httpd_req_t *req) /* Now turn the frame to PONG */ frame.type = HTTPD_WS_TYPE_PONG; return httpd_ws_send_frame(req, &frame); + } else if (aux->ws_type == HTTPD_WS_TYPE_CLOSE) { + ESP_LOGD(TAG, LOG_FMT("Got a WS CLOSE frame, Replying CLOSE...")); + + /* Read the rest of the CLOSE frame and response */ + /* Please refer to RFC6455 Section 5.5.1 for more details */ + httpd_ws_frame_t frame; + uint8_t frame_buf[128] = { 0 }; + memset(&frame, 0, sizeof(httpd_ws_frame_t)); + frame.payload = frame_buf; + + if (httpd_ws_recv_frame(req, &frame, 126) != ESP_OK) { + ESP_LOGD(TAG, LOG_FMT("Cannot receive the full CLOSE frame")); + return ESP_ERR_INVALID_STATE; + } + + frame.len = 0; + frame.type = HTTPD_WS_TYPE_CLOSE; + frame.payload = NULL; + return httpd_ws_send_frame(req, &frame); } return ESP_OK;