Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Feature request: Configurable WebSocket location #626

Closed
allan2 opened this issue Dec 12, 2023 · 8 comments
Closed

Feature request: Configurable WebSocket location #626

allan2 opened this issue Dec 12, 2023 · 8 comments
Milestone

Comments

@allan2
Copy link

allan2 commented Dec 12, 2023

Originally opened as ctron#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: (app.example.com)
  • non-root path: (example.com/app)

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
Copy link
Contributor

hmacias-avaya commented Feb 5, 2024

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
Copy link
Collaborator

ctron commented Feb 5, 2024

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
Copy link
Contributor

hmacias-avaya commented Feb 5, 2024

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 #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:

  • browser requests https://server.com/something/index.html
  • trunk replies with html content. It contains <link rel="preload" href="/resource.wasm"
  • browser tries to then request https://server.com/resource.wasm which fails (not because of trunk, but because the reverse proxy cannot understand this needs to be routed to trunk because trunk did not use a ./ relative url.

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:

  • browser requests https://server.com/something/index.html
  • trunk replies with html content. It contains <link rel="preload" href="./resource.wasm"
  • browser tries to then request https://server.com/something/resource.wasm which should work as the /something path is the same one used for all resources.

...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
Copy link
Contributor

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
Copy link
Collaborator

ctron commented Feb 12, 2024

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
Copy link
Contributor

thanks, I've just created #714, let's see if that makes sense.
That is by no means complete but hopefully enough to share the intention.

ctron added a commit to ctron/trunk that referenced this issue Feb 16, 2024
This change introduced the idea of the three different base URLs:

* The public base/common prefix, when generating links
* The "serve base", when serving content using `trunk serve`
* The "websocket base", where the auto-reload websocket connects to

The sane default still is to use an absolute --public-url, defaulting to
`/`. However, each of the URLs/bases can be overridden when necessary.

Closes: trunk-rs#668, trunk-rs#626
ctron added a commit that referenced this issue Feb 16, 2024
This change introduced the idea of the three different base URLs:

* The public base/common prefix, when generating links
* The "serve base", when serving content using `trunk serve`
* The "websocket base", where the auto-reload websocket connects to

The sane default still is to use an absolute --public-url, defaulting to
`/`. However, each of the URLs/bases can be overridden when necessary.

Closes: #668, #626
@ctron ctron added this to the 0.19.0 milestone Mar 1, 2024
@ctron
Copy link
Collaborator

ctron commented Mar 1, 2024

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
Copy link
Collaborator

ctron commented Mar 12, 2024

Trunk 0.19.0 was released.

@ctron ctron closed this as completed Mar 12, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants