mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-14 12:59:29 +03:00
refactor(httpd): extract shared header field-value lookup helper
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2018-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -1046,6 +1046,60 @@ esp_err_t httpd_req_get_url_query_str_ptr(httpd_req_t *r, const char **buf, size
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Advance the scratch pointer past the current header line to the next one.
|
||||
* Header lines are separated by null characters (their line terminators are
|
||||
* overwritten with '\0' during parsing). */
|
||||
static const char *httpd_next_hdr(const char *hdr_ptr)
|
||||
{
|
||||
/* Jump to the end of the current field-value string */
|
||||
hdr_ptr = 1 + strchr(hdr_ptr, '\0');
|
||||
|
||||
/* Skip all null characters with which the line terminators were overwritten */
|
||||
while (*hdr_ptr == '\0') {
|
||||
hdr_ptr++;
|
||||
}
|
||||
return hdr_ptr;
|
||||
}
|
||||
|
||||
/* Locate the value of a header field within the request's scratch buffer.
|
||||
* Returns a pointer to the NULL-terminated value (leading spaces skipped),
|
||||
* or NULL if the field is not present. The caller must validate r/field and
|
||||
* the request pointer before calling. */
|
||||
static const char *httpd_find_hdr_value(struct httpd_req_aux *ra, const char *field)
|
||||
{
|
||||
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 field_len = strlen(field);
|
||||
|
||||
while (count--) {
|
||||
/* Search for the ':' character. Else, it would mean
|
||||
* that the field is invalid */
|
||||
const char *val_ptr = strchr(hdr_ptr, ':');
|
||||
if (!val_ptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the field does not match, continue searching. Compare lengths
|
||||
* first as the field from the header is not null terminated (has ':'
|
||||
* in the end). */
|
||||
if (((size_t)(val_ptr - hdr_ptr) != field_len) ||
|
||||
strncasecmp(hdr_ptr, field, field_len)) {
|
||||
if (count) {
|
||||
hdr_ptr = httpd_next_hdr(hdr_ptr);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip ':' and any preceding spaces */
|
||||
val_ptr++;
|
||||
while (*val_ptr == ' ') {
|
||||
val_ptr++;
|
||||
}
|
||||
return val_ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the length of the value string of a header request field */
|
||||
size_t httpd_req_get_hdr_value_len(httpd_req_t *r, const char *field)
|
||||
{
|
||||
@@ -1057,48 +1111,8 @@ size_t httpd_req_get_hdr_value_len(httpd_req_t *r, const char *field)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
while (count--) {
|
||||
/* Search for the ':' character. Else, it would mean
|
||||
* that the field is invalid
|
||||
*/
|
||||
const char *val_ptr = strchr(hdr_ptr, ':');
|
||||
if (!val_ptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the field, does not match, continue searching.
|
||||
* Compare lengths first as field from header is not
|
||||
* null terminated (has ':' in the end).
|
||||
*/
|
||||
if ((val_ptr - hdr_ptr != strlen(field)) ||
|
||||
(strncasecmp(hdr_ptr, field, strlen(field)))) {
|
||||
if (count) {
|
||||
/* Jump to end of header field-value string */
|
||||
hdr_ptr = 1 + strchr(hdr_ptr, '\0');
|
||||
|
||||
/* Skip all null characters (with which the line
|
||||
* terminators had been overwritten) */
|
||||
while (*hdr_ptr == '\0') {
|
||||
hdr_ptr++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip ':' */
|
||||
val_ptr++;
|
||||
|
||||
/* Skip preceding space */
|
||||
while ((*val_ptr != '\0') && (*val_ptr == ' ')) {
|
||||
val_ptr++;
|
||||
}
|
||||
return strlen(val_ptr);
|
||||
}
|
||||
return 0;
|
||||
const char *val_ptr = httpd_find_hdr_value(r->aux, field);
|
||||
return val_ptr ? strlen(val_ptr) : 0;
|
||||
}
|
||||
|
||||
/* Get the value of a field from the request headers */
|
||||
@@ -1112,58 +1126,21 @@ esp_err_t httpd_req_get_hdr_value_str(httpd_req_t *r, const char *field, char *v
|
||||
return ESP_ERR_HTTPD_INVALID_REQ;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
while (count--) {
|
||||
/* Search for the ':' character. Else, it would mean
|
||||
* that the field is invalid
|
||||
*/
|
||||
const char *val_ptr = strchr(hdr_ptr, ':');
|
||||
if (!val_ptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the field, does not match, continue searching.
|
||||
* Compare lengths first as field from header is not
|
||||
* null terminated (has ':' in the end).
|
||||
*/
|
||||
if ((val_ptr - hdr_ptr != strlen(field)) ||
|
||||
(strncasecmp(hdr_ptr, field, strlen(field)))) {
|
||||
if (count) {
|
||||
/* Jump to end of header field-value string */
|
||||
hdr_ptr = 1 + strchr(hdr_ptr, '\0');
|
||||
|
||||
/* Skip all null characters (with which the line
|
||||
* terminators had been overwritten) */
|
||||
while (*hdr_ptr == '\0') {
|
||||
hdr_ptr++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip ':' */
|
||||
val_ptr++;
|
||||
|
||||
/* Skip preceding space */
|
||||
while ((*val_ptr != '\0') && (*val_ptr == ' ')) {
|
||||
val_ptr++;
|
||||
}
|
||||
|
||||
/* 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 (val_size < full_size) {
|
||||
return ESP_ERR_HTTPD_RESULT_TRUNC;
|
||||
}
|
||||
return ESP_OK;
|
||||
const char *val_ptr = httpd_find_hdr_value(r->aux, field);
|
||||
if (val_ptr == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
|
||||
/* 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 terminating null. */
|
||||
size_t full_size = strlcpy(val, val_ptr, val_size);
|
||||
|
||||
/* If buffer length is smaller than needed, return truncation error */
|
||||
if (val_size < full_size) {
|
||||
return ESP_ERR_HTTPD_RESULT_TRUNC;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Helper function to get a cookie value from a cookie string of the type "cookie1=val1; cookie2=val2" */
|
||||
|
||||
Reference in New Issue
Block a user