Sites: serve directly from FastAPI β no per-wolt servers, no ports - #383
Open
woltspace-jerpint[bot] wants to merge 2 commits into
Open
Sites: serve directly from FastAPI β no per-wolt servers, no ports#383woltspace-jerpint[bot] wants to merge 2 commits into
woltspace-jerpint[bot] wants to merge 2 commits into
Conversation
The per-wolt livereload subprocesses were vestigial: the server already
proxied every request, stripped livereload's own reload script, and
injected its own β wired to a watchfiles WebSocket the server serves
itself. The subprocess was a static file server behind a proxy, plus a
port, a state file, a liveness check, and a bind-gap needing a "waking
up" fallback page.
Now /wolt/{name}/site/* serves files straight from disk: HTML gets the
reload script injected at serve time, everything else goes through
FileResponse (ETag + Range β video on sites works now). The livereload
WebSocket is unchanged. A resolve + relative_to guard keeps requests
inside the site dir (same idiom as _serve_static), with tests that
attack it β traversal, encoding, symlink escape.
Gone: port allocation (6001-6999), site_port in wolt.json (existing
keys inert, no migration), .state/site.json, POST /sites/{name}/start
and /stop, the waking-up page, the livereload dependency, the orphaned
create-wakeup.html, and the perma-flaky PID-liveness test.
Sites scaffold at wolt creation as before; ensure_site() re-scaffolds
lazily on first request if missing. First paint is now instant β no
subprocess bind gap.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Independent review findings on the direct-serve refactor: - create-creature-wolt still imported the deleted start_site β the whole CLI died on import. Now uses ensure_site. - Directory URLs without a trailing slash 308-redirect to the canonical form so relative links inside index.html resolve (the old tornado static server did this; direct serving lost it). - Assets get the same no-cache header as HTML so livereload's refetch can't be served a stale copy. - HEAD requests supported (route was GET-only, old server answered HEAD). - Unknown-wolt 404 self-refreshes β the viewport can load the site URL before the wolt dir exists on first boot. - wolt name check tightened to re.fullmatch. - ARCHITECTURE.md + migration doc updated (ports, site.json, start_site references were stale β one actively told contributors to import the deleted function). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Deletes the per-wolt site server processes and all port machinery.
/wolt/{name}/site/*now serves straight from disk. Net β425 lines.Why
The per-wolt
livereloadsubprocesses were vestigial: the server already proxied every request, stripped livereload's own reload script, and injected its own β wired to a watchfiles WebSocket the server serves itself. Each subprocess was a static file server behind a proxy, dragging along a port (6001β6999), asite_portin wolt.json, a.state/site.jsonliveness file, and a bind-gap that needed the "waking up" fallback page.How
serve_wolt_site: direct disk serving. HTML gets the reload script injected at serve time; everything else viaFileResponse(ETag + Range β video on sites works now, the buffering proxy broke it). Livereload WS unchanged.resolve()+relative_tobefore any read, same idiom as_serve_static. Tested against literal../, encoded, deep, and symlink escapes.sites.pygutted tosite_dir()+ensure_site()(lazy starter-site scaffold, same semantics as before).site_portat creation (existing keys inert, zero migration),POST /sites/{name}/start|stop, the waking-up page, thelivereloaddependency, orphanedcreate-wakeup.html, the perma-flaky PID-liveness test.Review
Built by uxwolt (fable), then adversarially reviewed by an independent fable agent, which found: a blocker (
create-creature-woltstill imported the deletedstart_siteβ my greps missed it, no.pyextension), the missing directory redirect, missing asset no-cache, HEAD 405, and stale ARCHITECTURE.md lines (one told contributors to import the deleted function). All fixed in the second commit. The reviewer explicitly cleared: traversal guard (8 attack shapes), iframe headers (nothing adds X-Frame-Options), no downstream readers of removed fields, no circular imports, non-rodent scaffold-on-GET is pre-existing behavior.Tests
461 passed β
test_wolt_sites.pyrewritten to exercise the real ASGI route via TestClient (serving, injection, scaffold-on-request, traversal/symlink attacks, redirect, caching, HEAD). The one remaining failure (test_sessions_all_dead) is the pre-existing environment failure, unrelated; its perma-flaky siblingtest_stale_state_cleanedis deleted along with the code it tested.Behavior notes
/siteslists wolts with site dirs (no morerunning/portfields β nothing consumed them).π€ Generated with Claude Code