ESPHome 2025.11.0
Loading...
Searching...
No Matches
web_server_base.h
Go to the documentation of this file.
1#pragma once
3#ifdef USE_NETWORK
4#include <memory>
5#include <utility>
6#include <vector>
7
9
10// Platform-agnostic macros for web server components
11// On ESP32 (both Arduino and IDF): Use plain strings (no PROGMEM)
12// On ESP8266: Use Arduino's F() macro for PROGMEM strings
13#ifdef USE_ESP32
14#define ESPHOME_F(string_literal) (string_literal)
15#define ESPHOME_PGM_P const char *
16#define ESPHOME_strncpy_P strncpy
17#else
18// ESP8266 uses Arduino macros
19#define ESPHOME_F(string_literal) F(string_literal)
20#define ESPHOME_PGM_P PGM_P
21#define ESPHOME_strncpy_P strncpy_P
22#endif
23
24#if USE_ESP32
25#include "esphome/core/hal.h"
27#else
28#include <ESPAsyncWebServer.h>
29#endif
30
31#if USE_ESP32
32using PlatformString = std::string;
33#elif USE_ARDUINO
34using PlatformString = String;
35#endif
36
37namespace esphome {
38namespace web_server_base {
39
40class WebServerBase;
41extern WebServerBase *global_web_server_base; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
42
43namespace internal {
44
45class MiddlewareHandler : public AsyncWebHandler {
46 public:
47 MiddlewareHandler(AsyncWebHandler *next) : next_(next) {}
48
49 bool canHandle(AsyncWebServerRequest *request) const override { return next_->canHandle(request); }
50 void handleRequest(AsyncWebServerRequest *request) override { next_->handleRequest(request); }
51 void handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index, uint8_t *data,
52 size_t len, bool final) override {
53 next_->handleUpload(request, filename, index, data, len, final);
54 }
55 void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override {
56 next_->handleBody(request, data, len, index, total);
57 }
58 bool isRequestHandlerTrivial() const override { return next_->isRequestHandlerTrivial(); }
59
60 protected:
61 AsyncWebHandler *next_;
62};
63
64#ifdef USE_WEBSERVER_AUTH
66 std::string username;
67 std::string password;
68};
69
71 public:
72 AuthMiddlewareHandler(AsyncWebHandler *next, Credentials *credentials)
73 : MiddlewareHandler(next), credentials_(credentials) {}
74
75 bool check_auth(AsyncWebServerRequest *request) {
76 bool success = request->authenticate(credentials_->username.c_str(), credentials_->password.c_str());
77 if (!success) {
78 request->requestAuthentication();
79 }
80 return success;
81 }
82
83 void handleRequest(AsyncWebServerRequest *request) override {
84 if (!check_auth(request))
85 return;
87 }
88 void handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index, uint8_t *data,
89 size_t len, bool final) override {
90 if (!check_auth(request))
91 return;
92 MiddlewareHandler::handleUpload(request, filename, index, data, len, final);
93 }
94 void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override {
95 if (!check_auth(request))
96 return;
97 MiddlewareHandler::handleBody(request, data, len, index, total);
98 }
99
100 protected:
102};
103#endif
104
105} // namespace internal
106
107class WebServerBase : public Component {
108 public:
109 void init() {
110 if (this->initialized_) {
111 this->initialized_++;
112 return;
113 }
114 this->server_ = std::make_shared<AsyncWebServer>(this->port_);
115 // All content is controlled and created by user - so allowing all origins is fine here.
116 DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
117 this->server_->begin();
118
119 for (auto *handler : this->handlers_)
120 this->server_->addHandler(handler);
121
122 this->initialized_++;
123 }
124 void deinit() {
125 this->initialized_--;
126 if (this->initialized_ == 0) {
127 this->server_ = nullptr;
128 }
129 }
130 std::shared_ptr<AsyncWebServer> get_server() const { return server_; }
131 float get_setup_priority() const override;
132
133#ifdef USE_WEBSERVER_AUTH
134 void set_auth_username(std::string auth_username) { credentials_.username = std::move(auth_username); }
135 void set_auth_password(std::string auth_password) { credentials_.password = std::move(auth_password); }
136#endif
137
138 void add_handler(AsyncWebHandler *handler);
139
140 void set_port(uint16_t port) { port_ = port; }
141 uint16_t get_port() const { return port_; }
142
143 protected:
145 uint16_t port_{80};
146 std::shared_ptr<AsyncWebServer> server_{nullptr};
147 std::vector<AsyncWebHandler *> handlers_;
148#ifdef USE_WEBSERVER_AUTH
150#endif
151};
152
153} // namespace web_server_base
154} // namespace esphome
155#endif
std::shared_ptr< AsyncWebServer > get_server() const
void set_auth_password(std::string auth_password)
void set_auth_username(std::string auth_username)
void add_handler(AsyncWebHandler *handler)
std::vector< AsyncWebHandler * > handlers_
std::shared_ptr< AsyncWebServer > server_
void handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index, uint8_t *data, size_t len, bool final) override
void handleRequest(AsyncWebServerRequest *request) override
AuthMiddlewareHandler(AsyncWebHandler *next, Credentials *credentials)
void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override
bool canHandle(AsyncWebServerRequest *request) const override
void handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index, uint8_t *data, size_t len, bool final) override
void handleRequest(AsyncWebServerRequest *request) override
void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override
WebServerBase * global_web_server_base
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:483
std::string PlatformString