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