Merge branch 'contrib/github_pr_15288' into 'master'

Improve httpd string value fetching efficiency (GitHub PR)

Closes IDFGH-14524

See merge request espressif/esp-idf!37301
This commit is contained in:
Mahavir Jain
2025-04-06 19:17:28 +08:00

View File

@@ -79,10 +79,11 @@ static esp_err_t verify_url (http_parser *parser)
return ESP_FAIL;
}
/* Keep URI with terminating null character. Note URI string pointed
/* Copy URI and append terminating null character. Note URI string pointed
* by 'at' is not NULL terminated, therefore use length provided by
* parser while copying the URI to buffer */
strlcpy((char *)r->uri, at, (length + 1));
memcpy((char *)r->uri, at, length);
((char *)r->uri)[length] = '\0';
ESP_LOGD(TAG, LOG_FMT("received URI = %s"), r->uri);
/* Make sure version is HTTP/1.1 or HTTP/1.0 (legacy compliance purpose) */
@@ -95,7 +96,7 @@ static esp_err_t verify_url (http_parser *parser)
/* Parse URL and keep result for later */
http_parser_url_init(res);
if (http_parser_parse_url(r->uri, strlen(r->uri),
if (http_parser_parse_url(r->uri, length,
r->method == HTTP_CONNECT, res)) {
ESP_LOGW(TAG, LOG_FMT("http_parser_parse_url failed with errno = %d"),
parser->http_errno);
@@ -884,8 +885,7 @@ esp_err_t httpd_query_key_value(const char *qry_str, const char *key, char *val,
return ESP_ERR_INVALID_ARG;
}
const char *qry_ptr = qry_str;
const size_t buf_len = val_size;
const char *qry_ptr = qry_str;
while (strlen(qry_ptr)) {
/* Search for the '=' character. Else, it would mean
@@ -919,16 +919,18 @@ esp_err_t httpd_query_key_value(const char *qry_str, const char *key, char *val,
qry_ptr = val_ptr + strlen(val_ptr);
}
/* Update value length, including one byte for null */
val_size = qry_ptr - val_ptr + 1;
/* Query value length does not include terminating null */
size_t val_len = qry_ptr - val_ptr;
/* Copy value to the caller's buffer. */
strlcpy(val, val_ptr, MIN(val_size, buf_len));
size_t copy_len = MIN(val_len, val_size - 1);
/* If buffer length is smaller than needed, return truncation error */
if (buf_len < val_size) {
if (copy_len < val_len) {
return ESP_ERR_HTTPD_RESULT_TRUNC;
}
memcpy(val, val_ptr, copy_len);
val[copy_len] = '\0';
return ESP_OK;
}
ESP_LOGD(TAG, LOG_FMT("key %s not found"), key);
@@ -982,14 +984,17 @@ esp_err_t httpd_req_get_url_query_str(httpd_req_t *r, char *buf, size_t buf_len)
if (res->field_set & (1 << UF_QUERY)) {
const char *qry = r->uri + res->field_data[UF_QUERY].off;
/* Minimum required buffer len for keeping
* null terminated query string */
size_t min_buf_len = res->field_data[UF_QUERY].len + 1;
/* Query data length does not include terminating null */
size_t data_len = res->field_data[UF_QUERY].len;
strlcpy(buf, qry, MIN(buf_len, min_buf_len));
if (buf_len < min_buf_len) {
/* Copy data to the caller's buffer. */
size_t copy_len = MIN(data_len, buf_len - 1);
if (copy_len < data_len) {
return ESP_ERR_HTTPD_RESULT_TRUNC;
}
memcpy(buf, qry, copy_len);
buf[copy_len] = '\0';
return ESP_OK;
}
return ESP_ERR_NOT_FOUND;
@@ -1064,7 +1069,6 @@ esp_err_t httpd_req_get_hdr_value_str(httpd_req_t *r, const char *field, char *v
struct httpd_req_aux *ra = r->aux;
const char *hdr_ptr = ra->scratch; /*!< Request headers are kept in scratch buffer */
unsigned count = ra->req_hdrs_count; /*!< Count set during parsing */
const size_t buf_len = val_size;
while (count--) {
/* Search for the ':' character. Else, it would mean
@@ -1102,14 +1106,13 @@ esp_err_t httpd_req_get_hdr_value_str(httpd_req_t *r, const char *field, char *v
val_ptr++;
}
/* Get the NULL terminated value and copy it to the caller's buffer. */
strlcpy(val, val_ptr, buf_len);
/* Update value length, including one byte for null */
val_size = strlen(val_ptr) + 1;
/* Get the NULL terminated value and copy it to the caller's buffer.
* Note `strlcpy()` will always return the size of the source string
* including terminimating null.*/
size_t full_size = strlcpy(val, val_ptr, val_size);
/* If buffer length is smaller than needed, return truncation error */
if (buf_len < val_size) {
if (val_size < full_size) {
return ESP_ERR_HTTPD_RESULT_TRUNC;
}
return ESP_OK;
@@ -1125,8 +1128,6 @@ esp_err_t static httpd_cookie_key_value(const char *cookie_str, const char *key,
}
const char *cookie_ptr = cookie_str;
const size_t buf_len = *val_size;
size_t _val_size = *val_size;
while (strlen(cookie_ptr)) {
/* Search for the '=' character. Else, it would mean
@@ -1159,19 +1160,21 @@ esp_err_t static httpd_cookie_key_value(const char *cookie_str, const char *key,
cookie_ptr = val_ptr + strlen(val_ptr);
}
/* Update value length, including one byte for null */
_val_size = cookie_ptr - val_ptr + 1;
/* Cookie value length does not include terminating null */
size_t val_len = cookie_ptr - val_ptr;
/* Copy value to the caller's buffer. */
strlcpy(val, val_ptr, MIN(_val_size, buf_len));
size_t copy_len = MIN(val_len, *val_size - 1);
/* If buffer length is smaller than needed, return truncation error */
if (buf_len < _val_size) {
*val_size = _val_size;
if (copy_len < val_len) {
return ESP_ERR_HTTPD_RESULT_TRUNC;
}
/* Save amount of bytes copied to caller's buffer */
*val_size = MIN(_val_size, buf_len);
memcpy(val, val_ptr, copy_len);
val[copy_len] = '\0';
/* Save actual Cookie value size (including terminating null) */
*val_size = copy_len + 1;
return ESP_OK;
}
ESP_LOGD(TAG, LOG_FMT("cookie %s not found"), key);