From e0b4226930e30fbed70930a6ec25a23693970b05 Mon Sep 17 00:00:00 2001 From: Nikolay Vasilchuk Date: Thu, 12 Mar 2020 03:27:05 +0300 Subject: [PATCH] http_request http fix (#980) Co-authored-by: Nikolay Vasilchuk --- esphome/components/http_request/__init__.py | 5 ++-- .../components/http_request/http_request.cpp | 27 ++++++++++++++++--- .../components/http_request/http_request.h | 22 ++++++++------- esphome/const.py | 1 + 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/esphome/components/http_request/__init__.py b/esphome/components/http_request/__init__.py index ea12b0657d..e79df12a6c 100644 --- a/esphome/components/http_request/__init__.py +++ b/esphome/components/http_request/__init__.py @@ -4,7 +4,7 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import automation from esphome.const import CONF_ID, CONF_TIMEOUT, CONF_ESPHOME, CONF_METHOD, \ - CONF_ARDUINO_VERSION, ARDUINO_VERSION_ESP8266_2_5_1 + CONF_ARDUINO_VERSION, ARDUINO_VERSION_ESP8266_2_5_1, CONF_URL from esphome.core import CORE, Lambda from esphome.core_config import PLATFORMIO_ESP8266_LUT @@ -15,7 +15,6 @@ http_request_ns = cg.esphome_ns.namespace('http_request') HttpRequestComponent = http_request_ns.class_('HttpRequestComponent', cg.Component) HttpRequestSendAction = http_request_ns.class_('HttpRequestSendAction', automation.Action) -CONF_URL = 'url' CONF_HEADERS = 'headers' CONF_USERAGENT = 'useragent' CONF_BODY = 'body' @@ -121,7 +120,7 @@ def http_request_action_to_code(config, action_id, template_arg, args): paren = yield cg.get_variable(config[CONF_ID]) var = cg.new_Pvariable(action_id, template_arg, paren) - template_ = yield cg.templatable(config[CONF_URL], args, cg.const_char_ptr) + template_ = yield cg.templatable(config[CONF_URL], args, cg.std_string) cg.add(var.set_url(template_)) cg.add(var.set_method(config[CONF_METHOD])) if CONF_BODY in config: diff --git a/esphome/components/http_request/http_request.cpp b/esphome/components/http_request/http_request.cpp index 9df7cf7913..f2fe0cff54 100644 --- a/esphome/components/http_request/http_request.cpp +++ b/esphome/components/http_request/http_request.cpp @@ -14,14 +14,15 @@ void HttpRequestComponent::dump_config() { void HttpRequestComponent::send() { bool begin_status = false; + this->client_.setReuse(true); #ifdef ARDUINO_ARCH_ESP32 begin_status = this->client_.begin(this->url_); #endif #ifdef ARDUINO_ARCH_ESP8266 #ifndef CLANG_TIDY - begin_status = this->client_.begin(*this->wifi_client_, this->url_); this->client_.setFollowRedirects(true); this->client_.setRedirectLimit(3); + begin_status = this->client_.begin(*this->get_wifi_client_(), this->url_); #endif #endif @@ -41,8 +42,6 @@ void HttpRequestComponent::send() { } int http_code = this->client_.sendRequest(this->method_, this->body_.c_str()); - this->client_.end(); - if (http_code < 0) { ESP_LOGW(TAG, "HTTP Request failed; URL: %s; Error: %s", this->url_, HTTPClient::errorToString(http_code).c_str()); this->status_set_warning(); @@ -59,5 +58,27 @@ void HttpRequestComponent::send() { ESP_LOGD(TAG, "HTTP Request completed; URL: %s; Code: %d", this->url_, http_code); } +#ifdef ARDUINO_ARCH_ESP8266 +WiFiClient *HttpRequestComponent::get_wifi_client_() { + if (this->secure_) { + if (this->wifi_client_secure_ == nullptr) { + this->wifi_client_secure_ = new BearSSL::WiFiClientSecure(); + this->wifi_client_secure_->setInsecure(); + this->wifi_client_secure_->setBufferSizes(512, 512); + } + return this->wifi_client_secure_; + } + + if (this->wifi_client_ == nullptr) { + this->wifi_client_ = new WiFiClient(); + } + return this->wifi_client_; +} +#endif + +void HttpRequestComponent::close() { this->client_.end(); } + +const char *HttpRequestComponent::get_string() { return this->client_.getString().c_str(); } + } // namespace http_request } // namespace esphome diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index d26899c0db..0c849f2ab0 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -24,41 +24,42 @@ struct Header { class HttpRequestComponent : public Component { public: - void setup() override { -#ifdef ARDUINO_ARCH_ESP8266 - this->wifi_client_ = new BearSSL::WiFiClientSecure(); - this->wifi_client_->setInsecure(); - this->wifi_client_->setBufferSizes(512, 512); -#endif - } void dump_config() override; float get_setup_priority() const override { return setup_priority::AFTER_WIFI; } - void set_url(const char *url) { this->url_ = url; } + void set_url(std::string url) { + this->url_ = url.c_str(); + this->secure_ = url.compare(0, 6, "https:") == 0; + } void set_method(const char *method) { this->method_ = method; } void set_useragent(const char *useragent) { this->useragent_ = useragent; } void set_timeout(uint16_t timeout) { this->timeout_ = timeout; } void set_body(std::string body) { this->body_ = body; } void set_headers(std::list
headers) { this->headers_ = headers; } void send(); + void close(); + const char *get_string(); protected: HTTPClient client_{}; const char *url_; const char *method_; const char *useragent_{nullptr}; + bool secure_; uint16_t timeout_{5000}; std::string body_; std::list
headers_; #ifdef ARDUINO_ARCH_ESP8266 - BearSSL::WiFiClientSecure *wifi_client_; + WiFiClient *wifi_client_{nullptr}; + BearSSL::WiFiClientSecure *wifi_client_secure_{nullptr}; + WiFiClient *get_wifi_client_(); #endif }; template class HttpRequestSendAction : public Action { public: HttpRequestSendAction(HttpRequestComponent *parent) : parent_(parent) {} - TEMPLATABLE_VALUE(const char *, url) + TEMPLATABLE_VALUE(std::string, url) TEMPLATABLE_VALUE(const char *, method) TEMPLATABLE_VALUE(std::string, body) TEMPLATABLE_VALUE(const char *, useragent) @@ -102,6 +103,7 @@ template class HttpRequestSendAction : public Action { this->parent_->set_headers(headers); } this->parent_->send(); + this->parent_->close(); } protected: diff --git a/esphome/const.py b/esphome/const.py index 308dd2683f..e747371710 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -479,6 +479,7 @@ CONF_UNIQUE = 'unique' CONF_UNIT_OF_MEASUREMENT = 'unit_of_measurement' CONF_UPDATE_INTERVAL = 'update_interval' CONF_UPDATE_ON_BOOT = 'update_on_boot' +CONF_URL = 'url' CONF_USE_ADDRESS = 'use_address' CONF_USERNAME = 'username' CONF_UUID = 'uuid'