Skip to content

Commit 9f6ab55

Browse files
committed
feat(http_server): Added API to get scratch buffer data
1. Added the API in esp_http_server to get the raw headers data from the scratch buffer. 2. This data will be unparsed. Closes #15857
1 parent d73e172 commit 9f6ab55

File tree

6 files changed

+103
-1
lines changed

6 files changed

+103
-1
lines changed

components/esp_http_server/include/esp_http_server.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,6 +1813,44 @@ esp_err_t httpd_ws_send_data_async(httpd_handle_t handle, int socket, httpd_ws_f
18131813
* @}
18141814
*/
18151815

1816+
/**
1817+
* @brief Get the length of the raw request data received from the client.
1818+
*
1819+
* @param[in] req Current request
1820+
* @return
1821+
* - 0 : If req is NULL
1822+
* - size_t : The length of the buffer containing raw HTTP request data
1823+
*/
1824+
size_t httpd_get_raw_req_data_len(httpd_req_t *req);
1825+
1826+
/**
1827+
* @brief Get the raw HTTP request data received from the client.
1828+
*
1829+
* NOTE - This function returns different data for different http server states.
1830+
* 1. HTTP_SERVER_EVENT_ON_CONNECTED - Returns the data containing information related to URI and headers.
1831+
* 2. HTTP_SERVER_EVENT_ON_HEADER - Returns the data containing information related to only headers.
1832+
* 3. HTTP_SERVER_EVENT_ON_DATA - Returns the data containing information related to only headers.
1833+
* 4. HTTP_SERVER_EVENT_SENT_DATA - Returns the data containing information related to only headers.
1834+
* 5. HTTP_SERVER_EVENT_DISCONNECTED - Returns the data containing information related to only headers.
1835+
* 6. HTTP_SERVER_EVENT_STOP - Returns the data containing information related to only headers.
1836+
*
1837+
* @param[in] req Current request
1838+
* @param[out] buf Buffer to store the raw request data
1839+
* @param[in] buf_len The length of the buffer.
1840+
* @return
1841+
* - ESP_OK : On successful copy of raw request data
1842+
* - ESP_ERR_INVALID_ARG : If req or buf is NULL, or buf_len is 0
1843+
*/
1844+
esp_err_t httpd_get_raw_req_data(httpd_req_t *req, char *buf, size_t buf_len);
1845+
1846+
/**
1847+
* @brief Get the HTTPD server state
1848+
*
1849+
* @param[in] handle Handle to server returned by httpd_start
1850+
* @return HTTPD server state
1851+
*/
1852+
esp_http_server_event_id_t httpd_get_server_state(httpd_handle_t handle);
1853+
18161854
#ifdef __cplusplus
18171855
}
18181856
#endif

components/esp_http_server/src/esp_httpd_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct httpd_data {
127127
struct httpd_req hd_req; /*!< The current HTTPD request */
128128
struct httpd_req_aux hd_req_aux; /*!< Additional data about the HTTPD request kept unexposed */
129129
uint64_t lru_counter; /*!< LRU counter */
130+
esp_http_server_event_id_t http_server_state; /*!< HTTPD server state */
130131

131132
/* Array of registered error handler functions */
132133
httpd_err_handler_func_t *err_handler_fns;

components/esp_http_server/src/httpd_main.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -126,6 +126,7 @@ static esp_err_t httpd_accept_conn(struct httpd_data *hd, int listen_fd)
126126
goto exit;
127127
}
128128
ESP_LOGD(TAG, LOG_FMT("complete"));
129+
hd->http_server_state = HTTP_SERVER_EVENT_ON_CONNECTED;
129130
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_ON_CONNECTED, &new_fd, sizeof(int));
130131
return ESP_OK;
131132
exit:
@@ -539,6 +540,7 @@ esp_err_t httpd_start(httpd_handle_t *handle, const httpd_config_t *config)
539540
}
540541

541542
*handle = (httpd_handle_t)hd;
543+
hd->http_server_state = HTTP_SERVER_EVENT_START;
542544
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_START, NULL, 0);
543545

544546
return ESP_OK;
@@ -593,3 +595,12 @@ esp_err_t httpd_stop(httpd_handle_t handle)
593595
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_STOP, NULL, 0);
594596
return ESP_OK;
595597
}
598+
599+
esp_http_server_event_id_t httpd_get_server_state(httpd_handle_t handle)
600+
{
601+
struct httpd_data *hd = (struct httpd_data *) handle;
602+
if (hd == NULL) {
603+
return HTTP_SERVER_EVENT_ERROR;
604+
}
605+
return hd->http_server_state;
606+
}

components/esp_http_server/src/httpd_parse.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,8 @@ static esp_err_t cb_headers_complete(http_parser *parser)
408408

