RedirectScheme redirects based on X-Forwarded-Proto header
This commit is contained in:
parent
55ba4356f2
commit
ff17ac53df
3 changed files with 31 additions and 5 deletions
|
@ -12,7 +12,17 @@ Redirecting the Client to a Different Scheme/Port
|
|||
TODO: add schema
|
||||
-->
|
||||
|
||||
RedirectScheme redirects requests from a scheme/port to another.
|
||||
The RedirectScheme middleware redirects the request if the request scheme is different from the configured scheme.
|
||||
The middleware does not work for websocket requests.
|
||||
|
||||
!!! warning "When behind another reverse-proxy"
|
||||
|
||||
When there is at least one other reverse-proxy between the client and Traefik,
|
||||
the other reverse-proxy (i.e. the last hop) needs to be a [trusted](../../routing/entrypoints.md#forwarded-headers) one.
|
||||
|
||||
Otherwise, Traefik would clean up the X-Forwarded headers coming from this last hop,
|
||||
and as the RedirectScheme middleware relies on them to determine the scheme used,
|
||||
it would not function as intended.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
|
|
|
@ -13,8 +13,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
typeSchemeName = "RedirectScheme"
|
||||
uriPattern = `^(https?:\/\/)?(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$`
|
||||
typeSchemeName = "RedirectScheme"
|
||||
uriPattern = `^(https?:\/\/)?(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$`
|
||||
xForwardedProto = "X-Forwarded-Proto"
|
||||
)
|
||||
|
||||
// NewRedirectScheme creates a new RedirectScheme middleware.
|
||||
|
@ -63,7 +64,11 @@ func rawURLScheme(req *http.Request) string {
|
|||
scheme = schemeHTTPS
|
||||
}
|
||||
|
||||
if scheme == schemeHTTP && port == ":80" || scheme == schemeHTTPS && port == ":443" || port == "" {
|
||||
if value := req.Header.Get(xForwardedProto); value != "" {
|
||||
scheme = value
|
||||
}
|
||||
|
||||
if scheme == schemeHTTP && port == ":80" || scheme == schemeHTTPS && port == ":443" {
|
||||
port = ""
|
||||
}
|
||||
|
||||
|
|
|
@ -47,11 +47,22 @@ func TestRedirectSchemeHandler(t *testing.T) {
|
|||
},
|
||||
url: "http://foo",
|
||||
headers: map[string]string{
|
||||
"X-Forwarded-Proto": "https",
|
||||
"X-Forwarded-Proto": "http",
|
||||
},
|
||||
expectedURL: "https://foo",
|
||||
expectedStatus: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "HTTP to HTTPS, with X-Forwarded-Proto to HTTPS",
|
||||
config: dynamic.RedirectScheme{
|
||||
Scheme: "https",
|
||||
},
|
||||
url: "http://foo",
|
||||
headers: map[string]string{
|
||||
"X-Forwarded-Proto": "https",
|
||||
},
|
||||
expectedStatus: http.StatusOK,
|
||||
},
|
||||
{
|
||||
desc: "HTTP with port to HTTPS without port",
|
||||
config: dynamic.RedirectScheme{
|
||||
|
|
Loading…
Reference in a new issue