ESPHome 2026.1.5
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
11namespace esphome {
12namespace web_server_idf {
13
14static const char *const TAG = "web_server_idf_utils";
15
16size_t url_decode(char *str) {
17 char *start = str;
18 char *ptr = str, buf;
19 for (; *str; str++, ptr++) {
20 if (*str == '%') {
21 str++;
22 if (parse_hex(str, 2, reinterpret_cast<uint8_t *>(&buf), 1) == 2) {
23 *ptr = buf;
24 str++;
25 } else {
26 str--;
27 *ptr = *str;
28 }
29 } else if (*str == '+') {
30 *ptr = ' ';
31 } else {
32 *ptr = *str;
33 }
34 }
35 *ptr = '\0';
36 return ptr - start;
37}
38
39bool request_has_header(httpd_req_t *req, const char *name) { return httpd_req_get_hdr_value_len(req, name); }
40
41optional<std::string> request_get_header(httpd_req_t *req, const char *name) {
42 size_t len = httpd_req_get_hdr_value_len(req, name);
43 if (len == 0) {
44 return {};
45 }
46
47 std::string str;
48 str.resize(len);
49
50 auto res = httpd_req_get_hdr_value_str(req, name, &str[0], len + 1);
51 if (res != ESP_OK) {
52 return {};
53 }
54
55 return {str};
56}
57
59 auto len = httpd_req_get_url_query_len(req);
60 if (len == 0) {
61 return {};
62 }
63
64 std::string str;
65 str.resize(len);
66
67 auto res = httpd_req_get_url_query_str(req, &str[0], len + 1);
68 if (res != ESP_OK) {
69 ESP_LOGW(TAG, "Can't get query for request: %s", esp_err_to_name(res));
70 return {};
71 }
72
73 return {str};
74}
75
76optional<std::string> query_key_value(const std::string &query_url, const std::string &key) {
77 if (query_url.empty()) {
78 return {};
79 }
80
81 auto val = std::unique_ptr<char[]>(new char[query_url.size()]);
82 if (!val) {
83 ESP_LOGE(TAG, "Not enough memory to the query key value");
84 return {};
85 }
86
87 if (httpd_query_key_value(query_url.c_str(), key.c_str(), val.get(), query_url.size()) != ESP_OK) {
88 return {};
89 }
90
91 url_decode(val.get());
92 return {val.get()};
93}
94
95// Helper function for case-insensitive string region comparison
96bool str_ncmp_ci(const char *s1, const char *s2, size_t n) {
97 for (size_t i = 0; i < n; i++) {
98 if (!char_equals_ci(s1[i], s2[i])) {
99 return false;
100 }
101 }
102 return true;
103}
104
105// Case-insensitive string search (like strstr but case-insensitive)
106const char *stristr(const char *haystack, const char *needle) {
107 if (!haystack) {
108 return nullptr;
109 }
110
111 size_t needle_len = strlen(needle);
112 if (needle_len == 0) {
113 return haystack;
114 }
115
116 for (const char *p = haystack; *p; p++) {
117 if (str_ncmp_ci(p, needle, needle_len)) {
118 return p;
119 }
120 }
121
122 return nullptr;
123}
124
125} // namespace web_server_idf
126} // namespace esphome
127#endif // USE_ESP32
mopeka_std_values val[4]
const char *const TAG
Definition spi.cpp:7
bool char_equals_ci(char a, char b)
Definition utils.h:21
optional< std::string > request_get_url_query(httpd_req_t *req)
Definition utils.cpp:58
optional< std::string > request_get_header(httpd_req_t *req, const char *name)
Definition utils.cpp:41
bool str_ncmp_ci(const char *s1, const char *s2, size_t n)
Definition utils.cpp:96
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:16
optional< std::string > query_key_value(const std::string &query_url, const std::string &key)
Definition utils.cpp:76
const char * stristr(const char *haystack, const char *needle)
Definition utils.cpp:106
bool request_has_header(httpd_req_t *req, const char *name)
Definition utils.cpp:39
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:595
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:275