From f13f421e8443fc557aa1cd7b2400630688ce30ba Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 21 Aug 2019 22:02:39 -1000 Subject: [PATCH] Allow CopyObject in pathStyle across federated instances (#8064) Fixes #7976 --- cmd/generic-handlers.go | 52 +++++++++++++++++++++++------------------ cmd/object-handlers.go | 4 ++-- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index 677df01d3..5fc76a037 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -673,27 +673,30 @@ func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques bucket, _ = urlPath2BucketObjectName(r.URL.Path) } } - if bucket != "" { - sr, err := globalDNSConfig.Get(bucket) - if err != nil { - if err == dns.ErrNoEntriesFound { - writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrNoSuchBucket), r.URL, guessIsBrowserReq(r)) - } else { - writeErrorResponse(context.Background(), w, toAPIError(context.Background(), err), r.URL, guessIsBrowserReq(r)) - } - return - } - if globalDomainIPs.Intersection(set.CreateStringSet(getHostsSlice(sr)...)).IsEmpty() { - r.URL.Scheme = "http" - if globalIsSSL { - r.URL.Scheme = "https" - } - r.URL.Host = getHostFromSrv(sr) - f.fwd.ServeHTTP(w, r) - return - } + if bucket == "" { + f.handler.ServeHTTP(w, r) + return + } + sr, err := globalDNSConfig.Get(bucket) + if err != nil { + if err == dns.ErrNoEntriesFound { + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrNoSuchBucket), + r.URL, guessIsBrowserReq(r)) + } else { + writeErrorResponse(context.Background(), w, toAPIError(context.Background(), err), + r.URL, guessIsBrowserReq(r)) + } + return + } + if globalDomainIPs.Intersection(set.CreateStringSet(getHostsSlice(sr)...)).IsEmpty() { + r.URL.Scheme = "http" + if globalIsSSL { + r.URL.Scheme = "https" + } + r.URL.Host = getHostFromSrv(sr) + f.fwd.ServeHTTP(w, r) + return } - f.handler.ServeHTTP(w, r) return } @@ -715,9 +718,12 @@ func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques // CopyObject requests should be handled at current endpoint as path style // requests have target bucket and object in URI and source details are in // header fields - if r.Method == http.MethodPut && r.Header.Get("X-Amz-Copy-Source") != "" { - f.handler.ServeHTTP(w, r) - return + if r.Method == http.MethodPut && r.Header.Get(xhttp.AmzCopySource) != "" { + bucket, object = urlPath2BucketObjectName(r.Header.Get(xhttp.AmzCopySource)) + if bucket == "" || object == "" { + f.handler.ServeHTTP(w, r) + return + } } sr, err := globalDNSConfig.Get(bucket) if err != nil { diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 7bfab7d44..fc3a46040 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -1063,7 +1063,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req r.Body = &detectDisconnect{r.Body, r.Context().Done()} // X-Amz-Copy-Source shouldn't be set for this call. - if _, ok := r.Header["X-Amz-Copy-Source"]; ok { + if _, ok := r.Header[xhttp.AmzCopySource]; ok { writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) return } @@ -1086,7 +1086,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req size := r.ContentLength rAuthType := getRequestAuthType(r) if rAuthType == authTypeStreamingSigned { - if sizeStr, ok := r.Header["X-Amz-Decoded-Content-Length"]; ok { + if sizeStr, ok := r.Header[xhttp.AmzDecodedContentLength]; ok { if sizeStr[0] == "" { writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return