http_server: adds WebSocket support

This commit adds the WebSocket support for esp_http_server
library. It mainly does:

- Handling WebSocket handshake
  - Parsing HTTP upgrade request
  - Reply the upgrade request
- Receive WebSocket packets
  - Parse header, decode to a struct
  - Unmask payload (if required)
- Send WebSocket frames
- Receive WebSocket frame
- Automatic control frame handling

Merges https://github.com/espressif/esp-idf/pull/4306
Closes https://github.com/espressif/esp-idf/issues/4819
This commit is contained in:
Jackson Ming Hu
2019-11-04 20:51:59 +11:00
committed by bot
parent 5172724092
commit e983042af2
8 changed files with 597 additions and 8 deletions

View File

@@ -172,6 +172,9 @@ esp_err_t httpd_register_uri_handler(httpd_handle_t handle,
hd->hd_calls[i]->method = uri_handler->method;
hd->hd_calls[i]->handler = uri_handler->handler;
hd->hd_calls[i]->user_ctx = uri_handler->user_ctx;
#ifdef CONFIG_HTTPD_WS_SUPPORT
hd->hd_calls[i]->is_websocket = uri_handler->is_websocket;
#endif
ESP_LOGD(TAG, LOG_FMT("[%d] installed %s"), i, uri_handler->uri);
return ESP_OK;
}
@@ -276,6 +279,7 @@ 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 */
@@ -307,6 +311,23 @@ esp_err_t httpd_uri(struct httpd_data *hd)
/* Attach user context data (passed during URI registration) into request */
req->user_ctx = uri->user_ctx;
/* Final step for a WebSocket handshake verification */
#ifdef CONFIG_HTTPD_WS_SUPPORT
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);
if (ret != ESP_OK) {
return ret;
}
aux->sd->ws_handshake_done = true;
aux->sd->ws_handler = uri->handler;
/* Return immediately after handshake, no need to call handler here */
return ESP_OK;
}
#endif
/* Invoke handler */
if (uri->handler(req) != ESP_OK) {
/* Handler returns error, this socket should be closed */