ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
utils.cpp
Go to the documentation of this file.
1#ifdef USE_ESP32
2#include <cstring>
3#include <cctype>
5#include "http_parser.h"
6
7#include "utils.h"
8
10
11size_t url_decode(char *str) {
12 char *start = str;
13 char *ptr = str, buf;
14 for (; *str; str++, ptr++) {
15 if (*str == '%') {
16 str++;
17 if (parse_hex(str, 2, reinterpret_cast<uint8_t *>(&buf), 1) == 2) {
18 *ptr = buf;
19 str++;
20 } else {
21 str--;
22 *ptr = *str;
23 }
24 } else if (*str == '+') {
25 *ptr = ' ';
26 } else {
27 *ptr = *str;
28 }
29 }
30 *ptr = '\0';
31 return ptr - start;
32}
33
34bool request_has_header(httpd_req_t *req, const char *name) { return httpd_req_get_hdr_value_len(req, name); }
35
36optional<std::string> request_get_header(httpd_req_t *req, const char *name) {
37 size_t len = httpd_req_get_hdr_value_len(req, name);
38 if (len == 0) {
39 return {};
40 }
41
42 std::string str;
43 str.resize(len);
44
45 auto res = httpd_req_get_hdr_value_str(req, name, &str[0], len + 1);
46 if (res != ESP_OK) {
47 return {};
48 }
49
50 return {str};
51}
52
53optional<std::string> query_key_value(const char *query_url, size_t query_len, const char *key) {
54 if (query_url == nullptr || query_len == 0) {
55 return {};
56 }
57
58 // Value can't exceed query_len. Use small stack buffer for typical values,
59 // heap fallback for long ones (e.g. base64 IR data) to limit stack usage
60 // since callers may also have stack buffers for the query string.
62 if (httpd_query_key_value(query_url, key, val.get(), query_len) != ESP_OK) {
63 return {};
64 }
65
66 url_decode(val.get());
67 return {val.get()};
68}
69
70bool query_has_key(const char *query_url, size_t query_len, const char *key) {
71 if (query_url == nullptr || query_len == 0) {
72 return false;
73 }
74 // Minimal buffer — we only care if the key exists, not the value
75 char buf[1];
76 // httpd_query_key_value returns ESP_OK if found, ESP_ERR_HTTPD_RESULT_TRUNC if found
77 // but value truncated (expected with 1-byte buffer), or other errors for invalid input
78 auto err = httpd_query_key_value(query_url, key, buf, sizeof(buf));
79 return err == ESP_OK || err == ESP_ERR_HTTPD_RESULT_TRUNC;
80}
81
82// Helper function for case-insensitive string region comparison
83bool str_ncmp_ci(const char *s1, const char *s2, size_t n) {
84 for (size_t i = 0; i < n; i++) {
85 if (!char_equals_ci(s1[i], s2[i])) {
86 return false;
87 }
88 }
89 return true;
90}
91
92// Bounded case-insensitive string search (like strcasestr but length-bounded)
93const char *strcasestr_n(const char *haystack, size_t haystack_len, const char *needle) {
94 if (!haystack) {
95 return nullptr;
96 }
97
98 size_t needle_len = strlen(needle);
99 if (needle_len == 0) {
100 return haystack;
101 }
102
103 if (haystack_len < needle_len) {
104 return nullptr;
105 }
106
107 const char *end = haystack + haystack_len - needle_len + 1;
108 for (const char *p = haystack; p < end; p++) {
109 if (str_ncmp_ci(p, needle, needle_len)) {
110 return p;
111 }
112 }
113
114 return nullptr;
115}
116
117} // namespace esphome::web_server_idf
118#endif // USE_ESP32
Helper class for efficient buffer allocation - uses stack for small sizes, heap for large This is use...
Definition helpers.h:483
mopeka_std_values val[4]
bool query_has_key(const char *query_url, size_t query_len, const char *key)
Definition utils.cpp:70
bool char_equals_ci(char a, char b)
Definition utils.h:20
optional< std::string > request_get_header(httpd_req_t *req, const char *name)
Definition utils.cpp:36
optional< std::string > query_key_value(const char *query_url, size_t query_len, const char *key)
Definition utils.cpp:53
const char * strcasestr_n(const char *haystack, size_t haystack_len, const char *needle)
Definition utils.cpp:93
bool str_ncmp_ci(const char *s1, const char *s2, size_t n)
Definition utils.cpp:83
size_t url_decode(char *str)
Decode URL-encoded string in-place (e.g., %20 -> space, + -> space) Returns the new length of the dec...
Definition utils.cpp:11
bool request_has_header(httpd_req_t *req, const char *name)
Definition utils.cpp:34
std::string size_t len
Definition helpers.h:817
size_t parse_hex(const char *str, size_t length, uint8_t *data, size_t count)
Parse bytes from a hex-encoded string into a byte array.
Definition helpers.cpp:294
uint8_t end[39]
Definition sun_gtil2.cpp:17