Repository navigation
fix: make LeLab usable over plain-HTTP LAN access - #153
Open
openpilotcc wants to merge 4 commits into
Open
openpilotcc wants to merge 4 commits into
openpilotcc wants to merge 4 commits into
Conversation
crypto.randomUUID is only exposed in secure contexts (HTTPS or localhost). Opening LeLab over plain HTTP on a LAN IP (http://<host-ip>:8000) made the SingleTabGuard effect throw a TypeError, which unmounted the whole React tree and left the page completely blank behind a correct <title> and favicon. Fall back to a crypto.getRandomValues-based v4 UUID there; the id is only used for tab election, so it does not need crypto-grade randomness.
The fallback API base was hardcoded to http://localhost:8000, so a browser on another machine opening http://<host-ip>:8000 sent every API call to its own localhost and rendered an empty UI. Production `lelab` serves the UI and the API on the same origin, so default to window.location.origin there. Dev (Vite on :8080, API on :8000) and the HF Space (UI-only, driven via ?api=) keep the localhost default.
openpilotcc
force-pushed
the
fix/plain-http-lan-access
branch
from
November 5, 2026 01:28
3c05eb8 to
4ed284a
Compare
`lelab` hardcoded 127.0.0.1, so the server could not be reached from another machine at all, even with a browser that resolved everything correctly. `--host 0.0.0.0` now binds the backend (and, in --dev, the Vite server) to the requested interface; the default stays 127.0.0.1, so nothing changes unless the flag is passed. Readiness probes and the auto-opened browser keep using loopback, which a wildcard-bound socket accepts either way.
--host alone still left the backend pinned to :8000, which may be taken or firewalled on the host. --port now selects the backend port in both prod and dev modes (the dev frontend's ?api= URL follows it), and `lelab --stop --port N` frees a matching custom backend port. The default stays 8000, so existing invocations behave as before.
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.
Summary
Accessing LeLab from another machine over plain HTTP on a LAN IP (e.g.
http://<server-ip>:8000/) rendered a completely blank page: correct<title>and favicon, empty#root, no visible errors, while the backend log showed every request succeeding. Beyond the frontend, the launcher always bound to127.0.0.1on port8000, so the server could not even be reached from other machines, or started at all if:8000was taken. This PR fixes the frontend issues and adds--host/--portflags so the network-access story works end to end.Root causes
crypto.randomUUIDis undefined in insecure contexts.SingleTabGuardcalls it unconditionally in its mount effect, but the API is only exposed in secure contexts (HTTPS orlocalhost). Onhttp://<lan-ip>:8000the effect throws aTypeError, React unmounts the whole tree, and the page goes blank.localhostaccess works, which is why it went unnoticed.http://localhost:8000. Even with (1) fixed, a browser on another machine resolved every API call against its own localhost, where nothing listens.127.0.0.1:8000unconditionally. There was no way to expose the server to the network or move it off a taken port.Changes
SingleTabGuard.tsx: feature-detectcrypto.randomUUIDand fall back to acrypto.getRandomValues-based v4 UUID. The id is only used for tab election, so it does not need crypto-grade randomness, andgetRandomValuesis available in insecure contexts.ApiContext.tsx: default the base URL towindow.location.originin production, sincelelabserves the UI and the API on the same origin (also covers access via hostname or other NICs). Two cases deliberately keep thelocalhost:8000default:--dev(Vite on:8080, API on:8000);?api=(detected with the existingisHostedSpace()helper).The
?api=query param and the stored override keep their current precedence in all cases.lelab/scripts/lelab.py: new--hostand--portoptions, defaults127.0.0.1/8000(behavior unchanged unless opted in).lelab --host 0.0.0.0 --port 9000binds the backend to the requested interface and port; in--dev,--hostalso applies to the Vite server and--portselects the backend port that the dev frontend's?api=URL points to.lelab --stop --port Nfrees a matching custom backend port. Readiness probes and the auto-opened browser stay on loopback, which a wildcard-bound socket accepts anyway.README.md: a "Custom host and port" section in Quick Start documenting both flags.Testing
pytest tests/test_scripts_lelab.py: 23 pass (6 new: parser defaults,--host/--portparsing, custom host and port threaded through both prod and dev launchers, dev browser URL pointing at the custom API port,--stopport matching).ruff checkandruff format --check: clean.npm run test: 17 files / 58 tests pass;npx tsc -bandeslintoutput is identical tomain(remaining findings are pre-existing);npm run buildsucceeds.localhost:8000.