8.2 KiB
CrossPointWebServer API Reference
Source: src/network/CrossPointWebServer.cpp and CrossPointWebServer.h
Server Configuration
- HTTP port: 80 (default)
- WebSocket port: 81 (default)
- WiFi sleep disabled for responsiveness
- Supports both STA (station) and AP (access point) modes
HTTP Endpoints
GET /
Handler: handleRoot()
Response: HTML homepage from HomePageHtml (generated from html/HomePage.html)
Content-Type: text/html
GET /files
Handler: handleFileList()
Response: HTML file browser page from FilesPageHtml (generated from html/FilesPage.html)
Content-Type: text/html
GET /api/status
Handler: handleStatus()
Response: JSON device status
Content-Type: application/json
{
"version": "CROSSPOINT_VERSION",
"ip": "192.168.x.x",
"mode": "AP" | "STA",
"rssi": -50, // 0 in AP mode
"freeHeap": 123456,
"uptime": 3600 // seconds
}
GET /api/files
Handler: handleFileListData()
Query params:
path(optional): Directory path, defaults to "/"showHidden(optional): "true" to show dot-files (except .crosspoint) Response: JSON array of files Content-Type: application/json
[
{"name": "book.epub", "size": 123456, "isDirectory": false, "isEpub": true},
{"name": "folder", "size": 0, "isDirectory": true, "isEpub": false}
]
Notes:
- Hidden by default: files starting with ".", "System Volume Information", "XTCache"
- Always hidden: ".crosspoint" (internal cache folder)
- Streamed response (chunked encoding) to reduce memory usage
GET /api/archived
Handler: handleArchivedList()
Response: JSON array of archived books
Content-Type: application/json
[
{"filename": "archived_file.epub", "originalPath": "/Books/archived_file.epub"}
]
Notes: Uses BookManager::listArchivedBooks() and BookManager::getArchivedBookOriginalPath()
GET /download
Handler: handleDownload()
Query params:
path(required): File path to download Response: File binary with Content-Disposition attachment header Content-Type: application/octet-stream Errors:- 400: Missing path, path is directory
- 403: Hidden/system file, protected item
- 404: File not found Notes:
- Streams in 4KB chunks
- Updates
totalBytesDownloadedandtotalFilesDownloadedstats - Security: rejects paths with "..", files starting with ".", protected items
POST /upload
Handler: handleUpload() (multipart handler), handleUploadPost() (response handler)
Query params:
path(optional): Upload directory, defaults to "/" Form data: multipart/form-data with file Response: "File uploaded successfully: filename" or error message Notes:- Uses 4KB write buffer for SD card efficiency
- Overwrites existing files
- Clears epub cache after upload via
clearEpubCacheIfNeeded() - Updates
totalBytesUploadedandtotalFilesUploadedstats - Logs progress every 100KB
POST /mkdir
Handler: handleCreateFolder()
Form params:
name(required): Folder namepath(optional): Parent directory, defaults to "/" Response: "Folder created: foldername" or error Errors:- 400: Missing name, empty name, folder exists
POST /delete
Handler: handleDelete()
Form params:
path(required): Item path to deletetype(optional): "file" (default) or "folder"archived(optional): "true" for archived books Response: "Deleted successfully" or error Errors:- 400: Missing path, root directory, folder not empty
- 403: Hidden/system file, protected item
- 404: Item not found
- 500: Delete failed Notes:
- For files: uses
BookManager::deleteBook()which handles cache and recent books cleanup - For folders: must be empty first
- For archived: passes filename to
BookManager::deleteBook(filename, true)
POST /archive
Handler: handleArchive()
Form params:
path(required): Book path to archive Response: "Book archived successfully" or error Notes: UsesBookManager::archiveBook()
POST /unarchive
Handler: handleUnarchive()
Form params:
filename(required): Archived book filename Response: JSON with original path Content-Type: application/json
{"success": true, "originalPath": "/Books/book.epub"}
Notes: Uses BookManager::unarchiveBook() and BookManager::getArchivedBookOriginalPath()
POST /rename
Handler: handleRename()
Form params:
path(required): Current item pathnewName(required): New name (filename only, no path separators) Response: "Renamed successfully" or error Errors:- 400: Missing params, empty name, name contains "/" or "\", root directory, destination exists
- 403: System file, protected item
- 404: Source not found
- 500: Rename failed Notes:
- Renames in place (same directory, new name)
- Uses
SdMan.rename() - Clears epub cache after rename via
clearEpubCacheIfNeeded()
POST /copy
Handler: handleCopy()
Form params:
srcPath(required): Source pathdestPath(required): Full destination path (including new name) Response: "Copied successfully" or error Errors:- 400: Missing params, root directory, destination exists, copy into self
- 403: System file, protected item
- 404: Source not found
- 500: Copy failed Notes:
- Uses
copyFile()for files (4KB buffer chunks) - Uses
copyFolder()for recursive directory copy - Skips hidden files in folder copy
POST /move
Handler: handleMove()
Form params:
srcPath(required): Source pathdestPath(required): Full destination path (including new name) Response: "Moved successfully" or error Errors: Same as copy Notes:- First attempts atomic
SdMan.rename()(fast) - Falls back to copy+delete if rename fails
- Uses
deleteFolderRecursive()for folder cleanup
WebSocket Protocol (port 81)
Handler: onWebSocketEvent() via wsEventCallback() trampoline
Upload Protocol
- Client connects
- Server: (implicit connection acknowledgment)
- Client TEXT:
START:<filename>:<size>:<path> - Server TEXT:
READYorERROR:<message> - Client BIN: file data chunks (any size, recommend 64KB)
- Server TEXT:
PROGRESS:<received>:<total>(every 64KB or at end) - Server TEXT:
DONEorERROR:<message>
Events
WStype_CONNECTED: Client connected, logs connectionWStype_DISCONNECTED: Cleanup incomplete upload, delete partial fileWStype_TEXT: Parse control messages (START)WStype_BIN: Write file data, send progress, complete upload
Notes
- Faster than HTTP multipart for large files
- Direct binary writes to SD card
- Clears epub cache after upload
- Updates traffic statistics
Security
Protected Items (HIDDEN_ITEMS[])
- "System Volume Information"
- "XTCache"
Always Hidden
- ".crosspoint" (internal cache)
Security Checks Applied To
/delete: Rejects dot-files (unless archived), protected items/download: Rejects dot-files, protected items, path traversal (..)/rename: Rejects dot-files, protected items/copy: Rejects dot-files, protected items/move: Rejects dot-files, protected items
Helper Functions
clearEpubCacheIfNeeded(filePath)
- Location: anonymous namespace at top of file
- Clears epub cache if file ends with ".epub"
- Uses
Epub(filePath, "/.crosspoint").clearCache() - Called by: upload, WebSocket upload, rename
scanFiles(path, callback, showHidden)
- Iterates directory, calls callback for each FileInfo
- Yields and resets watchdog during iteration
- Filters hidden items based on showHidden flag
copyFile(srcPath, destPath) / copyFolder(srcPath, destPath)
- 4KB buffer for file copy
- Recursive for folders
- Returns bool success
deleteFolderRecursive(path)
- Static helper for move fallback
- Recursively deletes contents then directory
Traffic Statistics (mutable, updated from const handlers)
totalBytesUploadedtotalBytesDownloadedtotalFilesUploadedtotalFilesDownloadedserverStartTime(for uptime calculation)
Dependencies
<WebServer.h>- ESP32 HTTP server<WebSocketsServer.h>- WebSocket support<ArduinoJson.h>- JSON serialization<SDCardManager.h>- SD card operations (SdMan singleton)<Epub.h>- Epub cache managementBookManager.h- Book deletion, archiving, recent booksStringUtils.h- File extension checking