28 const std::string &body,
29 const std::vector<Header> &request_headers,
30 const std::vector<std::string> &lower_case_collect_headers) {
33 ESP_LOGW(TAG,
"HTTP Request failed; Not connected to network");
37 std::shared_ptr<HttpContainerArduino> container = std::make_shared<HttpContainerArduino>();
38 container->set_parent(
this);
42 bool secure = url.find(
"https:") != std::string::npos;
43 container->set_secure(secure);
48 container->client_.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
51 container->client_.setFollowRedirects(HTTPC_DISABLE_FOLLOW_REDIRECTS);
54#if defined(USE_ESP8266)
55 std::unique_ptr<WiFiClient> stream_ptr;
56#ifdef USE_HTTP_REQUEST_ESP8266_HTTPS
58 ESP_LOGV(TAG,
"ESP8266 HTTPS connection with WiFiClientSecure");
59 stream_ptr = std::make_unique<WiFiClientSecure>();
60 WiFiClientSecure *secure_client =
static_cast<WiFiClientSecure *
>(stream_ptr.get());
61 secure_client->setBufferSizes(RX_BUFFER_SIZE, TX_BUFFER_SIZE);
62 secure_client->setInsecure();
64 stream_ptr = std::make_unique<WiFiClient>();
67 ESP_LOGV(TAG,
"ESP8266 HTTP connection with WiFiClient");
69 ESP_LOGE(TAG,
"Can't use HTTPS connection with esp8266_disable_ssl_support");
72 stream_ptr = std::make_unique<WiFiClient>();
75#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 1, 0)
77 ESP_LOGW(TAG,
"Using HTTP on Arduino version >= 3.1 is **very** slow. Consider setting framework version to 3.0.2 "
78 "in your YAML, or use HTTPS");
81 bool status = container->client_.begin(*stream_ptr, url.c_str());
83#elif defined(USE_RP2040)
85 container->client_.setInsecure();
87 bool status = container->client_.begin(url.c_str());
93 ESP_LOGW(TAG,
"HTTP Request failed; URL: %s", url.c_str());
99 container->client_.setReuse(
true);
100 container->client_.setTimeout(this->
timeout_);
103 container->client_.setUserAgent(this->
useragent_);
105 for (
const auto &header : request_headers) {
106 container->client_.addHeader(header.name.c_str(), header.value.c_str(),
false,
true);
110 const char *header_keys[lower_case_collect_headers.size()];
112 for (
auto const &header_name : lower_case_collect_headers) {
113 header_keys[index++] = header_name.c_str();
115 container->client_.collectHeaders(header_keys, index);
118 container->status_code = container->client_.sendRequest(method.c_str(), body.c_str());
120 if (container->status_code < 0) {
121#if defined(USE_ESP8266) && defined(USE_HTTP_REQUEST_ESP8266_HTTPS)
123 WiFiClientSecure *secure_client =
static_cast<WiFiClientSecure *
>(stream_ptr.get());
124 int last_error = secure_client->getLastSSLError();
126 if (last_error != 0) {
127 const LogString *error_msg;
128 switch (last_error) {
129 case ESP8266_SSL_ERR_OOM:
130 error_msg = LOG_STR(
"Unable to allocate buffer memory");
132 case BR_ERR_TOO_LARGE:
133 error_msg = LOG_STR(
"Incoming TLS record does not fit in receive buffer (BR_ERR_TOO_LARGE)");
136 error_msg = LOG_STR(
"Unknown SSL error");
139 ESP_LOGW(TAG,
"SSL failure: %s (Code: %d)", LOG_STR_ARG(error_msg), last_error);
140 if (last_error == ESP8266_SSL_ERR_OOM) {
141 ESP_LOGW(TAG,
"Heap free: %u bytes, configured buffer sizes: %u bytes", ESP.getFreeHeap(),
142 static_cast<unsigned int>(RX_BUFFER_SIZE + TX_BUFFER_SIZE));
145 ESP_LOGW(TAG,
"Connection failure with no error code");
150 ESP_LOGW(TAG,
"HTTP Request failed; URL: %s; Error: %s", url.c_str(),
151 HTTPClient::errorToString(container->status_code).c_str());
158 ESP_LOGE(TAG,
"HTTP Request failed; URL: %s; Code: %d", url.c_str(), container->status_code);
163 container->response_headers_.clear();
164 auto header_count = container->client_.headers();
165 for (
int i = 0; i < header_count; i++) {
166 const std::string header_name =
str_lower_case(container->client_.headerName(i).c_str());
168 std::string header_value = container->client_.header(i).c_str();
169 ESP_LOGD(TAG,
"Received response header, name: %s, value: %s", header_name.c_str(), header_value.c_str());
170 container->response_headers_.push_back({header_name, header_value});
180 int content_length = container->client_.getSize();
181 ESP_LOGD(TAG,
"Content-Length: %d", content_length);
182 container->content_length = (size_t) content_length;
184 container->set_chunked(content_length == -1);
212 const uint32_t start =
millis();
215 WiFiClient *stream_ptr = this->
client_.getStreamPtr();
216 if (stream_ptr ==
nullptr) {
217 ESP_LOGE(TAG,
"Stream pointer vanished!");
218 return HTTP_ERROR_CONNECTION_CLOSED;
239 if (!stream_ptr->connected()) {
240 return HTTP_ERROR_CONNECTION_CLOSED;
246 int available_data = stream_ptr->available();
248 int bufsize = std::min(max_len, std::min(remaining, (
size_t) available_data));
255 if (!stream_ptr->connected()) {
256 return HTTP_ERROR_CONNECTION_CLOSED;
262 int read_len = stream_ptr->readBytes(buf, bufsize);