forked from me-no-dev/ESPAsyncWebServer
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split SimpleServer in multiple examples
- Loading branch information
1 parent
514d194
commit 2879ac9
Showing
31 changed files
with
2,029 additions
and
1,409 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
// SPDX-License-Identifier: LGPL-3.0-or-later | ||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov | ||
|
||
// | ||
// Authentification and authorization middlewares | ||
// | ||
|
||
#include <Arduino.h> | ||
#ifdef ESP32 | ||
#include <AsyncTCP.h> | ||
#include <WiFi.h> | ||
#elif defined(ESP8266) | ||
#include <ESP8266WiFi.h> | ||
#include <ESPAsyncTCP.h> | ||
#elif defined(TARGET_RP2040) | ||
#include <WebServer.h> | ||
#include <WiFi.h> | ||
#endif | ||
|
||
#include <ESPAsyncWebServer.h> | ||
|
||
static AsyncWebServer server(80); | ||
|
||
// basicAuth | ||
static AsyncAuthenticationMiddleware basicAuth; | ||
static AsyncAuthenticationMiddleware basicAuthHash; | ||
|
||
// simple digest authentication | ||
static AsyncAuthenticationMiddleware digestAuth; | ||
static AsyncAuthenticationMiddleware digestAuthHash; | ||
|
||
// complex authentication which adds request attributes for the next middlewares and handler | ||
static AsyncMiddlewareFunction complexAuth([](AsyncWebServerRequest *request, ArMiddlewareNext next) { | ||
if (!request->authenticate("user", "password")) { | ||
return request->requestAuthentication(); | ||
} | ||
|
||
// add attributes to the request for the next middlewares and handler | ||
request->setAttribute("user", "Mathieu"); | ||
request->setAttribute("role", "staff"); | ||
if (request->hasParam("token")) { | ||
request->setAttribute("token", request->getParam("token")->value().c_str()); | ||
} | ||
|
||
next(); | ||
}); | ||
|
||
static AsyncAuthorizationMiddleware authz([](AsyncWebServerRequest *request) { | ||
return request->getAttribute("token") == "123"; | ||
}); | ||
|
||
void setup() { | ||
Serial.begin(115200); | ||
|
||
#ifndef CONFIG_IDF_TARGET_ESP32H2 | ||
WiFi.mode(WIFI_AP); | ||
WiFi.softAP("esp-captive"); | ||
#endif | ||
|
||
// basic authentication | ||
basicAuth.setUsername("admin"); | ||
basicAuth.setPassword("admin"); | ||
basicAuth.setRealm("MyApp"); | ||
basicAuth.setAuthFailureMessage("Authentication failed"); | ||
basicAuth.setAuthType(AsyncAuthType::AUTH_BASIC); | ||
basicAuth.generateHash(); // precompute hash (optional but recommended) | ||
|
||
// basic authentication with hash | ||
basicAuthHash.setUsername("admin"); | ||
basicAuthHash.setPasswordHash("YWRtaW46YWRtaW4="); // BASE64(admin:admin) | ||
basicAuthHash.setRealm("MyApp"); | ||
basicAuthHash.setAuthFailureMessage("Authentication failed"); | ||
basicAuthHash.setAuthType(AsyncAuthType::AUTH_BASIC); | ||
|
||
// digest authentication | ||
digestAuth.setUsername("admin"); | ||
digestAuth.setPassword("admin"); | ||
digestAuth.setRealm("MyApp"); | ||
digestAuth.setAuthFailureMessage("Authentication failed"); | ||
digestAuth.setAuthType(AsyncAuthType::AUTH_DIGEST); | ||
digestAuth.generateHash(); // precompute hash (optional but recommended) | ||
|
||
// digest authentication with hash | ||
digestAuthHash.setUsername("admin"); | ||
digestAuthHash.setPasswordHash("f499b71f9a36d838b79268e145e132f7"); // MD5(user:realm:pass) | ||
digestAuthHash.setRealm("MyApp"); | ||
digestAuthHash.setAuthFailureMessage("Authentication failed"); | ||
digestAuthHash.setAuthType(AsyncAuthType::AUTH_DIGEST); | ||
|
||
// basic authentication method | ||
// curl -v -u admin:admin http://192.168.4.1/auth-basic | ||
server | ||
.on( | ||
"/auth-basic", HTTP_GET, | ||
[](AsyncWebServerRequest *request) { | ||
request->send(200, "text/plain", "Hello, world!"); | ||
} | ||
) | ||
.addMiddleware(&basicAuth); | ||
|
||
// basic authentication method with hash | ||
// curl -v -u admin:admin http://192.168.4.1/auth-basic-hash | ||
server | ||
.on( | ||
"/auth-basic-hash", HTTP_GET, | ||
[](AsyncWebServerRequest *request) { | ||
request->send(200, "text/plain", "Hello, world!"); | ||
} | ||
) | ||
.addMiddleware(&basicAuthHash); | ||
|
||
// digest authentication | ||
// curl -v -u admin:admin --digest http://192.168.4.1/auth-digest | ||
server | ||
.on( | ||
"/auth-digest", HTTP_GET, | ||
[](AsyncWebServerRequest *request) { | ||
request->send(200, "text/plain", "Hello, world!"); | ||
} | ||
) | ||
.addMiddleware(&digestAuth); | ||
|
||
// digest authentication with hash | ||
// curl -v -u admin:admin --digest http://192.168.4.1/auth-digest-hash | ||
server | ||
.on( | ||
"/auth-digest-hash", HTTP_GET, | ||
[](AsyncWebServerRequest *request) { | ||
request->send(200, "text/plain", "Hello, world!"); | ||
} | ||
) | ||
.addMiddleware(&digestAuthHash); | ||
|
||
// test digest auth custom authorization middleware | ||
// curl -v --digest -u user:password http://192.168.4.1/auth-custom?token=123 => OK | ||
// curl -v --digest -u user:password http://192.168.4.1/auth-custom?token=456 => 403 | ||
// curl -v --digest -u user:FAILED http://192.168.4.1/auth-custom?token=456 => 401 | ||
server | ||
.on( | ||
"/auth-custom", HTTP_GET, | ||
[](AsyncWebServerRequest *request) { | ||
String buffer = "Hello "; | ||
buffer.concat(request->getAttribute("user")); | ||
buffer.concat(" with role: "); | ||
buffer.concat(request->getAttribute("role")); | ||
request->send(200, "text/plain", buffer); | ||
} | ||
) | ||
.addMiddlewares({&complexAuth, &authz}); | ||
|
||
server.begin(); | ||
} | ||
|
||
// not needed | ||
void loop() { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// SPDX-License-Identifier: LGPL-3.0-or-later | ||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov | ||
|
||
// | ||
// How to use CORS middleware | ||
// | ||
|
||
#include <Arduino.h> | ||
#ifdef ESP32 | ||
#include <AsyncTCP.h> | ||
#include <WiFi.h> | ||
#elif defined(ESP8266) | ||
#include <ESP8266WiFi.h> | ||
#include <ESPAsyncTCP.h> | ||
#elif defined(TARGET_RP2040) | ||
#include <WebServer.h> | ||
#include <WiFi.h> | ||
#endif | ||
|
||
#include <ESPAsyncWebServer.h> | ||
|
||
static AsyncWebServer server(80); | ||
static AsyncCorsMiddleware cors; | ||
|
||
void setup() { | ||
Serial.begin(115200); | ||
|
||
#ifndef CONFIG_IDF_TARGET_ESP32H2 | ||
WiFi.mode(WIFI_AP); | ||
WiFi.softAP("esp-captive"); | ||
#endif | ||
|
||
cors.setOrigin("http://192.168.4.1"); | ||
cors.setMethods("POST, GET, OPTIONS, DELETE"); | ||
cors.setHeaders("X-Custom-Header"); | ||
cors.setAllowCredentials(false); | ||
cors.setMaxAge(600); | ||
|
||
server.addMiddleware(&cors); | ||
|
||
// Test CORS preflight request | ||
// curl -v -X OPTIONS -H "origin: http://192.168.4.1" http://192.168.4.1/cors | ||
// | ||
// Test CORS request | ||
// curl -v -H "origin: http://192.168.4.1" http://192.168.4.1/cors | ||
// | ||
// Test non-CORS request | ||
// curl -v http://192.168.4.1/cors | ||
// | ||
server.on("/cors", HTTP_GET, [](AsyncWebServerRequest *request) { | ||
request->send(200, "text/plain", "Hello, world!"); | ||
}); | ||
|
||
server.begin(); | ||
} | ||
|
||
// not needed | ||
void loop() { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// SPDX-License-Identifier: LGPL-3.0-or-later | ||
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov | ||
|
||
// | ||
// Shows how to catch all requests and send a 404 Not Found response | ||
// | ||
|
||
#include <Arduino.h> | ||
#ifdef ESP32 | ||
#include <AsyncTCP.h> | ||
#include <WiFi.h> | ||
#elif defined(ESP8266) | ||
#include <ESP8266WiFi.h> | ||
#include <ESPAsyncTCP.h> | ||
#elif defined(TARGET_RP2040) | ||
#include <WebServer.h> | ||
#include <WiFi.h> | ||
#endif | ||
|
||
#include <ESPAsyncWebServer.h> | ||
|
||
static AsyncWebServer server(80); | ||
|
||
static const char *htmlContent PROGMEM = R"( | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Sample HTML</title> | ||
</head> | ||
<body> | ||
<h1>Hello, World!</h1> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod | ||
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper | ||
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit | ||
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. | ||
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo | ||
dapibus elit, id varius sem dui id lacus.</p> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod | ||
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper | ||
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit | ||
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. | ||
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo | ||
dapibus elit, id varius sem dui id lacus.</p> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod | ||
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper | ||
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit | ||
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. | ||
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo | ||
dapibus elit, id varius sem dui id lacus.</p> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod | ||
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper | ||
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit | ||
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. | ||
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo | ||
dapibus elit, id varius sem dui id lacus.</p> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod | ||
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper | ||
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit | ||
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. | ||
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo | ||
dapibus elit, id varius sem dui id lacus.</p> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod | ||
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper | ||
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit | ||
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. | ||
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo | ||
dapibus elit, id varius sem dui id lacus.</p> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod | ||
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper | ||
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit | ||
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. | ||
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo | ||
dapibus elit, id varius sem dui id lacus.</p> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod | ||
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper | ||
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit | ||
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. | ||
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo | ||
dapibus elit, id varius sem dui id lacus.</p> | ||
</body> | ||
</html> | ||
)"; | ||
|
||
static const size_t htmlContentLength = strlen_P(htmlContent); | ||
|
||
void setup() { | ||
Serial.begin(115200); | ||
|
||
#ifndef CONFIG_IDF_TARGET_ESP32H2 | ||
WiFi.mode(WIFI_AP); | ||
WiFi.softAP("esp-captive"); | ||
#endif | ||
|
||
// curl -v http://192.168.4.1/ | ||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { | ||
// need to cast to uint8_t* | ||
// if you do not, the const char* will be copied in a temporary String buffer | ||
request->send(200, "text/html", (uint8_t *)htmlContent, htmlContentLength); | ||
}); | ||
|
||
// catch any request, and send a 404 Not Found response | ||
// except for /game_log which is handled by onRequestBody | ||
// | ||
// curl -v http://192.168.4.1/foo | ||
// | ||
server.onNotFound([](AsyncWebServerRequest *request) { | ||
if (request->url() == "/game_log") { | ||
return; // response object already created by onRequestBody | ||
} | ||
|
||
request->send(404, "text/plain", "Not found"); | ||
}); | ||
|
||
// See: https://github.com/ESP32Async/ESPAsyncWebServer/issues/6 | ||
// catch any POST request and send a 200 OK response | ||
// | ||
// curl -v -X POST http://192.168.4.1/game_log -H "Content-Type: application/json" -d '{"game": "test"}' | ||
// | ||
server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) { | ||
if (request->url() == "/game_log") { | ||
request->send(200, "application/json", "{\"status\":\"OK\"}"); | ||
} | ||
}); | ||
|
||
server.begin(); | ||
} | ||
|
||
// not needed | ||
void loop() { | ||
} |
Oops, something went wrong.