A lightweight Python-based HTTP file server.
Custom video and audio players and a custom photo viewer
Supports ACL‑based access control, uploads, and file operations.
This service exposes a filesystem directory over HTTP, enabling:
- File operations: copy/move, rename, upload, create, delete.
- Streaming: browser‑native playback using HTTP 206 partial content. No transcoding, no extra overhead.
- Access control via in‑memory hashmap‑based ACLs (read/write/deny per resource and user).
- Detects mount points and adjusts directory type (and icon) accordingly.
- Server‑rendered HTML with minimal size.
- Fast directory listing with intelligent caching.
- Fast recursive directory size calculation (disabled by default).
- Uses only browser‑native codecs.
- Custom metadata and subtitle cache to reduce
ffmpegcalls. - Switch audio tracks directly in the browser (requires experimental Web Platform Features).
- SSA/ASS subtitle support via
JASSUBon the client. - On‑demand SSA/ASS → WebVTT conversion when JASSUB fails or is unavailable.
- Extracts embedded subtitles and chapter data from
.mkv,.mp4, and similar formats. - Auto‑loads external
.mkssubtitles matching the video basename.
- Managed by
aclmgr.pyin thescripts/directory. - ACLs define per‑path permissions: read‑only, write, or deny.
- User accounts stored in JSON, configured via
USERS_FILE. - ACL rules stored in JSON, configured via
ACL_FILE. - Both files are loaded into RAM as dictionaries.
- The default user (not logged in) is
DEFAULT. - See aclmgr documentation.
pip install -r requirements.txt- Install
ffmpegat the system level for video playback support. - A
Redisserver is required for session storage and other caching.
- The web interface requires a modern browser (2021 or newer).
- If you're using something ancient—like a 2018 relic that hasn’t seen an update in half a decade—expect broken styles and layout quirks.
Configure via environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
| SERVE_PATH | Yes | — | Directory to serve. |
| ERRLOG_FILE | No | data/error.log | Server error log. |
| ACL_FILE | No | data/acl.json | ACL rules file. |
| USERS_FILE | No | data/users.json | User accounts file. |
| SHOW_DIRSIZE | No | False | Display directory sizes. |
| REDIS_PORT | No | 6379 | Redis port. |
| REDIS_ADDR | No | 127.0.0.1 | Redis host address. |
| SECRET_KEY | No | Auto-generated | Secret key |
Development (Flask builtin, 127.0.0.1:8000):
python3 app.pyProduction (WSGI, e.g., Gunicorn):
gunicorn -b 127.0.0.1:8000 app:app -w $(nproc) -t 900For production always set the SECRET_KEY, otherwise multi-worker setup will break.
When deploying with Gunicorn, set an appropriate timeout (-t).
For large uploads or long‑running file operations, a timeout of 300–900 seconds is recommended to avoid premature termination.
It is also recommended to disable post‑buffering on the proxy to prevent odd upload behavior.
If running behind a reverse proxy (e.g., Nginx), ensure its timeout settings match Gunicorn’s to avoid mismatches.
This server has no general‑purpose endpoints; everything is path‑based with optional query modifiers.
The entire /srv/ namespace is reserved for server functionality.
No part of /srv/ can be used as a folder name in the root directory.
Static files are served from /srv/static.
GET /srv/login?redirect=encoded_url→ Returns login page, redirecting after successful login or exit.POST /srv/login→ Authenticates usingusernameandpassword(form data).GET /srv/logout→ Logs out and ends the current session.
Responses:
200→ login successful / logout acknowledged.401→ invalid credentials or not logged in.
-
GET /path?get=file→ Always returns the file or its file representation.- Regular files: returned directly.
- Overrides the server’s custom MIME handling.
- Directories: returned as a TAR archive.
- Useful for bypassing the player page for audio/video.
-
GET /path?get=static→ Returns the file as a static asset.- Applies only to files.
- Overrides the server’s custom MIME handling.
- Uses the same cache headers as
/srv/static/. - Intended for plugin usage.
GET /videopath?get=chapters→ Returns chapter data (JSON).GET /videopath?get=tracks→ Returns subtitle tracks (JSON list).GET /videopath?get=subs_ssa&id=x→ Returns subtitle trackxin SSA format.GET /videopath?get=subs_vtt&id=x→ Returns subtitle trackxin VTT format (legacy).
GET /path?sort=XY→ Sorts directory listing by field and order.X: sort field →n= name,s= size,d= date.Y: sort order →p= ascending,d= descending.
GET /dir_path?get=json→ Retrieve directory listings in JSON format.- Works only for directories.
- Sorting parameter is ignored.
Behavior:
- Results follow the server’s default order.
- Valid
typevalues:disk,directory,text,file. - Additional types defined in
app/file_types.json.
Example response for /:
[
{
"name": "media",
"path": "/media",
"type": "directory",
"mtime": 1750592302.2184954,
"size": 0
},
{
"name": "something.txt",
"path": "/something.txt",
"type": "text",
"mtime": 1750589251.4473305,
"size": 9823
},
{
"name": "STORAGE",
"path": "/STORAGE",
"type": "disk",
"capacity": 2147483648000,
"size": 509872014832,
"mtime": null
}
]The server internally uses a subset of WebDAV methods for file/folder operations.
Note: This is not full WebDAV support—these methods are used internally only.
| Method | Action performed |
|---|---|
| DELETE | Delete a file or folder |
| MKCOL | Create a new folder |
| MOVE | Rename or move an item |
| COPY | Duplicate a file or folder |
| PUT | Upload a file |
.htmlfiles are treated as plain text..webfiles are recognized as HTML pages.- Placing
index.webin any folder auto‑loads that page instead of the default listing. - Disable with
?get=defaultto show the file listing page.
Plugins allow creation of new pages and customization of the frontend GUI by dropping .web extensions into served directories.
Available at: webFILE-plugins
Distributed under the GPLv3 License. See LICENSE for details.