ESPHome 2026.2.3
Loading...
Searching...
No Matches
utils.cpp
Go to the documentation of this file.
1#ifdef USE_ESP32
2#include <memory>
3#include <cstring>
4#include <cctype>
6#include "esphome/core/log.h"
7#include "http_parser.h"
8
9#include "utils.h"
10
12
13static const char *const TAG = "web_server_idf_utils";
14
15size_t url_decode(char *str) {
16 char *start = str;
17 char *ptr = str, buf;
18 for (; *str; str++, ptr++) {
19 if (*str == '%') {
20 str++;
21 if (parse_hex(str, 2, reinterpret_cast<uint8_t *>(&buf), 1) == 2) {
22 *ptr = buf;
23 str++;
24 } else {
25 str--;
26 *ptr = *str;
27 }
28 } else if (*str == '+') {
29 *ptr = ' ';
30 } else {
31 *ptr = *str;
32 }
33 }
34 *ptr = '\0';
35 return ptr - start;
36}
37
38bool request_has_header(httpd_req_t *req, const char *name) { return httpd_req_get_hdr_value_len(req, name); }
39
40optional<std::string> request_get_header(httpd_req_t *req, const char *name) {
41 size_t len = httpd_req_get_hdr_value_len(req, name);
42 if (len == 0) {
43 return {};
44 }
45
46 std::string str;
47 str.resize(len);
48
49 auto res = httpd_req_get_hdr_value_str(req, name, &str[0], len + 1);
50 if (res != ESP_OK) {
51 return {};
52 }
53
54 return {str};
55}
56
58 auto len = httpd_req_get_url_query_len(req);
59 if (len == 0) {
60 return {};
61 }
62
63 std::string str;
64 str.resize(len);
65
66 auto res = httpd_req_get_url_query_str(req, &str[0], len + 1);
67 if (res != ESP_OK) {
68 ESP_LOGW(TAG, "Can't get query for request: %s", esp_err_to_name(res));
69 return {};
70 }
71
72 return {str};
73}
74
75optional<std::string> query_key_value(const char *query_url, size_t query_len, const char *key) {
76 if (query_url == nullptr || query_len == 0) {
77 return {};
78 }
79
80 // Use stack buffer for typical query strings, heap fallback for large ones
82
83 if (httpd_query_key_value(query_url, key, val.get(), query_len) != ESP_OK) {
84 return {};
85 }
86
87 url_decode(val.get());
88 return {val.get()};
89}
90
91// Helper function for case-insensitive string region comparison
92bool str_ncmp_ci(const char *s1, const char *s2, size_t n) {
93 for (size_t i = 0; i < n; i++) {
94 if (!char_equals_ci(s1[i], s2[i])) {
95 return false;
96 }
97 }
98 return true;
99}
100
101// Bounded case-insensitive string search (like strcasestr but length-bounded)
102const char *strcasestr_n(const char *haystack, size_t haystack_len, const char *needle) {
103 if (!haystack) {
104 return nullptr;
105 }
106
107 size_t needle_len = strlen(needle);
108 if (needle_len == 0) {
109 return haystack;
110 }
111
112 if (haystack_len < needle_len) {
113 return nullptr;
114 }
115
116 const char *end = haystack + haystack_len - needle_len + 1;
117 for (const char *p = haystack; p < end; p++) {
118 if (str_ncmp_ci(p, needle, needle_len)) {
119 return p;
120 }
121 }
122
123 return nullptr;
124}
125
126} // namespace esphome::web_server_idf
127#endif // USE_ESP32
Helper class for efficient buffer allocation - uses stack for small sizes, heap for large This is use...
Definition helpers.h:411
mopeka_std_values val[4]
const char *const TAG
Definition spi.cpp:7
bool char_equals_ci(char a, char b)
Definition utils.h:23
optional< std::string > request_get_url_query(httpd_req_t *req)
Definition utils.cpp:57
optional< std::string > request_get_header(httpd_req_t *req, const char *name)
Definition utils.cpp:40
optional< std::string > query_key_value(const char *query_url, size_t query_len, const char *key)
Definition utils.cpp:75
const char * strcasestr_n(const char *haystack, size_t haystack_len, const char *needle)
Definition utils.cpp:102
bool str_ncmp_ci(const char *s1, const char *s2, size_t n)
Definition utils.cpp:92
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:15
bool request_has_header(httpd_req_t *req, const char *name)
Definition utils.cpp:38
std::string size_t len
Definition helpers.h:692
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