21 std::list<Header> request_headers,
22 std::set<std::string> response_headers) {
25 ESP_LOGW(TAG,
"HTTP Request failed; Not connected to network");
29 std::regex url_regex(R
"(^(([^:\/?#]+):)?(//([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)", std::regex::extended);
30 std::smatch url_match_result;
32 if (!std::regex_match(url, url_match_result, url_regex) || url_match_result.length() < 7) {
33 ESP_LOGE(TAG,
"HTTP Request failed; Malformed URL: %s", url.c_str());
36 auto host = url_match_result[4].str();
37 auto scheme_host = url_match_result[1].str() + url_match_result[3].str();
38 auto path = url_match_result[5].str() + url_match_result[6].str();
42 std::shared_ptr<HttpContainerHost> container = std::make_shared<HttpContainerHost>();
43 container->set_parent(
this);
49 httplib::Headers h_headers;
50 h_headers.emplace(
"Host", host.c_str());
51 h_headers.emplace(
"User-Agent", this->
useragent_);
52 for (
const auto &[name, value] : request_headers) {
53 h_headers.emplace(name, value);
55 httplib::Client client(scheme_host.c_str());
56 if (!client.is_valid()) {
57 ESP_LOGE(TAG,
"HTTP Request failed; Invalid URL: %s", url.c_str());
61#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
63 client.set_ca_cert_path(this->
ca_path_);
66 httplib::Result result;
67 if (method ==
"GET") {
68 result = client.Get(path, h_headers, [&](
const char *data,
size_t data_length) {
69 ESP_LOGV(TAG,
"Got data length: %zu", data_length);
70 container->response_body_.insert(container->response_body_.end(), (
const uint8_t *) data,
71 (
const uint8_t *) data + data_length);
74 }
else if (method ==
"HEAD") {
75 result = client.Head(path, h_headers);
76 }
else if (method ==
"PUT") {
77 result = client.Put(path, h_headers, body,
"");
79 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
80 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
82 }
else if (method ==
"PATCH") {
83 result = client.Patch(path, h_headers, body,
"");
85 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
86 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
88 }
else if (method ==
"POST") {
89 result = client.Post(path, h_headers, body,
"");
91 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
92 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
95 ESP_LOGW(TAG,
"HTTP Request failed - unsupported method %s; URL: %s", method.c_str(), url.c_str());
101 ESP_LOGW(TAG,
"HTTP Request failed; URL: %s, error code: %u", url.c_str(), (
unsigned) result.error());
107 auto response = *result;
108 container->status_code = response.status;
110 ESP_LOGE(TAG,
"HTTP Request failed; URL: %s; Code: %d", url.c_str(), response.status);
115 container->content_length = container->response_body_.size();
116 for (
auto header : response.headers) {
117 ESP_LOGD(TAG,
"Header: %s: %s", header.first.c_str(), header.second.c_str());
119 if (response_headers.find(lower_name) != response_headers.end()) {
120 container->response_headers_[lower_name].emplace_back(header.second);