diff options
Diffstat (limited to 'weed/s3api/s3api_server.go')
| -rw-r--r-- | weed/s3api/s3api_server.go | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/weed/s3api/s3api_server.go b/weed/s3api/s3api_server.go index 62a3121f2..5af274970 100644 --- a/weed/s3api/s3api_server.go +++ b/weed/s3api/s3api_server.go @@ -7,6 +7,7 @@ import ( "net" "net/http" "os" + "slices" "strings" "time" @@ -156,6 +157,30 @@ func NewS3ApiServerWithStore(router *mux.Router, option *S3ApiServerOption, expl return s3ApiServer, nil } +// classifyDomainNames classifies domains into path-style and virtual-host style domains. +// A domain is considered path-style if: +// 1. It contains a dot (has subdomains) +// 2. Its parent domain is also in the list of configured domains +// +// For example, if domains are ["s3.example.com", "develop.s3.example.com"], +// then "develop.s3.example.com" is path-style (parent "s3.example.com" is in the list), +// while "s3.example.com" is virtual-host style. +func classifyDomainNames(domainNames []string) (pathStyleDomains, virtualHostDomains []string) { + for _, domainName := range domainNames { + parts := strings.SplitN(domainName, ".", 2) + if len(parts) == 2 && slices.Contains(domainNames, parts[1]) { + // This is a subdomain and its parent is also in the list + // Register as path-style: domain.com/bucket/object + pathStyleDomains = append(pathStyleDomains, domainName) + } else { + // This is a top-level domain or its parent is not in the list + // Register as virtual-host style: bucket.domain.com/object + virtualHostDomains = append(virtualHostDomains, domainName) + } + } + return pathStyleDomains, virtualHostDomains +} + // handleCORSOriginValidation handles the common CORS origin validation logic func (s3a *S3ApiServer) handleCORSOriginValidation(w http.ResponseWriter, r *http.Request) bool { origin := r.Header.Get("Origin") @@ -196,11 +221,17 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) { var routers []*mux.Router if s3a.option.DomainName != "" { domainNames := strings.Split(s3a.option.DomainName, ",") - for _, domainName := range domainNames { - routers = append(routers, apiRouter.Host( - fmt.Sprintf("%s.%s:%d", "{bucket:.+}", domainName, s3a.option.Port)).Subrouter()) + pathStyleDomains, virtualHostDomains := classifyDomainNames(domainNames) + + // Register path-style domains + for _, domain := range pathStyleDomains { + routers = append(routers, apiRouter.Host(domain).PathPrefix("/{bucket}").Subrouter()) + } + + // Register virtual-host style domains + for _, virtualHost := range virtualHostDomains { routers = append(routers, apiRouter.Host( - fmt.Sprintf("%s.%s", "{bucket:.+}", domainName)).Subrouter()) + fmt.Sprintf("%s.%s", "{bucket:.+}", virtualHost)).Subrouter()) } } routers = append(routers, apiRouter.PathPrefix("/{bucket}").Subrouter()) |
