Skip to content

Commit b6d4fa2

Browse files
hrushikesh430mahavirj
authored andcommitted
fix(async_handler): Async handler example scratch buffer fix
1. In httpd_req_async_handler_begin, the httpd_req_aux is locally malloced and data is done memcpy to local httpd_req_aux from request'ss httpd_req_aux for async request use-case, this causes scartch pointer from these two structs pointing to same memory address. 2. In current workflow, the request's sratch buffer is freed in httpd_parse.c httpd_req_cleanup api. Therefore if the user try to fetch the data (like headers) from the scratch buffer, data will be not available. 3. Each request should have the deep copy of the scratch buffer. To retrive the data later. Closes #15587
1 parent fc5bf27 commit b6d4fa2

File tree

2 files changed

+48
-1
lines changed
  • components/esp_http_server/src
  • examples/protocols/http_server/async_handlers/main

2 files changed

+48
-1
lines changed

components/esp_http_server/src/httpd_txrx.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,18 @@ esp_err_t httpd_req_async_handler_begin(httpd_req_t *r, httpd_req_t **out)
647647
struct httpd_req_aux *async_aux = (struct httpd_req_aux *) async->aux;
648648
struct httpd_req_aux *r_aux = (struct httpd_req_aux *) r->aux;
649649

650+
if (r_aux->scratch) {
651+
async_aux->scratch = malloc(r_aux->scratch_cur_size);
652+
if (async_aux->scratch == NULL) {
653+
free(async_aux);
654+
free(async);
655+
return ESP_ERR_NO_MEM;
656+
}
657+
memcpy(async_aux->scratch, r_aux->scratch, r_aux->scratch_cur_size);
658+
} else {
659+
async_aux->scratch = NULL;
660+
}
661+
650662
async_aux->resp_hdrs = calloc(hd->config.max_resp_headers, sizeof(struct resp_hdr));
651663
if (async_aux->resp_hdrs == NULL) {
652664
free(async_aux);

examples/protocols/http_server/async_handlers/main/main.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,42 @@ static esp_err_t queue_request(httpd_req_t *req, httpd_req_handler_t handler)
9595
/* handle long request (on async thread) */
9696
static esp_err_t long_async(httpd_req_t *req)
9797
{
98-
ESP_LOGI(TAG, "running: /long");
98+
char* buf;
99+
size_t buf_len;
100+
101+
/* Get URI */
102+
ESP_LOGI(TAG, "Request URI: %s", req->uri);
103+
104+
/* Get header value string length and allocate memory for length + 1,
105+
* extra byte for null termination */
106+
buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;
107+
if (buf_len > 1) {
108+
buf = malloc(buf_len);
109+
if (buf == NULL) {
110+
ESP_LOGE(TAG, "Failed to allocate memory for headers");
111+
return ESP_FAIL;
112+
}
113+
/* Copy null terminated value string into buffer */
114+
if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
115+
ESP_LOGI(TAG, "Found header => Host: %s", buf);
116+
}
117+
free(buf);
118+
}
119+
/* Get query string length and allocate memory for length + 1,
120+
* extra byte for null termination */
121+
buf_len = httpd_req_get_url_query_len(req) + 1;
122+
if (buf_len > 1) {
123+
buf = malloc(buf_len);
124+
if (buf == NULL) {
125+
ESP_LOGE(TAG, "Failed to allocate memory for query string");
126+
return ESP_FAIL;
127+
}
128+
/* Copy null terminated query string into buffer */
129+
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
130+
ESP_LOGI(TAG, "Found query string => %s", buf);
131+
}
132+
free(buf);
133+
}
99134

100135
// track the number of long requests
101136
static uint8_t req_count = 0;

0 commit comments

Comments
 (0)