22 const std::vector<Header> &request_headers,
23 const std::vector<std::string> &lower_case_collect_headers,
27 ESP_LOGW(TAG,
"HTTP Request failed; Not connected to network");
31 std::regex url_regex(R
"(^(([^:\/?#]+):)?(//([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)", std::regex::extended);
32 std::cmatch url_match_result;
34 if (!std::regex_match(url, url_match_result, url_regex) || url_match_result.length() < 7) {
35 ESP_LOGE(TAG,
"HTTP Request failed; Malformed URL: %s", url);
38 auto host = url_match_result[4].str();
39 auto scheme_host = url_match_result[1].str() + url_match_result[3].str();
40 auto path = url_match_result[5].str() + url_match_result[6].str();
44 std::shared_ptr<HttpContainerHost> container = std::make_shared<HttpContainerHost>();
45 container->set_parent(
this);
51 httplib::Headers h_headers;
52 h_headers.emplace(
"Host", host.c_str());
53 h_headers.emplace(
"User-Agent", this->
useragent_);
54 for (
const auto &[name, value] : request_headers) {
55 h_headers.emplace(name, value);
57 httplib::Client client(scheme_host);
58 if (!client.is_valid()) {
59 ESP_LOGE(TAG,
"HTTP Request failed; Invalid URL: %s", url);
63#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
65 client.set_ca_cert_path(this->
ca_path_);
68 httplib::Result result;
69 if (strcmp(method,
"GET") == 0) {
70 result = client.Get(path, h_headers, [&](
const char *data,
size_t data_length) {
71 ESP_LOGV(TAG,
"Got data length: %zu", data_length);
72 container->response_body_.insert(container->response_body_.end(), (
const uint8_t *) data,
73 (
const uint8_t *) data + data_length);
76 }
else if (strcmp(method,
"HEAD") == 0) {
77 result = client.Head(path, h_headers);
78 }
else if (strcmp(method,
"PUT") == 0) {
79 result = client.Put(path, h_headers, body,
"");
81 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
82 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
84 }
else if (strcmp(method,
"PATCH") == 0) {
85 result = client.Patch(path, h_headers, body,
"");
87 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
88 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
90 }
else if (strcmp(method,
"POST") == 0) {
91 result = client.Post(path, h_headers, body,
"");
93 auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
94 container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
97 ESP_LOGW(TAG,
"HTTP Request failed - unsupported method %s; URL: %s", method, url);
103 ESP_LOGW(TAG,
"HTTP Request failed; URL: %s, error code: %u", url, (
unsigned) result.error());
109 auto response = *result;
110 container->status_code = response.status;
112 ESP_LOGE(TAG,
"HTTP Request failed; URL: %s; Code: %d", url, response.status);
117 container->content_length = container->response_body_.size();
118 for (
const auto &header : response.headers) {
119 ESP_LOGD(TAG,
"Header: %s: %s", header.first.c_str(), header.second.c_str());
122 container->response_headers_.push_back({lower_name, header.second});