diff options
| author | Konstantin Lebedev <9497591+kmlebedev@users.noreply.github.com> | 2025-10-24 13:45:22 +0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-24 01:45:22 -0700 |
| commit | bf58c5a6880728961456e9123ae0b196474fe7e1 (patch) | |
| tree | 0cbb0ba357614b2d03c5925f6731dcd395e89e18 /weed/s3api/s3api_server.go | |
| parent | 1d0471aebb07a7cd27e05a44845acc2206af843e (diff) | |
| download | seaweedfs-bf58c5a6880728961456e9123ae0b196474fe7e1.tar.xz seaweedfs-bf58c5a6880728961456e9123ae0b196474fe7e1.zip | |
fix: Use a mixed of virtual and path styles within a single subdomain (#7357)
* fix: Use a mixed of virtual and path styles within a single subdomain
* address comments
* add tests
---------
Co-authored-by: chrislu <chris.lu@gmail.com>
Co-authored-by: Chris Lu <chrislusf@users.noreply.github.com>
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()) |
