Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http: Function to get Cookie value from request. (IDFGH-5548) #7273

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions components/esp_http_server/include/esp_http_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,43 @@ esp_err_t httpd_req_get_url_query_str(httpd_req_t *r, char *buf, size_t buf_len)
*/
esp_err_t httpd_query_key_value(const char *qry, const char *key, char *val, size_t val_size);

/**
* @brief Helper function to get a cookie value from a cookie
* string of the type "cookie1=val1; cookie2=val2"
*
* @note
* - If actual value size is greater than val_size, then the value is truncated,
* accompanied by truncation error as return value.
*
* @param[in] cookie_str Pointer to cookie string
* @param[in] key The key to be searched in the cookie string
* @param[out] val Pointer to the buffer into which the value will be copied if the key is found
* @param[in] val_size Size of the user buffer "val"
*
* @return
* - ESP_OK : Key is found in the cookie string and copied to buffer
* - ESP_ERR_NOT_FOUND : Key not found
* - ESP_ERR_INVALID_ARG : Null arguments
* - ESP_ERR_HTTPD_RESULT_TRUNC : Value string truncated
*/
esp_err_t httpd_cookie_key_value(const char *cookie_str, const char *key, char *val, size_t val_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patrykkrz Any reason for adding this API in header file?
Will this be used from application? Or it is just a helper API for httpd_req_get_cookie_val?


/**
* @brief Get the value string of a cookie value from the "Cookie" request headers by cookie name.
*
* @param[in] req Pointer to the HTTP request
* @param[in] cookie_name The cookie name to be searched in the request
* @param[out] val Pointer to the buffer into which the value of cookie will be copied if the cookie is found
* @param[in] val_size Size of the user buffer "val"
*
* @return
* - ESP_OK : Key is found in the cookie string and copied to buffer
* - ESP_ERR_NOT_FOUND : Key not found
* - ESP_ERR_INVALID_ARG : Null arguments
* - ESP_ERR_HTTPD_RESULT_TRUNC : Value string truncated
*/
esp_err_t httpd_req_get_cookie_val(httpd_req_t *req, const char *cookie_name, char *val, size_t val_size);

/**
* @brief Test if a URI matches the given wildcard template.
*
Expand Down
81 changes: 81 additions & 0 deletions components/esp_http_server/src/httpd_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1070,3 +1070,84 @@ esp_err_t httpd_req_get_hdr_value_str(httpd_req_t *r, const char *field, char *v
}
return ESP_ERR_NOT_FOUND;
}

/* Helper function to get a cookie value from a cookie string of the type "cookie1=val1; cookie2=val2" */
esp_err_t httpd_cookie_key_value(const char *cookie_str, const char *key, char *val, size_t val_size)
{
if(cookie_str == NULL || key == NULL || val == NULL) {
return ESP_ERR_INVALID_ARG;
}

const char *cookie_ptr = cookie_str;
const size_t buf_len = val_size;

while(strlen(cookie_ptr)) {
/* Search for the '=' character. Else, it would mean
* that the parameter is invalid */
const char *val_ptr = strchr(cookie_ptr, '=');
if(!val_ptr) {
break;
}
size_t offset = val_ptr - cookie_ptr;

/* If the key, does not match, continue searching.
* Compare lengths first as key from cookie string is not
* null terminated (has '=' in the end) */
if((offset != strlen(key)) || (strncmp(cookie_ptr, key, offset))) {
/* Get the name=val string. Multiple name=value pairs
* are separated by '; ' */
cookie_ptr = strchr(val_ptr, ' ');
if(!cookie_ptr) {
break;
}
cookie_ptr++;
continue;
}

/* Locate start of next query */
cookie_ptr = strchr(++val_ptr, ';');
/* Or this could be the last query, in which
* case get to the end of query string */
if(!cookie_ptr) {
cookie_ptr = val_ptr + strlen(val_ptr);
}

/* Update value length, including one byte for null */
val_size = cookie_ptr - val_ptr + 1;

/* Copy value to the caller's buffer. */
strlcpy(val, val_ptr, MIN(val_size, buf_len));

/* If buffer length is smaller than needed, return truncation error */
if(buf_len < val_size) {
return ESP_ERR_HTTPD_RESULT_TRUNC;
}
return ESP_OK;
}
ESP_LOGD(TAG, LOG_FMT("cookie %s not found"), key);
return ESP_ERR_NOT_FOUND;
}

/* Get the value of a cookie from the request headers */
esp_err_t httpd_req_get_cookie_val(httpd_req_t *req, const char *cookie_name, char *val, size_t val_size)
{
esp_err_t ret;
size_t hdr_len_cookie = httpd_req_get_hdr_value_len(req, "Cookie");
char *cookie_str;

if(hdr_len_cookie <= 0) {
return ESP_ERR_NOT_FOUND;
}
cookie_str = malloc(hdr_len_cookie + 1);

if(httpd_req_get_hdr_value_str(req, "Cookie", cookie_str, hdr_len_cookie + 1) != ESP_OK) {
ESP_LOGW(TAG, "Not Found Cookie in header uri:[%s]", req->uri);
free(cookie_str);
return ESP_ERR_NOT_FOUND;
}

ret = httpd_cookie_key_value(cookie_str, cookie_name, val, val_size);
free(cookie_str);
return ret;

}