18 std::list<Header> request_headers,
19 std::set<std::string> response_headers) {
22 ESP_LOGW(TAG,
"HTTP Request failed; Not connected to network");
26 std::regex url_regex(R
"(^(([^:\/?#]+):)?(//([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)", std::regex::extended);
27 std::smatch url_match_result;
29 if (!std::regex_match(url, url_match_result, url_regex) || url_match_result.length() < 7) {
30 ESP_LOGE(TAG,
"HTTP Request failed; Malformed URL: %s", url.c_str());
33 auto host = url_match_result[4].str();
34 auto scheme_host = url_match_result[1].str() + url_match_result[3].str();
35 auto path = url_match_result[5].str() + url_match_result[6].str();
39 std::shared_ptr<HttpContainerHost> container = std::make_shared<HttpContainerHost>();
40 container->set_parent(
this);
46 httplib::Headers h_headers;
47 h_headers.emplace(
"Host", host.c_str());
48 h_headers.emplace(
"User-Agent", this->
useragent_);
49 for (
const auto &[name, value] : request_headers) {
50 h_headers.emplace(name, value);
52 httplib::Client client(scheme_host.c_str());
53 if (!client.is_valid()) {
54 ESP_LOGE(TAG,
"HTTP Request failed; Invalid URL: %s", url.c_str());
58#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
60 client.set_ca_cert_path(this->
ca_path_);
63 httplib::Result result;
64 if (method ==
"GET") {
65 result = client.Get(path, h_headers, [&](
const char *data,
size_t data_length) {
66 ESP_LOGV(TAG,
"Got data length: %zu", data_length);
67 container->response_body_.insert(container->response_body_.end(), (
const uint8_t *) data,
68 (
const uint8_t *) data + data_length);
71 }
else if (method ==
"HEAD") {
72 result = client.Head(path, h_headers);
73 }
else if (method ==
"PUT") {
74 result = client.Put(path, h_headers, body,
"");
76 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
77 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
79 }
else if (method ==
"PATCH") {
80 result = client.Patch(path, h_headers, body,
"");
82 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
83 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
85 }
else if (method ==
"POST") {
86 result = client.Post(path, h_headers, body,
"");
88 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
89 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
92 ESP_LOGW(TAG,
"HTTP Request failed - unsupported method %s; URL: %s", method.c_str(), url.c_str());
98 ESP_LOGW(TAG,
"HTTP Request failed; URL: %s, error code: %u", url.c_str(), (
unsigned) result.error());
104 auto response = *result;
105 container->status_code = response.status;
107 ESP_LOGE(TAG,
"HTTP Request failed; URL: %s; Code: %d", url.c_str(), response.status);
112 container->content_length = container->response_body_.size();
113 for (
auto header : response.headers) {
114 ESP_LOGD(TAG,
"Header: %s: %s", header.first.c_str(), header.second.c_str());
116 if (response_headers.find(lower_name) != response_headers.end()) {
117 container->response_headers_[lower_name].emplace_back(header.second);