feat: serve static files, relay example
This commit is contained in:
@@ -81,6 +81,11 @@ void ApiServer::addService(Service& service) {
|
||||
LOG_INFO(ctx, "API", "Added service: " + String(service.getName()));
|
||||
}
|
||||
|
||||
void ApiServer::serveStatic(const String& uri, fs::FS& fs, const String& path, const String& cache_header) {
|
||||
server.serveStatic(uri.c_str(), fs, path.c_str(), cache_header.c_str()).setDefaultFile("index.html");
|
||||
LOG_INFO(ctx, "API", "Registered static file serving: " + uri + " -> " + path);
|
||||
}
|
||||
|
||||
void ApiServer::begin() {
|
||||
// Register all service endpoints
|
||||
for (auto& service : services) {
|
||||
|
||||
@@ -16,95 +16,7 @@ void StaticFileService::registerEndpoints(ApiServer& api) {
|
||||
}
|
||||
LOG_INFO(ctx, "StaticFileService", "LittleFS mounted successfully");
|
||||
|
||||
// Root endpoint - serve index.html
|
||||
api.addEndpoint("/", HTTP_GET,
|
||||
[this](AsyncWebServerRequest* request) { handleRootRequest(request); },
|
||||
std::vector<ParamSpec>{});
|
||||
|
||||
// Static file serving for any path
|
||||
api.addEndpoint("/*", HTTP_GET,
|
||||
[this](AsyncWebServerRequest* request) { handleStaticFileRequest(request); },
|
||||
std::vector<ParamSpec>{});
|
||||
// Use the built-in static file serving from ESPAsyncWebServer
|
||||
api.serveStatic("/", LittleFS, "/public", "max-age=3600");
|
||||
}
|
||||
|
||||
void StaticFileService::handleRootRequest(AsyncWebServerRequest* request) {
|
||||
// Serve index.html from root
|
||||
String path = "/index.html";
|
||||
|
||||
if (!fileExists(path)) {
|
||||
request->send(404, "text/plain", "File not found");
|
||||
return;
|
||||
}
|
||||
|
||||
File file = LittleFS.open(path, "r");
|
||||
if (!file) {
|
||||
request->send(500, "text/plain", "Failed to open file");
|
||||
return;
|
||||
}
|
||||
|
||||
String contentType = getContentType(path);
|
||||
request->send(LittleFS, path, contentType);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void StaticFileService::handleStaticFileRequest(AsyncWebServerRequest* request) {
|
||||
String path = request->url();
|
||||
|
||||
// Remove leading slash for LittleFS path
|
||||
if (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
|
||||
// If path is empty or just "/", serve index.html
|
||||
if (path.isEmpty() || path == "/") {
|
||||
path = "index.html";
|
||||
}
|
||||
|
||||
// Check if file exists
|
||||
if (!fileExists("/" + path)) {
|
||||
request->send(404, "text/plain", "File not found: " + path);
|
||||
return;
|
||||
}
|
||||
|
||||
String contentType = getContentType(path);
|
||||
request->send(LittleFS, "/" + path, contentType);
|
||||
}
|
||||
|
||||
void StaticFileService::handleNotFound(AsyncWebServerRequest* request) {
|
||||
// Try to serve index.html as fallback
|
||||
if (fileExists("/index.html")) {
|
||||
request->send(LittleFS, "/index.html", "text/html");
|
||||
} else {
|
||||
request->send(404, "text/plain", "Not found");
|
||||
}
|
||||
}
|
||||
|
||||
String StaticFileService::getContentType(const String& filename) {
|
||||
if (filename.endsWith(".html") || filename.endsWith(".htm")) {
|
||||
return "text/html";
|
||||
} else if (filename.endsWith(".css")) {
|
||||
return "text/css";
|
||||
} else if (filename.endsWith(".js")) {
|
||||
return "application/javascript";
|
||||
} else if (filename.endsWith(".json")) {
|
||||
return "application/json";
|
||||
} else if (filename.endsWith(".png")) {
|
||||
return "image/png";
|
||||
} else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg")) {
|
||||
return "image/jpeg";
|
||||
} else if (filename.endsWith(".gif")) {
|
||||
return "image/gif";
|
||||
} else if (filename.endsWith(".svg")) {
|
||||
return "image/svg+xml";
|
||||
} else if (filename.endsWith(".ico")) {
|
||||
return "image/x-icon";
|
||||
} else if (filename.endsWith(".txt")) {
|
||||
return "text/plain";
|
||||
} else {
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
|
||||
bool StaticFileService::fileExists(const String& path) {
|
||||
return LittleFS.exists(path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user