diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index 0032457c2..0c4aef3c2 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -625,7 +625,9 @@ type bucketForwardingHandler struct { } func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if globalDNSConfig == nil || globalDomainName == "" || guessIsBrowserReq(r) || guessIsHealthCheckReq(r) || guessIsMetricsReq(r) || guessIsRPCReq(r) { + if globalDNSConfig == nil || globalDomainName == "" || + guessIsBrowserReq(r) || guessIsHealthCheckReq(r) || + guessIsMetricsReq(r) || guessIsRPCReq(r) || isAdminReq(r) { f.handler.ServeHTTP(w, r) return } diff --git a/cmd/handler-utils.go b/cmd/handler-utils.go index 3fb915015..f6cf7dcf1 100644 --- a/cmd/handler-utils.go +++ b/cmd/handler-utils.go @@ -28,6 +28,7 @@ import ( "strings" "github.com/minio/minio/cmd/logger" + "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/handlers" httptracer "github.com/minio/minio/pkg/handlers" ) @@ -176,13 +177,13 @@ func getRedirectPostRawQuery(objInfo ObjectInfo) string { return redirectValues.Encode() } -// Returns access key in the request Authorization header. -func getReqAccessKey(r *http.Request, region string) (accessKey string) { - cred, _, _ := getReqAccessKeyV4(r, region) +// Returns access credentials in the request Authorization header. +func getReqAccessCred(r *http.Request, region string) (cred auth.Credentials) { + cred, _, _ = getReqAccessKeyV4(r, region) if cred.AccessKey == "" { cred, _, _ = getReqAccessKeyV2(r) } - return cred.AccessKey + return cred } // Extract request params to be sent with event notifiation. @@ -192,10 +193,11 @@ func extractReqParams(r *http.Request) map[string]string { } region := globalServerConfig.GetRegion() + cred := getReqAccessCred(r, region) // Success. return map[string]string{ "region": region, - "accessKey": getReqAccessKey(r, region), + "accessKey": cred.AccessKey, "sourceIPAddress": handlers.GetSourceIP(r), // Add more fields here. } diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 6f188fc85..bbf60c782 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -644,6 +644,15 @@ func getCpObjMetadataFromHeader(ctx context.Context, r *http.Request, userMeta m return defaultMeta, nil } +// Returns a minio-go Client configured to access remote host described by destDNSRecord +// Applicable only in a federated deployment +var getRemoteInstanceClient = func(r *http.Request, host string, port int) (*miniogo.Core, error) { + // In a federated deployment, all the instances share config files and hence expected to have same + // credentials, make sure to send the same credentials for which the request came in. + cred := getReqAccessCred(r, globalServerConfig.GetRegion()) + return miniogo.NewCore(net.JoinHostPort(host, strconv.Itoa(port)), cred.AccessKey, cred.SecretKey, globalIsSSL) +} + // CopyObjectHandler - Copy Object // ---------- // This implementation of the PUT operation adds an object to a bucket @@ -949,17 +958,6 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re var objInfo ObjectInfo - // Returns a minio-go Client configured to access remote host described by destDNSRecord - // Applicable only in a federated deployment - var getRemoteInstanceClient = func(host string, port int) (*miniogo.Core, error) { - // In a federated deployment, all the instances share config files and hence expected to have same - // credentials. So, access current instances creds and use it to create client for remote instance - endpoint := net.JoinHostPort(host, strconv.Itoa(port)) - accessKey := globalServerConfig.Credential.AccessKey - secretKey := globalServerConfig.Credential.SecretKey - return miniogo.NewCore(endpoint, accessKey, secretKey, globalIsSSL) - } - if isRemoteCallRequired(ctx, srcBucket, dstBucket, objectAPI) { if globalDNSConfig == nil { writeErrorResponse(w, ErrNoSuchBucket, r.URL, guessIsBrowserReq(r)) @@ -969,14 +967,15 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if dstRecords, err = globalDNSConfig.Get(dstBucket); err == nil { // Send PutObject request to appropriate instance (in federated deployment) host, port := getRandomHostPort(dstRecords) - client, rerr := getRemoteInstanceClient(host, port) + client, rerr := getRemoteInstanceClient(r, host, port) if rerr != nil { - writeErrorResponse(w, ErrInternalError, r.URL, guessIsBrowserReq(r)) + writeErrorResponse(w, toAPIErrorCode(ctx, rerr), r.URL, guessIsBrowserReq(r)) return } - remoteObjInfo, rerr := client.PutObject(dstBucket, dstObject, srcInfo.Reader, srcInfo.Size, "", "", srcInfo.UserDefined, dstOpts.ServerSideEncryption) + remoteObjInfo, rerr := client.PutObject(dstBucket, dstObject, srcInfo.Reader, + srcInfo.Size, "", "", srcInfo.UserDefined, dstOpts.ServerSideEncryption) if rerr != nil { - writeErrorResponse(w, ErrInternalError, r.URL, guessIsBrowserReq(r)) + writeErrorResponse(w, toAPIErrorCode(ctx, rerr), r.URL, guessIsBrowserReq(r)) return } objInfo.ETag = remoteObjInfo.ETag