Repository navigation
Conversation
The CORS policy allowed `http://localhost:` and nothing else. It was written when the server bound every interface and was reached by name; since it binds the loopback, `listenHost()` is an address rather than a name, so the URL the application opens in the browser is `http://127.0.0.1:8080`. A browser sends an `Origin` header on a POST even when it is same-origin, so the page the application had just opened was refused by the application that opened it. The event bus handshake is a POST: every SockJS request answered `403 CORS Rejected - Invalid origin`, the channel never opened, and the UI retried for as long as it stayed open while showing the user that device monitoring was down. Nothing about it was intermittent -- it could not work at all -- and it was reported from a browser before it was reproduced with curl. The rule is that the loopback is one host under several names, so all three are accepted and the port stays open-ended, which the development server needs. It is not widened to `*`: this API has no authentication, and whatever a page on another origin could reach here, it could reach in the browser of anyone who visits it. That refusal is asserted with the same weight as the acceptance, since a policy that allowed everything would pass the nominal cases on its own.
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.
The web UI loses device monitoring the moment it is opened the way the application opens it. Reported from a browser, then reproduced with
curl:Why
The CORS policy allowed
http://localhost:.*and nothing else. It was written when the server bound every interface and was reached by name. Since it binds the loopback,listenHost()is an address rather than a name, so the URLopenInBrowseris handed ishttp://127.0.0.1:8080.A browser sends an
Originheader on a POST even when it is same-origin, so the page the application had just opened was refused by the application that opened it. The event bus handshake is a POST, so every SockJS request answered 403, the channel never opened, and the UI retried for as long as the tab stayed open while telling the user monitoring was down. Nothing about it was intermittent: opened that way, it could not work at all.The fix
The loopback is one host under several names, so
localhost,127.0.0.1and[::1]are all accepted, with the port left open-ended because the development server picks its own.Not widened to
*. This API has no authentication, and whatever a page on another origin could reach here, it could reach in the browser of anyone who visits it.CorsOriginTestasserts that refusal with the same weight as the acceptance — a policy that allowed everything would pass the nominal cases on its own — including the near misseshttp://localhost.example.com:8080andhttp://127.0.0.1.example.com:8080, which the pattern must not treat as the loopback.Verification
The test deploys the real
MainVerticle, likeStaticResourceConfinementTest, because what is under test is the router's configuration rather than a handler in isolation. It failed first with the exact production response (HTTP/1.0 403 CORS Rejected - Invalid origin), then passed.CorsOriginTest: 3 testsweb-ui, 0 failures,BUILD SUCCESSacross every module🤖 Generated with Claude Code