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