actix / actix-web

Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
https://actix.rs
Apache License 2.0
21.6k stars 1.67k forks source link

Support for `X-Forwarded-Prefix` #3143

Open Valentin-Metz opened 1 year ago

Valentin-Metz commented 1 year ago

Expected Behavior

Reverse proxies have the ability to deploy specific routes behind a URL-prefix. This allows multiple webservers to serve on the same site without having to adapt their respective frontend. The reverse proxy takes care of stripping the URL-prefix out of incoming requests, but it is the responsibility of the backend-server to re-attach this prefix to links served on site.

Example: https://doc.traefik.io/traefik/middlewares/http/stripprefix/

Current Behavior

Currently Actix has no support for this and (resource-)links served on site will break.

Possible Solution

The server can utilize the X-Forwarded-Prefix attached by the reverse proxy to reconstruct the expected relative site-root.

Quote from traefik docs: If your backend is serving assets (e.g. images or JavaScript files), it can use the X-Forwarded-Prefix header to properly construct relative URLs. Using the previous example, the backend should return /products/shoes/image.png (and not /image.png, which Traefik would likely not be able to associate with the same backend).

Here is what aspnetcore did: https://github.com/dotnet/aspnetcore/issues/23263

Steps to Reproduce (for bugs)

  1. Host an Actix server behind a reverse proxy
  2. Strip the URL-prefix

Context

Without this feature it is a lot harder to share a single domain between multiple webservers.

Your Environment

Actix with Leptos behind Traefik.

varshard commented 10 months ago

@Valentin-Metz Do you mind elaborate more on the steps to reproduce?

  1. Strip the URL-prefix

Let's say we have an endpoint /foo/image.png. This step is to put /foo on X-Forwarded-Prefix and cut the URL to just /image.png. The expected behavior is that the response should have the Location header as /foo/image.png, right?

Valentin-Metz commented 10 months ago

@Valentin-Metz Do you mind elaborate more on the steps to reproduce?

  1. Strip the URL-prefix

Let's say we have an endpoint /foo/image.png. This step is to put /foo on X-Forwarded-Prefix and cut the URL to just /image.png. The expected behavior is that the response should have the Location header as /foo/image.png, right?

The reverse proxy (e.g. Traefik) will take care of stripping the URL from /foo/image.png down to /image.png. To a website hosted by Actix (for example with Leptos) it should appear as if it were hosted directly on / itself. For links to work, it is then necessary to reattach the prefix to the URL, because all links that the webframework will generate, will point relative to /. That's why the reverse proxy tells the webserver about the prefix it strips from the URL with X-Forwarded-Prefix, so that it may re-insert it into links presented on the page.