/* Web Server */ const String webroot = "/web/"; //Require tailing slash void sendNotFound() { server.send(404, "text/plain", "404 - Not found"); } // Function to handle file uploads void handleFileUpload() { HTTPUpload& upload = server.upload(); static File uploadFile; if (upload.status == UPLOAD_FILE_START) { String path = webroot + "uploads/" + upload.filename; Serial.printf("UploadStart: %s\n", path.c_str()); uploadFile = SD.open(path, FILE_WRITE); if (!uploadFile) { Serial.println("Failed to open file for writing"); return; } } else if (upload.status == UPLOAD_FILE_WRITE) { // Write the received data to the file if (uploadFile) { uploadFile.write(upload.buf, upload.currentSize); } } else if (upload.status == UPLOAD_FILE_END) { // Close the file at the final chunk if (uploadFile) { uploadFile.close(); Serial.printf("UploadEnd: %s (%u)\n", upload.filename.c_str(), upload.totalSize); server.send(200, "text/plain", "File Uploaded"); } else { server.send(500, "text/plain", "File Upload Failed"); } } else { sendNotFound(); } } // Function to serve files void handleFileServe() { String path = server.uri(); String filepath = path; filepath.remove(0, 1); //Trim the prefix slash in uri filepath = webroot + filepath; Serial.println(filepath); if (SD.exists(filepath)) { File file = SD.open(filepath); if (file) { server.streamFile(file, getMime(path)); file.close(); } else { server.send(500, "text/plain", "500 - Internal Server Error"); } } else { handleRootRedirect(); } } //Redirect request to index.html void handleRootRedirect() { server.sendHeader("Location", "/index.html", true); server.send(302, "text/plain", "Redirecting to index.html"); } void registerAPIEndpoints() { server.on("/", HTTP_GET, handleRootRedirect); server.onNotFound(handleFileServe); server.on("/upload", HTTP_POST, []() { server.send(200, "text/plain", ""); // Send empty response for the upload URL }, handleFileUpload); } /* Utilities */ String getMime(const String& path) { String _contentType = "text/plain"; if (path.endsWith(".html")) _contentType = "text/html"; else if (path.endsWith(".htm")) _contentType = "text/html"; else if (path.endsWith(".css")) _contentType = "text/css"; else if (path.endsWith(".json")) _contentType = "text/json"; else if (path.endsWith(".js")) _contentType = "application/javascript"; else if (path.endsWith(".png")) _contentType = "image/png"; else if (path.endsWith(".gif")) _contentType = "image/gif"; else if (path.endsWith(".jpg")) _contentType = "image/jpeg"; else if (path.endsWith(".ico")) _contentType = "image/x-icon"; else if (path.endsWith(".svg")) _contentType = "image/svg+xml"; else if (path.endsWith(".eot")) _contentType = "font/eot"; else if (path.endsWith(".woff")) _contentType = "font/woff"; else if (path.endsWith(".woff2")) _contentType = "font/woff2"; else if (path.endsWith(".ttf")) _contentType = "font/ttf"; else if (path.endsWith(".xml")) _contentType = "text/xml"; else if (path.endsWith(".pdf")) _contentType = "application/pdf"; else if (path.endsWith(".zip")) _contentType = "application/zip"; else if (path.endsWith(".gz")) _contentType = "application/x-gzip"; else if (path.endsWith(".mp3")) _contentType = "audio/mpeg"; else if (path.endsWith(".mp4")) _contentType = "video/mp4"; else if (path.endsWith(".aac")) _contentType = "audio/aac"; else if (path.endsWith(".ogg")) _contentType = "audio/ogg"; else if (path.endsWith(".wav")) _contentType = "audio/wav"; else if (path.endsWith(".m4v")) _contentType = "video/x-m4v"; else if (path.endsWith(".webm")) _contentType = "video/webm"; else _contentType = "text/plain"; return _contentType; }