mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/fix_ws_ping_receive' into 'master'
fix(websocket): Support handler deal with PING and CLOSE frame Closes IDFGH-7209 See merge request espressif/esp-idf!18065
This commit is contained in:
commit
52769051e2
@ -445,6 +445,12 @@ esp_err_t httpd_ws_get_frame_type(httpd_req_t *req)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
struct sock_db *sd = aux->sd;
|
||||
if (sd == NULL) {
|
||||
ESP_LOGW(TAG, LOG_FMT("Invalid sd pointer"));
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Read the first byte from the frame to get the FIN flag and Opcode */
|
||||
/* Please refer to RFC6455 Section 5.2 for more details */
|
||||
uint8_t first_byte = 0;
|
||||
@ -463,46 +469,50 @@ esp_err_t httpd_ws_get_frame_type(httpd_req_t *req)
|
||||
aux->ws_final = (first_byte & HTTPD_WS_FIN_BIT) != 0;
|
||||
aux->ws_type = (first_byte & HTTPD_WS_OPCODE_BITS);
|
||||
|
||||
/* Reply to PING. For PONG and CLOSE, it will be handled elsewhere. */
|
||||
if(aux->ws_type == HTTPD_WS_TYPE_PING) {
|
||||
ESP_LOGD(TAG, LOG_FMT("Got a WS PING frame, Replying PONG..."));
|
||||
/* If userspace requests control frames, do not deal with the control frames */
|
||||
if (!sd->ws_control_frames) {
|
||||
ESP_LOGD(TAG, LOG_FMT("Handler not requests control frames"));
|
||||
|
||||
/* Read the rest of the PING frame, for PONG to reply back. */
|
||||
/* Please refer to RFC6455 Section 5.5.2 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;
|
||||
/* Reply to PING. For PONG and CLOSE, it will be handled elsewhere. */
|
||||
if (aux->ws_type == HTTPD_WS_TYPE_PING) {
|
||||
ESP_LOGD(TAG, LOG_FMT("Got a WS PING frame, Replying PONG..."));
|
||||
|
||||
if(httpd_ws_recv_frame(req, &frame, 126) != ESP_OK) {
|
||||
ESP_LOGD(TAG, LOG_FMT("Cannot receive the full PING frame"));
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
/* Read the rest of the PING frame, for PONG to reply back. */
|
||||
/* Please refer to RFC6455 Section 5.5.2 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 PING frame"));
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -74,8 +74,18 @@ static esp_err_t ws_handler(httpd_req_t *req)
|
||||
httpd_req_to_sockfd(req));
|
||||
|
||||
// If it was a TEXT message, just echo it back
|
||||
} else if (ws_pkt.type == HTTPD_WS_TYPE_TEXT) {
|
||||
ESP_LOGI(TAG, "Received packet with message: %s", ws_pkt.payload);
|
||||
} else if (ws_pkt.type == HTTPD_WS_TYPE_TEXT || ws_pkt.type == HTTPD_WS_TYPE_PING || ws_pkt.type == HTTPD_WS_TYPE_CLOSE) {
|
||||
if (ws_pkt.type == HTTPD_WS_TYPE_TEXT) {
|
||||
ESP_LOGI(TAG, "Received packet with message: %s", ws_pkt.payload);
|
||||
} else if (ws_pkt.type == HTTPD_WS_TYPE_PING) {
|
||||
// Response PONG packet to peer
|
||||
ESP_LOGI(TAG, "Got a WS PING frame, Replying PONG");
|
||||
ws_pkt.type = HTTPD_WS_TYPE_PONG;
|
||||
} else if (ws_pkt.type == HTTPD_WS_TYPE_CLOSE) {
|
||||
// Response CLOSE packet with no payload to peer
|
||||
ws_pkt.len = 0;
|
||||
ws_pkt.payload = NULL;
|
||||
}
|
||||
ret = httpd_ws_send_frame(req, &ws_pkt);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "httpd_ws_send_frame failed with %d", ret);
|
||||
|
@ -143,6 +143,16 @@ def test_examples_protocol_https_wss_server(dut: Dut) -> None:
|
||||
raise RuntimeError('Failed to receive the correct echo response')
|
||||
logging.info('Correct echo response obtained from the wss server')
|
||||
|
||||
# Test for PING
|
||||
logging.info('Testing for send PING')
|
||||
ws.write(data=DATA, opcode=OPCODE_PING)
|
||||
dut.expect('Got a WS PING frame, Replying PONG')
|
||||
opcode, data = ws.read()
|
||||
data = data.decode('UTF-8')
|
||||
if data != DATA or opcode != OPCODE_PONG:
|
||||
raise RuntimeError('Failed to receive the PONG response')
|
||||
logging.info('Passed the test for PING')
|
||||
|
||||
# Test for keepalive
|
||||
logging.info('Testing for keep alive (approx time = 20s)')
|
||||
start_time = time.time()
|
||||
|
Loading…
Reference in New Issue
Block a user