ESPHome 2025.5.0
Loading...
Searching...
No Matches
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"
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
17namespace esphome {
18namespace web_server_base {
19
20static const char *const TAG = "web_server_base";
21
22void 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
42void 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}
97void 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
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition component.cpp:72
void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) override
void handleRequest(AsyncWebServerRequest *request) override
void add_handler(AsyncWebHandler *handler)
std::vector< AsyncWebHandler * > handlers_
std::shared_ptr< AsyncWebServer > server_
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:301
uint32_t IRAM_ATTR HOT millis()
Definition core.cpp:27
Application App
Global storage of Application pointer - only one Application can exist.