Repository navigation
Serve the frontend with correct MIME types, whatever the host registry says - #620
Merged
Merged
Conversation
…y says StaticFiles asks `mimetypes` for a content type, and on Windows `mimetypes` reads HKEY_CLASSES_ROOT. Any program that ever registered `.js` as `text/plain` leaves it that way for every application on that machine, so StemDeck served its own ES modules as plain text there and nowhere else. Browsers enforce strict MIME checking on module scripts and refuse to execute one served as text/plain. Every module was blocked, so nothing wired itself up. The app rendered completely and responded to nothing: hover and text selection still worked because the engine does those itself, while buttons and file drop did nothing because no listener had ever been attached. Nothing in the response is malformed on a healthy machine, which is exactly why this survived CI and every developer box. The dependency on a registry StemDeck does not control is the bug; pinning the handful of types the app actually serves removes it. Diagnosed by Dick Siemer, who supplied the console output and the cause. The tests reproduce the broken host rather than trusting the one they run on. Two of them deliberately cannot fail on a correct registry and say so in their docstrings: they guard the healthy case. The ones that carry the weight install the text/plain mapping first, including an end-to-end request that asserts the broken response before asserting the fixed one. Verified by neutering the fix: 8 of 11 fail, including that one. Closes #617
2 tasks done
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.
Closes #617
The problem
StaticFilesasksmimetypesfor a content type, and on WindowsmimetypesreadsHKEY_CLASSES_ROOT. Any program that ever registered.jsastext/plainleaves it that way for every application on that machine. StemDeck then served its own ES modules as plain text there, and nowhere else.Browsers enforce strict MIME checking on module scripts and refuse to execute one served as
text/plain:Every module is blocked, so nothing wires itself up. The app renders completely and responds to nothing. Hover and text selection keep working because the engine does those itself; buttons and file drop do nothing because no listener was ever attached.
Nothing in the response is malformed on a healthy machine, which is exactly why this survived CI, every developer box, and the whole e2e suite. The bug is the dependency on a registry StemDeck does not control.
Diagnosed by @DrSiemer, who supplied the console output and identified the cause.
The fix
_pin_static_mime_types()registers the handful of types the app actually serves, before theStaticFilesmount:.js,.mjs,.css,.json,.svg,.wasm.It sits next to the mount it protects rather than at the top of the module, so the reason is visible from the thing it affects.
Test plan
tests/test_static_mime.py, 11 tests. They reproduce the broken host rather than trusting the one they run on./js/main.jsrequest. On a sane machine these pass with or without the fix, and pretending otherwise would be worse than saying it.text/plainmapping first. One parametrised case per pinned extension, plus an end-to-end request that asserts the response really does come backtext/plainbefore asserting the fix corrects it.add_typereplaced bypass, 8 of 11 fail, including the end-to-end one.ruff checkandruff format --checkcleanbandit -r app/ -llcleangit diff --stat uv.lockempty, so the desktop in-app updater is unaffectedPre-existing, unrelated
8 failures in
test_click_render.pyandtest_transpose_export.pyon my Windows box. The identical 8 fail on cleanmain; they are ffmpeg/rubberband environment issues, not this change.Reproducing it by hand
On Windows, point
.jsattext/plainand start the app:Before this change the window renders and ignores every click. After it, the app works. Restore with
/d "text/javascript".Relationship to #619
#619 is a separate problem found while investigating this one: the app could not report a boot failure at all, because
main.jsregisters its error handlers after the wiring run that fails. That is why this arrived with clean logs. The two are independent and neither replaces the other. With #619 in place, this failure would have named itself on screen instead of presenting as a dead window.