trunk-rs / trunk

Build, bundle & ship your Rust WASM application to the web.
https://trunkrs.dev/
Apache License 2.0
3.48k stars 252 forks source link

Feature request: Configurable WebSocket location #626

Closed allan2 closed 7 months ago

allan2 commented 10 months ago

Originally opened as https://github.com/trunk-dev/trunk/issues/10.

Opening here due to the recent changes breathing life into upstream Trunk ;)


I would like to use Nginx in front of Trunk when developing, but I am encountering some problems with autoreload.

Trunk serves on [::1]:8080. I would like to be able to use both of these configurations:

subdomain setup (app.example.com)

server {
    ...

    server_name app.example.com;

    location / {
        proxy_pass http://[::1]:8080;
    }

    location /_trunk/ws {
        proxy_pass http://[::1]:8080;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
    }
}

non-root-path setup (example.com/app)

server {
    ...

    server_name example.com;

    location / {
        ...  # do other things
    }

   location /app/ {
        proxy_pass http://[::1]:8080;
    }

    location /app/_trunk/ws {
        proxy_pass http://[::1]:8080;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
    }
}

In this setup, public_url must be set in Trunk.toml for the SPA to load:

[Build]
public_url = "/app/"

The SPA must also be made aware of the pathname to route properly.

In this configuration, Trunk is looking for the WS socket in the wrong place at https://example.com/_trunk/ws. This affects both thedodd/trunk and ctron/trunk.

It would be nice if the socket location also followed public_url or if it could be configured separately.

(I filed this issue here instead of upstream because it seems more active)

Thank you!

hmacias-avaya commented 8 months ago

I have a slightly related issue. I'm commenting here as I do think this is related and may help solve the issue without having to add an additional configuration option (if you prefer me to open another issue just let me know).

Shouldn't the /_trunk/ws url be relative to whatever that started the application?

Currently trunk/autoreload is looking at the browser address and adding /_trunk/ws. Shouldn't it also check the browser's location and keep that?

For example, I'm serving an application behind a reverse proxy. I'm browsing https://server.com/some/path/ and this reaches trunk. Shouldn't autoreload be trying to connect to https://server.com/some/path/_trunk/ws (in other words, relative to the URL that loaded the application) instead of trying to connect to https://server.com/_trunk/ws (which at least in this reverse proxy scenario results in the route not being found)?

I can tinker with the reverse proxy configuration but ideally this should be transparent. Whichever path the browser used to reach index.html should be used again for reaching _trunk/ws

ctron commented 8 months ago

Shouldn't the /_trunk/ws url be relative to whatever that started the application? I would say that this endpoint is something specific to trunk (serve). Right now, trunk serve assuming that it is directly being accessed by the user. So have a "well known" path works just fine.

Having that nested somewhere in a lower path might actually make things a bit more complicated. As stuff might overlap now with other paths (like proxied stuff).

hmacias-avaya commented 8 months ago

Perhaps I'm missing the bigger picture, sorry. I may be mixing things again but I do believe are related.

The point I was trying to make is (and I believe this is also related to how other resources are loaded using a non "./" relative url such as https://github.com/trunk-rs/trunk/issues/668) is the following:

If the html produced/served by trunk is using /resource for the urls (e.g. <link rel="preload" href="/resource.wasm" as="fetch") this means any scenario where a reverse proxy is manipulating the URLs before trunk will not work or (if possible) will need tinkering with configuration in order to work. (and I believe is also the case for the websocket at /_trunk/ws although the way the websocket url is created is different).

For example:

If, on the other hand, the html produced/served by trunk uses ./resource for the urls (and I understand ./ cannot be used for the server routing part but that is I believe slightly different), the scenarios where some reverse proxy is manipulating the URLs before trunk should work (without breaking the scenario where there is no manipulation done to the url).

In this scenario, trunk will still receive a request to https://server.com/resource.wasm or https://server.com/_trunk/ws and should continue to work, but it allows the "trunk behind reverse proxy scenario" to work because:

...of course, if there is another way to achieve this "reverse proxy scenario" which also makes the reloading ws work, please let me know :)

hmacias-avaya commented 8 months ago

in case this is of any help, I forked from 0.18.7 and made some changes to how autoreload and the rust resources are loaded, and this seems to work for me (where trunk is behind a reverse proxy) without needing to configure websocket location or doing anything else. https://github.com/hmacias-avaya/trunk/tree/relative_resources

For sure I have not gone through all the other resource types being bundled so that would need likely similar minor updates as well.

ctron commented 8 months ago

So if you have something that works, I think it would be great to have a PR so that we can take a look at this.

I am pretty sure putting a reverse proxy in front of trunk was ever considered. Still, if we could add this for 0.19.x it might be a valuable addition.

I guess having a --public-url <relative> base and --serve-url <absolute> base could work. where --serve-url defaults to --public-url, but enforces an absolute path?

hmacias-avaya commented 8 months ago

thanks, I've just created https://github.com/trunk-rs/trunk/pull/714, let's see if that makes sense. That is by no means complete but hopefully enough to share the intention.

ctron commented 7 months ago

I think this should be addressed by 0.19.x, for which there's an RC now (0.19.0-rc.1). Maybe you can give it a try.

ctron commented 7 months ago

Trunk 0.19.0 was released.