21 const std::string &body,
22 const std::list<Header> &request_headers,
23 const std::set<std::string> &response_headers) {
26 ESP_LOGW(TAG,
"HTTP Request failed; Not connected to network");
30 std::regex url_regex(R
"(^(([^:\/?#]+):)?(//([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)", std::regex::extended);
31 std::smatch url_match_result;
33 if (!std::regex_match(url, url_match_result, url_regex) || url_match_result.length() < 7) {
34 ESP_LOGE(TAG,
"HTTP Request failed; Malformed URL: %s", url.c_str());
37 auto host = url_match_result[4].str();
38 auto scheme_host = url_match_result[1].str() + url_match_result[3].str();
39 auto path = url_match_result[5].str() + url_match_result[6].str();
43 std::shared_ptr<HttpContainerHost> container = std::make_shared<HttpContainerHost>();
44 container->set_parent(
this);
50 httplib::Headers h_headers;
51 h_headers.emplace(
"Host", host.c_str());
52 h_headers.emplace(
"User-Agent", this->
useragent_);
53 for (
const auto &[name, value] : request_headers) {
54 h_headers.emplace(name, value);
56 httplib::Client client(scheme_host.c_str());
57 if (!client.is_valid()) {
58 ESP_LOGE(TAG,
"HTTP Request failed; Invalid URL: %s", url.c_str());
62#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
64 client.set_ca_cert_path(this->
ca_path_);
67 httplib::Result result;
68 if (method ==
"GET") {
69 result = client.Get(path, h_headers, [&](
const char *data,
size_t data_length) {
70 ESP_LOGV(TAG,
"Got data length: %zu", data_length);
71 container->response_body_.insert(container->response_body_.end(), (
const uint8_t *) data,
72 (
const uint8_t *) data + data_length);
75 }
else if (method ==
"HEAD") {
76 result = client.Head(path, h_headers);
77 }
else if (method ==
"PUT") {
78 result = client.Put(path, h_headers, body,
"");
80 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
81 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
83 }
else if (method ==
"PATCH") {
84 result = client.Patch(path, h_headers, body,
"");
86 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
87 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
89 }
else if (method ==
"POST") {
90 result = client.Post(path, h_headers, body,
"");
92 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
93 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
96 ESP_LOGW(TAG,
"HTTP Request failed - unsupported method %s; URL: %s", method.c_str(), url.c_str());
102 ESP_LOGW(TAG,
"HTTP Request failed; URL: %s, error code: %u", url.c_str(), (
unsigned) result.error());
108 auto response = *result;
109 container->status_code = response.status;
111 ESP_LOGE(TAG,
"HTTP Request failed; URL: %s; Code: %d", url.c_str(), response.status);
116 container->content_length = container->response_body_.size();
117 for (
auto header : response.headers) {
118 ESP_LOGD(TAG,
"Header: %s: %s", header.first.c_str(), header.second.c_str());
120 if (response_headers.find(lower_name) != response_headers.end()) {
121 container->response_headers_[lower_name].emplace_back(header.second);