aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api/s3api_server.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/s3api/s3api_server.go')
-rw-r--r--weed/s3api/s3api_server.go39
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())