ESPHome  2023.3.2
web_server_base.cpp
Go to the documentation of this file.
1 #ifdef USE_ARDUINO
2 
3 #include "web_server_base.h"
4 #include "esphome/core/log.h"
6 #include <StreamString.h>
7 
8 #ifdef USE_ESP32
9 #include <Update.h>
10 #endif
11 #ifdef USE_ESP8266
12 #include <Updater.h>
13 #endif
14 
15 namespace esphome {
16 namespace web_server_base {
17 
18 static const char *const TAG = "web_server_base";
19 
20 void WebServerBase::add_handler(AsyncWebHandler *handler) {
21  // remove all handlers
22 
23  if (!credentials_.username.empty()) {
24  handler = new internal::AuthMiddlewareHandler(handler, &credentials_);
25  }
26  this->handlers_.push_back(handler);
27  if (this->server_ != nullptr)
28  this->server_->addHandler(handler);
29 }
30 
32  StreamString ss;
33  Update.printError(ss);
34  ESP_LOGW(TAG, "OTA Update failed! Error: %s", ss.c_str());
35 }
36 
37 void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index,
38  uint8_t *data, size_t len, bool final) {
39  bool success;
40  if (index == 0) {
41  ESP_LOGI(TAG, "OTA Update Start: %s", filename.c_str());
42  this->ota_read_length_ = 0;
43 #ifdef USE_ESP8266
44  Update.runAsync(true);
45  // NOLINTNEXTLINE(readability-static-accessed-through-instance)
46  success = Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
47 #endif
48 #ifdef USE_ESP32
49  if (Update.isRunning())
50  Update.abort();
51  success = Update.begin(UPDATE_SIZE_UNKNOWN, U_FLASH);
52 #endif
53  if (!success) {
55  return;
56  }
57  } else if (Update.hasError()) {
58  // don't spam logs with errors if something failed at start
59  return;
60  }
61 
62  success = Update.write(data, len) == len;
63  if (!success) {
65  return;
66  }
67  this->ota_read_length_ += len;
68 
69  const uint32_t now = millis();
70  if (now - this->last_ota_progress_ > 1000) {
71  if (request->contentLength() != 0) {
72  float percentage = (this->ota_read_length_ * 100.0f) / request->contentLength();
73  ESP_LOGD(TAG, "OTA in progress: %0.1f%%", percentage);
74  } else {
75  ESP_LOGD(TAG, "OTA in progress: %u bytes read", this->ota_read_length_);
76  }
77  this->last_ota_progress_ = now;
78  }
79 
80  if (final) {
81  if (Update.end(true)) {
82  ESP_LOGI(TAG, "OTA update successful!");
83  this->parent_->set_timeout(100, []() { App.safe_reboot(); });
84  } else {
86  }
87  }
88 }
89 void OTARequestHandler::handleRequest(AsyncWebServerRequest *request) {
90  AsyncWebServerResponse *response;
91  if (!Update.hasError()) {
92  response = request->beginResponse(200, "text/plain", "Update Successful!");
93  } else {
94  StreamString ss;
95  ss.print("Update Failed: ");
96  Update.printError(ss);
97  response = request->beginResponse(200, "text/plain", ss);
98  }
99  response->addHeader("Connection", "close");
100  request->send(response);
101 }
102 
104  this->add_handler(new OTARequestHandler(this)); // NOLINT
105 }
107  // Before WiFi (captive portal)
108  return setup_priority::WIFI + 2.0f;
109 }
110 
111 } // namespace web_server_base
112 } // namespace esphome
113 
114 #endif // USE_ARDUINO
std::shared_ptr< AsyncWebServer > server_
void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) override
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:26
void add_handler(AsyncWebHandler *handler)
Application App
Global storage of Application pointer - only one Application can exist.
std::string size_t len
Definition: helpers.h:286
void handleRequest(AsyncWebServerRequest *request) override
std::vector< AsyncWebHandler * > handlers_
Definition: a4988.cpp:4