You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Often web application does not need to be aware of by which address it is accessed. Internal links can just use relative URLs, so it doesn't matter how it is served to the client because the browser is just told to use the same authority it used for the original request.
But sometimes an app still needs to generate absolute URLs to internal resources. Examples for this are canonical URLs or presenting links for sharing.
A trivial solution is to set the hostname and protocol as a configuration value. This works well for simple environments. But it does not work when the application serves different host names or protocols (such as http and https). And it should not the app's responsibility to care about this. That's the job of network configuration, DNS, reverse proxies etc.
An often superior solution is to reconstruct the effective request URL (what the user entered into their browser) from the available data on a per-request basis. The path and query part of the URL is contained in every request as the resource property. But the scheme and authority are typically more complex to reconstruct.
For a directly exposed application the relevant information is in the Host header (and #remote_address as default). The protocol is currently not passed from HTTP::Server so it can only be guessed from the port. But this can be improved (see #5784).
For an application running behind a reverse proxy / load balancer, the information is typically transferred via headers such as X-Forwarded-Host, X-Forwarded-Proto and X-Forwarded-Port and others. Given there's no standardization on this, there are many different configurations to consider and allow for customization of accepted headers.
The most complex part is probably differntiation between whether an application is directly exposed to incoming connections (and handles TLS termination) or if it sits behind a reverse proxy. The reason is that you wouldn't want to blindly trust any forwarded host header (shame on you, Rails! rails/rails#29893). Whether an app is running behind a reverse proxy is as good as impossible to detect at runtime, so it needs configuration. An example for such configuration would be USE_X_FORWARDED_HOST for Django.
Such a "small" feature involves a high level of complexity. This could mean it's too much for stdlib and we should keep it simple. On the other hand, it's a relatively common necessity for web applications and users frequently trip over incomplete solutions. Having an default implementation available would be a great feature.
I should also note, even guessing the original /path is just guessing. A reverse proxy could've rewritten all of it, though the most typical one is stripping a prefix for the purpose of mounting an app onto that prefix path.
Often web application does not need to be aware of by which address it is accessed. Internal links can just use relative URLs, so it doesn't matter how it is served to the client because the browser is just told to use the same authority it used for the original request.
But sometimes an app still needs to generate absolute URLs to internal resources. Examples for this are canonical URLs or presenting links for sharing.
A trivial solution is to set the hostname and protocol as a configuration value. This works well for simple environments. But it does not work when the application serves different host names or protocols (such as http and https). And it should not the app's responsibility to care about this. That's the job of network configuration, DNS, reverse proxies etc.
An often superior solution is to reconstruct the effective request URL (what the user entered into their browser) from the available data on a per-request basis. The path and query part of the URL is contained in every request as the resource property. But the scheme and authority are typically more complex to reconstruct.
For a directly exposed application the relevant information is in the
Host
header (and#remote_address
as default). The protocol is currently not passed fromHTTP::Server
so it can only be guessed from the port. But this can be improved (see #5784).For an application running behind a reverse proxy / load balancer, the information is typically transferred via headers such as
X-Forwarded-Host
,X-Forwarded-Proto
andX-Forwarded-Port
and others. Given there's no standardization on this, there are many different configurations to consider and allow for customization of accepted headers.The most complex part is probably differntiation between whether an application is directly exposed to incoming connections (and handles TLS termination) or if it sits behind a reverse proxy. The reason is that you wouldn't want to blindly trust any forwarded host header (shame on you, Rails! rails/rails#29893). Whether an app is running behind a reverse proxy is as good as impossible to detect at runtime, so it needs configuration. An example for such configuration would be
USE_X_FORWARDED_HOST
for Django.Such a "small" feature involves a high level of complexity. This could mean it's too much for stdlib and we should keep it simple. On the other hand, it's a relatively common necessity for web applications and users frequently trip over incomplete solutions. Having an default implementation available would be a great feature.
Related: #7096
The text was updated successfully, but these errors were encountered: