Stop the frontend from naming the address it is served from - #43
Conversation
Every call was written against `http://localhost:8080` -- twenty places across the three service modules, the i18n load path, the favicon in index.html and the event bus. They are relative now, so the web UI addresses whatever origin served it rather than a host and port compiled into the bundle. The event bus is the one exception. sockjs-client validates its URL and rejects one with no host and no protocol, so '/eventbus' throws at construction; it derives an absolute URL from the page's own origin instead. The existing tests would not have caught that -- eventBusChannel.test.js drives a fake transport, not the real client. Under `yarn start` the CRA dev server serves from :3000 while the backend listens on :8080, and it cannot proxy the SockJS connection. `proxy` in package.json forwards /api and /locales; .env.development points the event bus at the backend directly. Neither is used by a packaged build. This falsifies one paragraph of the javadoc on listenHost(), which argued that nothing was lost by binding narrowly because the frontend hardcoded localhost, so a browser elsewhere would talk to its own loopback and remote use never worked. That is no longer true. The paragraph is rewritten rather than left standing, and the conclusion is deliberately kept: remote use would now work if the socket bound wider, and the reason to stay on the loopback becomes the plainer one -- the API has no authentication. See the discussion in the pull request for whether that should change. Credit for the relative addressing goes to kairoh's fork, commit 74f53cc, recorded under "Code from other forks" in the README with what is and is not taken from it. 284 Java tests and 57 JavaScript tests on this tree, unchanged from master: this adds no test. The behaviour it changes is the address a request is sent to, which the existing suites exercise against a running server. Co-authored-by: kairoh <3878594+kairoh@users.noreply.github.com>
Restores ServerBindingTest, which had been dropped as a duplicate of HttpServerBindingTest. It is not one. That test starts a bare server on listenHost() and proves the operating system honours the address; this one deploys the real MainVerticle and proves start() actually uses it. A bare server bound correctly says nothing about what the application does. The two cases that made no sense after the design settled are gone: they asserted studio.port and studio.host, which do not exist. What is left is the loopback answering and every other address of this machine refusing, against the deployed verticle. The cost is that the real verticle binds the fixed LISTEN_PORT and cannot be pointed elsewhere -- deliberately, since a test-only seam to vary it would be the same override under another name. So both cases skip when that port is already taken, which on a developer's machine means a running STUdio. On a runner it is free and they execute. HttpServerBindingTest stays precisely because it covers the address unconditionally. Verified both ways rather than assumed: with 8080 held they skip, with it free they run and pass. One observation recorded in the javadoc: LISTEN_PORT is a static final int, so javac inlines it into this test -- the same trap that made listenHost() a method rather than a field. Milder here, since a stale copy makes the test connect to the wrong port and go red rather than silently agree with itself, but the same shape of problem. 286 Java tests, 0 failures, 39 skipped on Linux.
|
The answer to your question is no, and it is the answer you offered: not until the API authenticates. Nothing about On the rest: the javadoc rewrite is right, and keeping the old reason as history was the correct call. I would not have thought to phrase it that way. You were also right where I was wrong about the tests. I said yours was the one I would keep. Keeping both, for the reason you put in The attribution section reads well, and I am glad it says what is not taken from that commit as clearly as what is. Two things before this can go in, neither of them about your code:
Your "unrelated, take it or leave it" note is worth taking separately. |
Hello — first contribution here, so please tell me if any of this cuts across how you want the project to go.
This removes the twenty places where the frontend writes
http://localhost:8080and makes them relative, so the web UI addresses whatever origin served it instead of a host and port baked into the bundle.It touches one paragraph of your reasoning, which is why I am asking rather than just proposing.
What is in it
index.htmlbecome relative.'/eventbus'throws at construction; it derives an absolute URL fromwindow.location.origininstead. Worth noting the existing tests would not have caught that —eventBusChannel.test.jsdrives a fake transport, not the real client.proxyinpackage.jsonplus a.env.developmentkeepyarn startworking: the CRA dev server serves from:3000, cannot proxy the SockJS connection, and would otherwise break the dev loop. Neither file affects a packaged build.The paragraph I had to rewrite, and the question
MainVerticle.listenHost()argues:That was exactly right, and this change makes it false — the frontend no longer hardcodes anything, so remote use would work if the socket bound wider. You anticipated this:
I have rewritten the paragraph to state the current facts while keeping your conclusion: the loopback stays, and the reason becomes the plainer one — the API has no authentication, so a wider binding hands it to anyone on the segment. I deliberately did not change the binding itself. Please rewrite that javadoc however you prefer; I was trying not to leave a comment in the tree that says something untrue, not to argue the point through it.
The question: would you be open to a follow-up making the listen address configurable — something like
-Dstudio.host/-Dstudio.port, defaulting to the loopback exactly as now?I had written that (with tests) before seeing your fix, and dropped it in favour of yours, which I think is the right call for this PR. But the capability argument against it was the frontend, and that is what this removes. If your answer is "not until the API authenticates", that is a good answer and I will drop it for good rather than keep proposing it — I would just rather ask than assume.
Checks
284Java tests and57JavaScript tests pass on this branch, on Temurin 11 and Node 12 — the versions your CI uses. No test is added: what changes is the address a request goes to, which the existing suites already exercise against a running server.mvn packagebuilds the bundle.Not verified: Windows, which I have no machine for. Your CI covers it.
Attribution
The relative addressing comes from @kairoh's fork, commit
74f53cc(April 2022, before that fork moved to Quarkus, so it applied to this same Vert.x code). Both projects are MPL-2.0. I have added a "Code from other forks" section to the README recording what is and is not taken from it — happy to move or drop that section if you would rather record it elsewhere.Unrelated, take it or leave it
mvn packagerewrites the trackedyarn.lockon every run. Theyarn-update-browserslistexecution runsnpx browserslist@latest --update-db, which by design removes and reinstallscaniuse-lite. It also means a packaging build fetches@latestof a tool from npm. Yourgit diff --exit-codestep cannot see it, since the job that runs it skips the frontend goals. Not part of this PR, just something I tripped over.