Browse Source

* Fix s3 auth with proxy request

pull/7403/head
zuzuviewer 1 month ago
parent
commit
f7694e0b61
  1. 78
      weed/s3api/auth_signature_v4.go

78
weed/s3api/auth_signature_v4.go

@ -591,44 +591,60 @@ func extractSignedHeaders(signedHeaders []string, r *http.Request) (http.Header,
// extractHostHeader returns the value of host header if available.
func extractHostHeader(r *http.Request) string {
// Check for X-Forwarded-Host header first, which is set by reverse proxies
if forwardedHost := r.Header.Get("X-Forwarded-Host"); forwardedHost != "" {
// Check if X-Forwarded-Host already contains a port
// This handles proxies (like Traefik, HAProxy) that include port in X-Forwarded-Host
if _, _, err := net.SplitHostPort(forwardedHost); err == nil {
// X-Forwarded-Host already contains a port (e.g., "example.com:8443" or "[::1]:8080")
// Use it as-is
return forwardedHost
forwardedHost := r.Header.Get("X-Forwarded-Host")
forwardedPort := r.Header.Get("X-Forwarded-Port")
forwardedProto := r.Header.Get("X-Forwarded-Proto")
// If X-Forwarded-Host is set, use that as the host.
// If X-Forwarded-Port is set, use that too to form the host.
// If X-Forwarded-Proto is set, check if is it default to omit the port.
if forwardedHost != "" {
extractedHost := forwardedHost
host, port, err := net.SplitHostPort(extractedHost)
if err == nil {
extractedHost = host
if forwardedPort == "" {
forwardedPort = port
}
}
// An IPv6 address literal must be enclosed in square brackets.
if ip := net.ParseIP(forwardedHost); ip != nil && strings.Contains(forwardedHost, ":") {
forwardedHost = "[" + forwardedHost + "]"
scheme := r.URL.Scheme
if forwardedProto != "" {
scheme = forwardedProto
}
// X-Forwarded-Host doesn't contain a port, check if X-Forwarded-Port is provided
if forwardedPort := r.Header.Get("X-Forwarded-Port"); forwardedPort != "" {
// Determine the protocol to check for standard ports
proto := strings.ToLower(r.Header.Get("X-Forwarded-Proto"))
// Only add port if it's not the standard port for the protocol
if (proto == "https" && forwardedPort != "443") || (proto != "https" && forwardedPort != "80") {
return forwardedHost + ":" + forwardedPort
}
if !isDefaultPort(scheme, forwardedPort) {
extractedHost = net.JoinHostPort(extractedHost, forwardedPort)
}
return extractedHost
} else {
// Go http server removes "host" from Request.Header
host := r.Host
if host == "" {
host = r.URL.Host
}
// Using reverse proxy with X-Forwarded-Host (standard port or no port forwarded).
return forwardedHost
h, port, err := net.SplitHostPort(host)
if err != nil {
return host
}
if isDefaultPort(r.URL.Scheme, port) {
return h
}
return host
}
}
hostHeaderValue := r.Host
// For standard requests, this should be fine.
if r.Host != "" {
return hostHeaderValue
func isDefaultPort(scheme, port string) bool {
if port == "" {
return true
}
// If no host header is found, then check for host URL value.
if r.URL.Host != "" {
hostHeaderValue = r.URL.Host
switch port {
case "80":
return strings.EqualFold(scheme, "http")
case "443":
return strings.EqualFold(scheme, "https")
default:
return false
}
return hostHeaderValue
}
// getScope generate a string of a specific date, an AWS region, and a service.

Loading…
Cancel
Save