* Add HTTP-parser lib to support ESP32 WebServer * Add WebServer from ESP32. Only supports HTTP * Separate HTTP server from the network server Instead of managing the WiFiServer/WiFiServerSecure in the same object as the HTTP handling, split them into separate objects. This lets HTTP and HTTPS servers work without templates or duplicating code. The HTTP block just gets a `WiFiClient*` and works with that to only do HTTP processing, while the upper object handles the appropriate server and client types. * Add HTTPS server * Clean up some THandlerFunction refs * Refactor into a template-ized WebServer/WebServerSecure * Add DNSServer examples which need WebServer * Fix CoreMutex infinite recursion crash Core could crash while Serial debugging was going on and prints were happening from LWIP/IRQ land and the main app. * Add HTTPUpdateServer(Secure) * Add MIME include, optimize WebServer::send(size,len) When send()ing a large buffer, the WebServer::send() call would actually convert that buffer into a String (i.e. duplicate it, and potential issues with embedded \0s in binary data). Make a simple override to send(size, len) to allow writing from the source buffer instead. * Fix WiFiClient::send(Stream), add FSBrowser example
134 lines
4 KiB
C++
134 lines
4 KiB
C++
#include <WiFi.h>
|
|
#include <WiFiClient.h>
|
|
#include <WebServer.h>
|
|
|
|
#ifndef STASSID
|
|
#define STASSID "your-ssid"
|
|
#define STAPSK "your-password"
|
|
#endif
|
|
|
|
const char* ssid = STASSID;
|
|
const char* password = STAPSK;
|
|
|
|
WebServer server(80);
|
|
|
|
// Check if header is present and correct
|
|
bool is_authenticated() {
|
|
Serial.println("Enter is_authenticated");
|
|
if (server.hasHeader("Cookie")) {
|
|
Serial.print("Found cookie: ");
|
|
String cookie = server.header("Cookie");
|
|
Serial.println(cookie);
|
|
if (cookie.indexOf("PICOSESSIONID=1") != -1) {
|
|
Serial.println("Authentication Successful");
|
|
return true;
|
|
}
|
|
}
|
|
Serial.println("Authentication Failed");
|
|
return false;
|
|
}
|
|
|
|
// login page, also called for disconnect
|
|
void handleLogin() {
|
|
String msg;
|
|
if (server.hasHeader("Cookie")) {
|
|
Serial.print("Found cookie: ");
|
|
String cookie = server.header("Cookie");
|
|
Serial.println(cookie);
|
|
}
|
|
if (server.hasArg("DISCONNECT")) {
|
|
Serial.println("Disconnection");
|
|
server.sendHeader("Location", "/login");
|
|
server.sendHeader("Cache-Control", "no-cache");
|
|
server.sendHeader("Set-Cookie", "PICOSESSIONID=0");
|
|
server.send(301);
|
|
return;
|
|
}
|
|
if (server.hasArg("USERNAME") && server.hasArg("PASSWORD")) {
|
|
if (server.arg("USERNAME") == "admin" && server.arg("PASSWORD") == "admin") {
|
|
server.sendHeader("Location", "/");
|
|
server.sendHeader("Cache-Control", "no-cache");
|
|
server.sendHeader("Set-Cookie", "PICOSESSIONID=1");
|
|
server.send(301);
|
|
Serial.println("Log in Successful");
|
|
return;
|
|
}
|
|
msg = "Wrong username/password! try again.";
|
|
Serial.println("Log in Failed");
|
|
}
|
|
String content = "<html><body><form action='/login' method='POST'>To log in, please use : admin/admin<br>";
|
|
content += "User:<input type='text' name='USERNAME' placeholder='user name'><br>";
|
|
content += "Password:<input type='password' name='PASSWORD' placeholder='password'><br>";
|
|
content += "<input type='submit' name='SUBMIT' value='Submit'></form>" + msg + "<br>";
|
|
content += "You also can go <a href='/inline'>here</a></body></html>";
|
|
server.send(200, "text/html", content);
|
|
}
|
|
|
|
// root page can be accessed only if authentication is ok
|
|
void handleRoot() {
|
|
Serial.println("Enter handleRoot");
|
|
String header;
|
|
if (!is_authenticated()) {
|
|
server.sendHeader("Location", "/login");
|
|
server.sendHeader("Cache-Control", "no-cache");
|
|
server.send(301);
|
|
return;
|
|
}
|
|
String content = "<html><body><H2>hello, you successfully connected to Pico W!</H2><br>";
|
|
if (server.hasHeader("User-Agent")) {
|
|
content += "the user agent used is : " + server.header("User-Agent") + "<br><br>";
|
|
}
|
|
content += "You can access this page until you <a href=\"/login?DISCONNECT=YES\">disconnect</a></body></html>";
|
|
server.send(200, "text/html", content);
|
|
}
|
|
|
|
// no need authentication
|
|
void handleNotFound() {
|
|
String message = "File Not Found\n\n";
|
|
message += "URI: ";
|
|
message += server.uri();
|
|
message += "\nMethod: ";
|
|
message += (server.method() == HTTP_GET) ? "GET" : "POST";
|
|
message += "\nArguments: ";
|
|
message += server.args();
|
|
message += "\n";
|
|
for (uint8_t i = 0; i < server.args(); i++) {
|
|
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
|
|
}
|
|
server.send(404, "text/plain", message);
|
|
}
|
|
|
|
void setup(void) {
|
|
Serial.begin(115200);
|
|
WiFi.mode(WIFI_STA);
|
|
WiFi.begin(ssid, password);
|
|
Serial.println("");
|
|
|
|
// Wait for connection
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(500);
|
|
Serial.print(".");
|
|
}
|
|
Serial.println("");
|
|
Serial.print("Connected to ");
|
|
Serial.println(ssid);
|
|
Serial.print("IP address: ");
|
|
Serial.println(WiFi.localIP());
|
|
|
|
|
|
server.on("/", handleRoot);
|
|
server.on("/login", handleLogin);
|
|
server.on("/inline", []() {
|
|
server.send(200, "text/plain", "this works without need of authentication");
|
|
});
|
|
|
|
server.onNotFound(handleNotFound);
|
|
// ask server to track these headers
|
|
server.collectHeaders("User-Agent", "Cookie");
|
|
server.begin();
|
|
Serial.println("HTTP server started");
|
|
}
|
|
|
|
void loop(void) {
|
|
server.handleClient();
|
|
}
|