409409
parser_data->status = PARSING_BODY;
410410
ra->remaining_len = r->content_len;
411+
struct httpd_data *hd = (struct httpd_data *) r->handle;
412+
hd->http_server_state = HTTP_SERVER_EVENT_ON_HEADER;
411413
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_ON_HEADER, &(ra->sd->fd), sizeof(int));
412414
return ESP_OK;
413415
}
@@ -1209,3 +1211,44 @@ esp_err_t httpd_req_get_cookie_val(httpd_req_t *req, const char *cookie_name, ch
12091211
return ret;
12101212

12111213
}
1214+
1215+
/* Get the length of the raw request data received from the client.
1216+
*/
1217+
size_t httpd_get_raw_req_data_len(httpd_req_t *req)
1218+
{
1219+
if (req == NULL) {
1220+
return 0;
1221+
}
1222+
struct httpd_req_aux *ra = req->aux;
1223+
return ra->scratch_cur_size;
1224+
}
1225+
1226+
/* Get the raw request data, which contains the raw HTTP request headers and
1227+
* URI related information. Internally, the httpd_parse.c file uses a scratch buffer
1228+
* to store the original HTTP request data exactly as received from the client.
1229+
* This function returns the contents of this scratch buffer.
1230+
*
1231+
* NOTE - This function returns different data for different http server states.
1232+
* 1. HTTP_SERVER_EVENT_ON_CONNECTED - Returns the data containing information related to URI and headers.
1233+
* 2. HTTP_SERVER_EVENT_ON_HEADER - Returns the data containing information related to only headers.
1234+
* 3. HTTP_SERVER_EVENT_ON_DATA - Returns the data containing information related to only headers.
1235+
* 4. HTTP_SERVER_EVENT_SENT_DATA - Returns the data containing information related to only headers.
1236+
* 5. HTTP_SERVER_EVENT_DISCONNECTED - Returns the data containing information related to only headers.
1237+
* 6. HTTP_SERVER_EVENT_STOP - Returns the data containing information related to only headers.
1238+
*/
1239+
esp_err_t httpd_get_raw_req_data(httpd_req_t *req, char *buf, size_t buf_len)
1240+
{
1241+
if (req == NULL || buf == NULL) {
1242+
return ESP_ERR_INVALID_ARG;
1243+
}
1244+
if (buf_len == 0) {
1245+
return ESP_ERR_INVALID_ARG;
1246+
}
1247+
if (req->aux == NULL) {
1248+
ESP_LOGW(TAG, "Request auxiliary data is NULL for URI: [%s]", req->uri ? req->uri : "(null)");
1249+
return ESP_ERR_INVALID_ARG;
1250+
}
1251+
struct httpd_req_aux *ra = req->aux;
1252+
memcpy(buf, ra->scratch, buf_len);
1253+
return ESP_OK;
1254+
}

components/esp_http_server/src/httpd_sess.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ static void httpd_sess_close(void *arg)
146146
}
147147
sock_db->lru_socket = false;
148148
struct httpd_data *hd = (struct httpd_data *) sock_db->handle;
149+
hd->http_server_state = HTTP_SERVER_EVENT_DISCONNECTED;
149150
httpd_sess_delete(hd, sock_db);
150151
}
151152

@@ -374,6 +375,7 @@ void httpd_sess_delete(struct httpd_data *hd, struct sock_db *session)
374375
} else {
375376
close(session->fd);
376377
}
378+
hd->http_server_state = HTTP_SERVER_EVENT_DISCONNECTED;
377379
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_DISCONNECTED, &session->fd, sizeof(int));
378380

379381
// clear all contexts

components/esp_http_server/src/httpd_txrx.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, ssize_t buf_len)
294294
if (httpd_send_all(r, cr_lf_seperator, strlen(cr_lf_seperator)) != ESP_OK) {
295295
return ESP_ERR_HTTPD_RESP_SEND;
296296
}
297+
struct httpd_data *hd = (struct httpd_data *) r->handle;
298+
hd->http_server_state = HTTP_SERVER_EVENT_HEADERS_SENT;
297299
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_HEADERS_SENT, &(ra->sd->fd), sizeof(int));
298300

299301
/* Sending content */
@@ -306,6 +308,7 @@ esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, ssize_t buf_len)
306308
.fd = ra->sd->fd,
307309
.data_len = buf_len,
308310
};
311+
hd->http_server_state = HTTP_SERVER_EVENT_SENT_DATA;
309312
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_SENT_DATA, &evt_data, sizeof(esp_http_server_event_data));
310313
return ESP_OK;
311314
}
@@ -325,6 +328,7 @@ esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, ssize_t buf_len
325328
}
326329

327330
struct httpd_req_aux *ra = r->aux;
331+
struct httpd_data *hd = (struct httpd_data *) r->handle;
328332
const char *httpd_chunked_hdr_str = "HTTP/1.1 %s\r\nContent-Type: %s\r\nTransfer-Encoding: chunked\r\n";
329333
const char *colon_separator = ": ";
330334
const char *cr_lf_seperator = "\r\n";
@@ -404,6 +408,7 @@ esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, ssize_t buf_len
404408
.fd = ra->sd->fd,
405409
.data_len = buf_len,
406410
};
411+
hd->http_server_state = HTTP_SERVER_EVENT_SENT_DATA;
407412
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_SENT_DATA, &evt_data, sizeof(esp_http_server_event_data));
408413

409414
return ESP_OK;
@@ -613,6 +618,8 @@ int httpd_req_recv(httpd_req_t *r, char *buf, size_t buf_len)
613618
}
614619
ra->remaining_len -= ret;
615620
ESP_LOGD(TAG, LOG_FMT("received length = %d"), ret);
621+
struct httpd_data *hd = (struct httpd_data *) r->handle;
622+
hd->http_server_state = HTTP_SERVER_EVENT_ON_DATA;
616623
esp_http_server_event_data evt_data = {
617624
.fd = ra->sd->fd,
618625
.data_len = ret,

0 commit comments

Comments
 (0)