http_request http fix (#980)

Co-authored-by: Nikolay Vasilchuk <nikolay.vasilchuk@corp.mail.ru>
This commit is contained in:
Nikolay Vasilchuk 2020-03-12 03:27:05 +03:00 committed by GitHub
parent 426e6a1b46
commit e0b4226930
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 16 deletions

View file

@ -4,7 +4,7 @@ import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome import automation from esphome import automation
from esphome.const import CONF_ID, CONF_TIMEOUT, CONF_ESPHOME, CONF_METHOD, \ 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 import CORE, Lambda
from esphome.core_config import PLATFORMIO_ESP8266_LUT 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) HttpRequestComponent = http_request_ns.class_('HttpRequestComponent', cg.Component)
HttpRequestSendAction = http_request_ns.class_('HttpRequestSendAction', automation.Action) HttpRequestSendAction = http_request_ns.class_('HttpRequestSendAction', automation.Action)
CONF_URL = 'url'
CONF_HEADERS = 'headers' CONF_HEADERS = 'headers'
CONF_USERAGENT = 'useragent' CONF_USERAGENT = 'useragent'
CONF_BODY = 'body' 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]) paren = yield cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren) 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_url(template_))
cg.add(var.set_method(config[CONF_METHOD])) cg.add(var.set_method(config[CONF_METHOD]))
if CONF_BODY in config: if CONF_BODY in config:

View file

@ -14,14 +14,15 @@ void HttpRequestComponent::dump_config() {
void HttpRequestComponent::send() { void HttpRequestComponent::send() {
bool begin_status = false; bool begin_status = false;
this->client_.setReuse(true);
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
begin_status = this->client_.begin(this->url_); begin_status = this->client_.begin(this->url_);
#endif #endif
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
#ifndef CLANG_TIDY #ifndef CLANG_TIDY
begin_status = this->client_.begin(*this->wifi_client_, this->url_);
this->client_.setFollowRedirects(true); this->client_.setFollowRedirects(true);
this->client_.setRedirectLimit(3); this->client_.setRedirectLimit(3);
begin_status = this->client_.begin(*this->get_wifi_client_(), this->url_);
#endif #endif
#endif #endif
@ -41,8 +42,6 @@ void HttpRequestComponent::send() {
} }
int http_code = this->client_.sendRequest(this->method_, this->body_.c_str()); int http_code = this->client_.sendRequest(this->method_, this->body_.c_str());
this->client_.end();
if (http_code < 0) { if (http_code < 0) {
ESP_LOGW(TAG, "HTTP Request failed; URL: %s; Error: %s", this->url_, HTTPClient::errorToString(http_code).c_str()); ESP_LOGW(TAG, "HTTP Request failed; URL: %s; Error: %s", this->url_, HTTPClient::errorToString(http_code).c_str());
this->status_set_warning(); 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); 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 http_request
} // namespace esphome } // namespace esphome

View file

@ -24,41 +24,42 @@ struct Header {
class HttpRequestComponent : public Component { class HttpRequestComponent : public Component {
public: 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; void dump_config() override;
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; } 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_method(const char *method) { this->method_ = method; }
void set_useragent(const char *useragent) { this->useragent_ = useragent; } void set_useragent(const char *useragent) { this->useragent_ = useragent; }
void set_timeout(uint16_t timeout) { this->timeout_ = timeout; } void set_timeout(uint16_t timeout) { this->timeout_ = timeout; }
void set_body(std::string body) { this->body_ = body; } void set_body(std::string body) { this->body_ = body; }
void set_headers(std::list<Header> headers) { this->headers_ = headers; } void set_headers(std::list<Header> headers) { this->headers_ = headers; }
void send(); void send();
void close();
const char *get_string();
protected: protected:
HTTPClient client_{}; HTTPClient client_{};
const char *url_; const char *url_;
const char *method_; const char *method_;
const char *useragent_{nullptr}; const char *useragent_{nullptr};
bool secure_;
uint16_t timeout_{5000}; uint16_t timeout_{5000};
std::string body_; std::string body_;
std::list<Header> headers_; std::list<Header> headers_;
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
BearSSL::WiFiClientSecure *wifi_client_; WiFiClient *wifi_client_{nullptr};
BearSSL::WiFiClientSecure *wifi_client_secure_{nullptr};
WiFiClient *get_wifi_client_();
#endif #endif
}; };
template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> { template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
public: public:
HttpRequestSendAction(HttpRequestComponent *parent) : parent_(parent) {} HttpRequestSendAction(HttpRequestComponent *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(const char *, url) TEMPLATABLE_VALUE(std::string, url)
TEMPLATABLE_VALUE(const char *, method) TEMPLATABLE_VALUE(const char *, method)
TEMPLATABLE_VALUE(std::string, body) TEMPLATABLE_VALUE(std::string, body)
TEMPLATABLE_VALUE(const char *, useragent) TEMPLATABLE_VALUE(const char *, useragent)
@ -102,6 +103,7 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
this->parent_->set_headers(headers); this->parent_->set_headers(headers);
} }
this->parent_->send(); this->parent_->send();
this->parent_->close();
} }
protected: protected:

View file

@ -479,6 +479,7 @@ CONF_UNIQUE = 'unique'
CONF_UNIT_OF_MEASUREMENT = 'unit_of_measurement' CONF_UNIT_OF_MEASUREMENT = 'unit_of_measurement'
CONF_UPDATE_INTERVAL = 'update_interval' CONF_UPDATE_INTERVAL = 'update_interval'
CONF_UPDATE_ON_BOOT = 'update_on_boot' CONF_UPDATE_ON_BOOT = 'update_on_boot'
CONF_URL = 'url'
CONF_USE_ADDRESS = 'use_address' CONF_USE_ADDRESS = 'use_address'
CONF_USERNAME = 'username' CONF_USERNAME = 'username'
CONF_UUID = 'uuid' CONF_UUID = 'uuid'