fix(s3api): correctly extract host header port in extractHostHeader (#8464)
* Prevent concurrent maintenance tasks per volume * fix panic * fix(s3api): correctly extract host header port when X-Forwarded-Port is present * test(s3api): add test cases for misreported X-Forwarded-Port
This commit is contained in:
@@ -828,29 +828,32 @@ func extractHostHeader(r *http.Request, externalHost string) string {
|
|||||||
} else {
|
} else {
|
||||||
host = strings.TrimSpace(forwardedHost)
|
host = strings.TrimSpace(forwardedHost)
|
||||||
}
|
}
|
||||||
// Baseline port from forwarded port if available
|
|
||||||
if forwardedPort != "" {
|
|
||||||
port = forwardedPort
|
|
||||||
}
|
|
||||||
// If the host itself contains a port, it should take precedence
|
// If the host itself contains a port, it should take precedence
|
||||||
if h, p, err := net.SplitHostPort(host); err == nil {
|
if h, p, err := net.SplitHostPort(host); err == nil {
|
||||||
host = h
|
host = h
|
||||||
port = p
|
port = p
|
||||||
|
} else {
|
||||||
|
// If X-Forwarded-Host has no port, try to get port from r.Host if hostnames match
|
||||||
|
if rh, rp, err := net.SplitHostPort(r.Host); err == nil && rh == host {
|
||||||
|
port = rp
|
||||||
|
} else if forwardedPort != "" {
|
||||||
|
port = forwardedPort
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
host = r.Host
|
host = r.Host
|
||||||
if host == "" {
|
if host == "" {
|
||||||
host = r.URL.Host
|
host = r.URL.Host
|
||||||
}
|
}
|
||||||
// Also apply X-Forwarded-Port in the fallback path
|
|
||||||
if forwardedPort != "" {
|
// If the host already contains a port, use it.
|
||||||
if h, _, err := net.SplitHostPort(host); err == nil {
|
// Otherwise, if X-Forwarded-Port is set, use it.
|
||||||
host = h
|
if h, p, err := net.SplitHostPort(host); err == nil {
|
||||||
}
|
|
||||||
port = forwardedPort
|
|
||||||
} else if h, p, err := net.SplitHostPort(host); err == nil {
|
|
||||||
host = h
|
host = h
|
||||||
port = p
|
port = p
|
||||||
|
} else if forwardedPort != "" {
|
||||||
|
port = forwardedPort
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -364,6 +364,31 @@ func TestExtractHostHeader(t *testing.T) {
|
|||||||
externalHost: "[::1]:9000",
|
externalHost: "[::1]:9000",
|
||||||
expected: "[::1]:9000",
|
expected: "[::1]:9000",
|
||||||
},
|
},
|
||||||
|
// Bug fix: X-Forwarded-Port should not override more specific ports in other headers
|
||||||
|
{
|
||||||
|
name: "User reported case: X-Forwarded-Port misreports 443 but Host has 30007",
|
||||||
|
hostHeader: "storage-stgops.mt.mtnet:30007",
|
||||||
|
forwardedHost: "storage-stgops.mt.mtnet",
|
||||||
|
forwardedPort: "443",
|
||||||
|
forwardedProto: "https",
|
||||||
|
expected: "storage-stgops.mt.mtnet:30007",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "X-Forwarded-Host already contains correct port, ignore misaligned X-Forwarded-Port",
|
||||||
|
hostHeader: "backend:8333",
|
||||||
|
forwardedHost: "storage-stgops.mt.mtnet:30007",
|
||||||
|
forwardedPort: "443",
|
||||||
|
forwardedProto: "https",
|
||||||
|
expected: "storage-stgops.mt.mtnet:30007",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "X-Forwarded-Host has no port, match r.Host hostname and take its port",
|
||||||
|
hostHeader: "example.com:8080",
|
||||||
|
forwardedHost: "example.com",
|
||||||
|
forwardedPort: "80",
|
||||||
|
forwardedProto: "http",
|
||||||
|
expected: "example.com:8080",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|||||||
Reference in New Issue
Block a user