ESPHome  2024.9.0
web_server_base.h
Go to the documentation of this file.
1 #pragma once
2 #include "esphome/core/defines.h"
3 #ifdef USE_NETWORK
4 #include <memory>
5 #include <utility>
6 #include <vector>
7 
9 
10 #ifdef USE_ARDUINO
11 #include <ESPAsyncWebServer.h>
12 #elif USE_ESP_IDF
13 #include "esphome/core/hal.h"
15 #endif
16 
17 namespace esphome {
18 namespace web_server_base {
19 
20 namespace internal {
21 
22 class MiddlewareHandler : public AsyncWebHandler {
23  public:
24  MiddlewareHandler(AsyncWebHandler *next) : next_(next) {}
25 
26  bool canHandle(AsyncWebServerRequest *request) override { return next_->canHandle(request); }
27  void handleRequest(AsyncWebServerRequest *request) override { next_->handleRequest(request); }
28  void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len,
29  bool final) override {
30  next_->handleUpload(request, filename, index, data, len, final);
31  }
32  void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override {
33  next_->handleBody(request, data, len, index, total);
34  }
35  bool isRequestHandlerTrivial() override { return next_->isRequestHandlerTrivial(); }
36 
37  protected:
38  AsyncWebHandler *next_;
39 };
40 
41 struct Credentials {
42  std::string username;
43  std::string password;
44 };
45 
47  public:
48  AuthMiddlewareHandler(AsyncWebHandler *next, Credentials *credentials)
49  : MiddlewareHandler(next), credentials_(credentials) {}
50 
51  bool check_auth(AsyncWebServerRequest *request) {
52  bool success = request->authenticate(credentials_->username.c_str(), credentials_->password.c_str());
53  if (!success) {
54  request->requestAuthentication();
55  }
56  return success;
57  }
58 
59  void handleRequest(AsyncWebServerRequest *request) override {
60  if (!check_auth(request))
61  return;
63  }
64  void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len,
65  bool final) override {
66  if (!check_auth(request))
67  return;
68  MiddlewareHandler::handleUpload(request, filename, index, data, len, final);
69  }
70  void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override {
71  if (!check_auth(request))
72  return;
73  MiddlewareHandler::handleBody(request, data, len, index, total);
74  }
75 
76  protected:
78 };
79 
80 } // namespace internal
81 
82 class WebServerBase : public Component {
83  public:
84  void init() {
85  if (this->initialized_) {
86  this->initialized_++;
87  return;
88  }
89  this->server_ = std::make_shared<AsyncWebServer>(this->port_);
90  // All content is controlled and created by user - so allowing all origins is fine here.
91  DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
92  this->server_->begin();
93 
94  for (auto *handler : this->handlers_)
95  this->server_->addHandler(handler);
96 
97  this->initialized_++;
98  }
99  void deinit() {
100  this->initialized_--;
101  if (this->initialized_ == 0) {
102  this->server_ = nullptr;
103  }
104  }
105  std::shared_ptr<AsyncWebServer> get_server() const { return server_; }
106  float get_setup_priority() const override;
107 
108  void set_auth_username(std::string auth_username) { credentials_.username = std::move(auth_username); }
109  void set_auth_password(std::string auth_password) { credentials_.password = std::move(auth_password); }
110 
111  void add_handler(AsyncWebHandler *handler);
112 
113  void add_ota_handler();
114 
115  void set_port(uint16_t port) { port_ = port; }
116  uint16_t get_port() const { return port_; }
117 
118  protected:
119  friend class OTARequestHandler;
120 
121  int initialized_{0};
122  uint16_t port_{80};
123  std::shared_ptr<AsyncWebServer> server_{nullptr};
124  std::vector<AsyncWebHandler *> handlers_;
126 };
127 
128 class OTARequestHandler : public AsyncWebHandler {
129  public:
130  OTARequestHandler(WebServerBase *parent) : parent_(parent) {}
131  void handleRequest(AsyncWebServerRequest *request) override;
132  void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len,
133  bool final) override;
134  bool canHandle(AsyncWebServerRequest *request) override {
135  return request->url() == "/update" && request->method() == HTTP_POST;
136  }
137 
138  // NOLINTNEXTLINE(readability-identifier-naming)
139  bool isRequestHandlerTrivial() override { return false; }
140 
141  protected:
142  uint32_t last_ota_progress_{0};
143  uint32_t ota_read_length_{0};
145 };
146 
147 } // namespace web_server_base
148 } // namespace esphome
149 #endif
void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override
AuthMiddlewareHandler(AsyncWebHandler *next, Credentials *credentials)
bool canHandle(AsyncWebServerRequest *request) override
void set_auth_username(std::string auth_username)
bool canHandle(AsyncWebServerRequest *request) override
void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override
void handleRequest(AsyncWebServerRequest *request) override
void handleRequest(AsyncWebServerRequest *request) override
std::string size_t len
Definition: helpers.h:292
std::vector< AsyncWebHandler * > handlers_
void set_auth_password(std::string auth_password)
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
std::shared_ptr< AsyncWebServer > get_server() const
void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) override
void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) override