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