From a51781e5cf4a055546301ed3c49b68d7209e51d1 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 13 Feb 2019 16:07:21 -0800 Subject: [PATCH] Use context to fill in more details about error XML (#7232) --- cmd/acl-handlers.go | 16 +- cmd/admin-handlers.go | 179 +++++++------- cmd/api-errors.go | 15 +- cmd/api-response-multipart.go | 9 +- cmd/api-response.go | 25 +- cmd/auth-handler.go | 2 +- cmd/bucket-handlers-listobjects.go | 28 +-- cmd/bucket-handlers.go | 112 ++++----- cmd/bucket-notification-handlers.go | 58 ++--- cmd/bucket-policy-handlers.go | 34 +-- cmd/copy-part-range.go | 6 +- cmd/dummy-handlers.go | 24 +- cmd/generic-handlers.go | 32 +-- cmd/handler-utils.go | 4 +- cmd/object-handlers-common.go | 20 +- cmd/object-handlers.go | 348 ++++++++++++++-------------- cmd/object-handlers_test.go | 137 ++++++++--- cmd/test-utils_test.go | 53 +++-- cmd/web-handlers.go | 6 +- 19 files changed, 599 insertions(+), 509 deletions(-) diff --git a/cmd/acl-handlers.go b/cmd/acl-handlers.go index 2feb458c1..1dcee825b 100644 --- a/cmd/acl-handlers.go +++ b/cmd/acl-handlers.go @@ -64,21 +64,21 @@ func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http. objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } // Allow getBucketACL if policy action is set, since this is a dummy call // we are simply re-purposing the bucketPolicyAction. if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Before proceeding validate if bucket exists. _, err := objAPI.GetBucketInfo(ctx, bucket) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -92,7 +92,7 @@ func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http. Permission: "FULL_CONTROL", }) if err := xml.NewEncoder(w).Encode(acl); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -114,21 +114,21 @@ func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http. objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } // Allow getObjectACL if policy action is set, since this is a dummy call // we are simply re-purposing the bucketPolicyAction. if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Before proceeding validate if object exists. _, err := objAPI.GetObjectInfo(ctx, bucket, object, ObjectOptions{}) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -142,7 +142,7 @@ func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http. Permission: "FULL_CONTROL", }) if err := xml.NewEncoder(w).Encode(acl); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index b8133bf2a..1dff4980a 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -83,7 +83,7 @@ func (a adminAPIHandlers) VersionHandler(w http.ResponseWriter, r *http.Request) jsonBytes, err := json.Marshal(adminAPIVersionInfo) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -119,7 +119,7 @@ func (a adminAPIHandlers) ServiceStatusHandler(w http.ResponseWriter, r *http.Re // Marshal API response jsonBytes, err := json.Marshal(serverStatus) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -144,7 +144,7 @@ func (a adminAPIHandlers) ServiceStopNRestartHandler(w http.ResponseWriter, r *h var sa madmin.ServiceAction err := json.NewDecoder(r.Body).Decode(&sa) if err != nil { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrRequestBodyParse), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrRequestBodyParse), r.URL) return } @@ -155,7 +155,7 @@ func (a adminAPIHandlers) ServiceStopNRestartHandler(w http.ResponseWriter, r *h case madmin.ServiceActionValueStop: serviceSig = serviceStop default: - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL) logger.LogIf(ctx, errors.New("Invalid service action received")) return } @@ -242,7 +242,7 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque thisAddr, err := xnet.ParseHost(GetLocalPeer(globalEndpoints)) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -268,7 +268,7 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque // Marshal API response jsonBytes, err := json.Marshal(serverInfo) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -324,7 +324,7 @@ func (a adminAPIHandlers) PerfInfoHandler(w http.ResponseWriter, r *http.Request if perfType == "drive" { info := objectAPI.StorageInfo(ctx) if !(info.Backend.Type == BackendFS || info.Backend.Type == BackendErasure) { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } // Get drive performance details from local server's drive(s) @@ -337,7 +337,7 @@ func (a adminAPIHandlers) PerfInfoHandler(w http.ResponseWriter, r *http.Request // Marshal API response jsonBytes, err := json.Marshal(dps) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -354,7 +354,7 @@ func (a adminAPIHandlers) PerfInfoHandler(w http.ResponseWriter, r *http.Request // Marshal API response jsonBytes, err := json.Marshal(cpus) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -371,7 +371,7 @@ func (a adminAPIHandlers) PerfInfoHandler(w http.ResponseWriter, r *http.Request // Marshal API response jsonBytes, err := json.Marshal(mems) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -379,7 +379,7 @@ func (a adminAPIHandlers) PerfInfoHandler(w http.ResponseWriter, r *http.Request // distributed setup) as json. writeSuccessResponseJSON(w, jsonBytes) } else { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) } } @@ -438,21 +438,13 @@ func (a adminAPIHandlers) TopLocksHandler(w http.ResponseWriter, r *http.Request // Method only allowed in Distributed XL mode. if !globalIsDistXL { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) - return - } - - // Authenticate request - // Setting the region as empty so as the mc server info command is irrespective to the region. - adminAPIErr := checkAdminRequestAuthType(ctx, r, "") - if adminAPIErr != ErrNone { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(adminAPIErr), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } thisAddr, err := xnet.ParseHost(GetLocalPeer(globalEndpoints)) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -470,7 +462,7 @@ func (a adminAPIHandlers) TopLocksHandler(w http.ResponseWriter, r *http.Request // Marshal API response jsonBytes, err := json.Marshal(topLocks) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -503,7 +495,7 @@ func (a adminAPIHandlers) StartProfilingHandler(w http.ResponseWriter, r *http.R thisAddr, err := xnet.ParseHost(GetLocalPeer(globalEndpoints)) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -544,7 +536,7 @@ func (a adminAPIHandlers) StartProfilingHandler(w http.ResponseWriter, r *http.R // Create JSON result and send it to the client startProfilingResultInBytes, err := json.Marshal(startProfilingResult) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -581,7 +573,7 @@ func (a adminAPIHandlers) DownloadProfilingHandler(w http.ResponseWriter, r *htt } if !globalNotificationSys.DownloadProfilingData(ctx, w) { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminProfilerNotEnabled), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminProfilerNotEnabled), r.URL) return } } @@ -659,13 +651,13 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { // Check if this setup has an erasure coded backend. if !globalIsXL { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrHealNotImplemented), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrHealNotImplemented), r.URL) return } bucket, objPrefix, hs, clientToken, forceStart, forceStop, errCode := extractHealInitParams(r) if errCode != ErrNone { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(errCode), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(errCode), r.URL) return } @@ -708,15 +700,16 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { default: var errorRespJSON []byte if hr.errBody == "" { - errorRespJSON = encodeResponseJSON(getAPIErrorResponse(hr.apiErr, - r.URL.Path, w.Header().Get(responseRequestIDKey))) + errorRespJSON = encodeResponseJSON(getAPIErrorResponse(ctx, hr.apiErr, + r.URL.Path, w.Header().Get(responseRequestIDKey), + w.Header().Get(responseDeploymentIDKey))) } else { errorRespJSON = encodeResponseJSON(APIErrorResponse{ Code: hr.apiErr.Code, Message: hr.errBody, Resource: r.URL.Path, RequestID: w.Header().Get(responseRequestIDKey), - HostID: "3L137", + HostID: w.Header().Get(responseDeploymentIDKey), }) } if !started { @@ -746,7 +739,7 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { StartTime: nh.startTime, }) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } // Client token not specified but a heal sequence exists on a path, @@ -762,7 +755,7 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { respBytes, errCode := globalAllHealState.PopHealStatusJSON( healPath, clientToken) if errCode != ErrNone { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(errCode), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(errCode), r.URL) } else { writeSuccessResponseJSON(w, respBytes) } @@ -804,20 +797,20 @@ func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Reques config, err := readServerConfig(ctx, objectAPI) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } configData, err := json.MarshalIndent(config, "", "\t") if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } password := config.GetCredential().SecretKey econfigData, err := madmin.EncryptData(password, configData) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -847,14 +840,14 @@ func validateAdminReq(ctx context.Context, w http.ResponseWriter, r *http.Reques // Get current object layer instance. objectAPI := newObjectLayerFn() if objectAPI == nil || globalNotificationSys == nil || globalIAMSys == nil { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) return nil } // Validate request signature. adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(adminAPIErr), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(adminAPIErr), r.URL) return nil } @@ -880,13 +873,13 @@ func (a adminAPIHandlers) GetConfigKeysHandler(w http.ResponseWriter, r *http.Re config, err := readServerConfig(ctx, objectAPI) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } configData, err := json.Marshal(config) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -908,7 +901,7 @@ func (a adminAPIHandlers) GetConfigKeysHandler(w http.ResponseWriter, r *http.Re password := config.GetCredential().SecretKey econfigData, err := madmin.EncryptData(password, []byte(newConfigStr)) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -941,14 +934,14 @@ func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) { // Deny if WORM is enabled if globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } vars := mux.Vars(r) accessKey := vars["accessKey"] if err := globalIAMSys.DeleteUser(accessKey); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) } } @@ -963,20 +956,20 @@ func (a adminAPIHandlers) ListUsers(w http.ResponseWriter, r *http.Request) { allCredentials, err := globalIAMSys.ListUsers() if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } data, err := json.Marshal(allCredentials) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } password := globalServerConfig.GetCredential().SecretKey econfigData, err := madmin.EncryptData(password, data) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -994,7 +987,7 @@ func (a adminAPIHandlers) SetUserStatus(w http.ResponseWriter, r *http.Request) // Deny if WORM is enabled if globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } @@ -1004,12 +997,12 @@ func (a adminAPIHandlers) SetUserStatus(w http.ResponseWriter, r *http.Request) // Custom IAM policies not allowed for admin user. if accessKey == globalServerConfig.GetCredential().AccessKey { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL) return } if err := globalIAMSys.SetUserStatus(accessKey, madmin.AccountStatus(status)); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1033,7 +1026,7 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { // Deny if WORM is enabled if globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } @@ -1042,13 +1035,13 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { // Custom IAM policies not allowed for admin user. if accessKey == globalServerConfig.GetCredential().AccessKey { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAddUserInvalidArgument), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAddUserInvalidArgument), r.URL) return } if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 { // More than maxConfigSize bytes were available - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) return } @@ -1056,19 +1049,19 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { configBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) if err != nil { logger.LogIf(ctx, err) - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) return } var uinfo madmin.UserInfo if err = json.Unmarshal(configBytes, &uinfo); err != nil { logger.LogIf(ctx, err) - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) return } if err = globalIAMSys.SetUser(accessKey, uinfo); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1092,12 +1085,12 @@ func (a adminAPIHandlers) ListCannedPolicies(w http.ResponseWriter, r *http.Requ policies, err := globalIAMSys.ListCannedPolicies() if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } if err = json.NewEncoder(w).Encode(policies); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1118,12 +1111,12 @@ func (a adminAPIHandlers) RemoveCannedPolicy(w http.ResponseWriter, r *http.Requ // Deny if WORM is enabled if globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } if err := globalIAMSys.DeleteCannedPolicy(policyName); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1150,36 +1143,36 @@ func (a adminAPIHandlers) AddCannedPolicy(w http.ResponseWriter, r *http.Request // Deny if WORM is enabled if globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } // Error out if Content-Length is missing. if r.ContentLength <= 0 { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL) return } // Error out if Content-Length is beyond allowed size. if r.ContentLength > maxBucketPolicySize { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL) return } iamPolicy, err := iampolicy.ParseConfig(io.LimitReader(r.Body, r.ContentLength)) if err != nil { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMalformedPolicy), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMalformedPolicy), r.URL) return } // Version in policy must not be empty if iamPolicy.Version == "" { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMalformedPolicy), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMalformedPolicy), r.URL) return } if err = globalIAMSys.SetCannedPolicy(policyName, *iamPolicy); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1207,18 +1200,18 @@ func (a adminAPIHandlers) SetUserPolicy(w http.ResponseWriter, r *http.Request) // Deny if WORM is enabled if globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } // Custom IAM policies not allowed for admin user. if accessKey == globalServerConfig.GetCredential().AccessKey { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL) return } if err := globalIAMSys.SetUserPolicy(accessKey, policyName); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) } // Notify all other Minio peers to reload users @@ -1241,13 +1234,13 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques // Deny if WORM is enabled if globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 { // More than maxConfigSize bytes were available - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) return } @@ -1255,7 +1248,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques configBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) if err != nil { logger.LogIf(ctx, err) - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) return } @@ -1263,14 +1256,14 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques // client has not sent JSON objects with duplicate keys. if err = quick.CheckDuplicateKeys(string(configBytes)); err != nil { logger.LogIf(ctx, err) - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) return } var config serverConfig if err = json.Unmarshal(configBytes, &config); err != nil { logger.LogIf(ctx, err) - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) return } @@ -1278,23 +1271,23 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques // then credentials in the provided configuration must match. if globalIsEnvCreds { if !globalServerConfig.GetCredential().Equal(config.Credential) { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminCredentialsMismatch), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminCredentialsMismatch), r.URL) return } } if err = config.Validate(); err != nil { - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) return } if err = config.TestNotificationTargets(); err != nil { - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) return } if err = saveServerConfig(ctx, objectAPI, &config); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1329,21 +1322,21 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re // Deny if WORM is enabled if globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } // Load config configStruct, err := readServerConfig(ctx, objectAPI) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } // Convert config to json bytes configBytes, err := json.Marshal(configStruct) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1360,14 +1353,14 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re reqInfo := (&logger.ReqInfo{}).AppendTags("key", k) ctx = logger.SetReqInfo(ctx, reqInfo) logger.LogIf(ctx, dErr) - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), dErr.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), dErr.Error(), r.URL) return } elem, dErr := madmin.DecryptData(password, bytes.NewBuffer([]byte(encryptedElem))) if dErr != nil { logger.LogIf(ctx, dErr) - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), dErr.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), dErr.Error(), r.URL) return } @@ -1377,7 +1370,7 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re // Convert passed value to json filed type val, cErr := convertValueType(elem, jsonFieldType) if cErr != nil { - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), cErr.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), cErr.Error(), r.URL) return } // Set the key/value in the new json document @@ -1391,17 +1384,17 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re // Validate config var config serverConfig if err = json.Unmarshal(configBytes, &config); err != nil { - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) return } if err = config.Validate(); err != nil { - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) return } if err = config.TestNotificationTargets(); err != nil { - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) return } @@ -1409,13 +1402,13 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re // then credentials in the provided configuration must match. if globalIsEnvCreds { if !globalServerConfig.GetCredential().Equal(config.Credential) { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminCredentialsMismatch), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminCredentialsMismatch), r.URL) return } } if err = saveServerConfig(ctx, objectAPI, &config); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1439,13 +1432,13 @@ func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter, // Avoid setting new credentials when they are already passed // by the environment. Deny if WORM is enabled. if globalIsEnvCreds || globalWORMEnabled { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) return } if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 { // More than maxConfigSize bytes were available - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) return } @@ -1453,7 +1446,7 @@ func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter, configBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) if err != nil { logger.LogIf(ctx, err) - writeCustomErrorResponseJSON(w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) + writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) return } @@ -1461,13 +1454,13 @@ func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter, var req madmin.SetCredsReq if err = json.Unmarshal(configBytes, &req); err != nil { logger.LogIf(ctx, err) - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrRequestBodyParse), r.URL) + writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrRequestBodyParse), r.URL) return } creds, err := auth.CreateCredentials(req.AccessKey, req.SecretKey) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } @@ -1482,7 +1475,7 @@ func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter, globalActiveCred = creds if err = saveServerConfig(ctx, objectAPI, globalServerConfig); err != nil { - writeErrorResponseJSON(w, toAdminAPIErr(ctx, err), r.URL) + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 35e0476cc..97a11e98f 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -1715,12 +1715,15 @@ func getAPIError(code APIErrorCode) APIError { // getErrorResponse gets in standard error and resource value and // provides a encodable populated response values -func getAPIErrorResponse(err APIError, resource, requestid string) APIErrorResponse { +func getAPIErrorResponse(ctx context.Context, err APIError, resource, requestID, hostID string) APIErrorResponse { + reqInfo := logger.GetReqInfo(ctx) return APIErrorResponse{ - Code: err.Code, - Message: err.Description, - Resource: resource, - RequestID: requestid, - HostID: "3L137", + Code: err.Code, + Message: err.Description, + BucketName: reqInfo.BucketName, + Key: reqInfo.ObjectName, + Resource: resource, + RequestID: requestID, + HostID: hostID, } } diff --git a/cmd/api-response-multipart.go b/cmd/api-response-multipart.go index edb0b0cfe..36224dac2 100644 --- a/cmd/api-response-multipart.go +++ b/cmd/api-response-multipart.go @@ -43,11 +43,12 @@ type completeMultipartAPIError struct { // XML doesn't carry the additional fields required to send this // error. So we construct a new type which lies well within the scope // of this function. -func writePartSmallErrorResponse(w http.ResponseWriter, r *http.Request, err PartTooSmall) { - - apiError := toAPIError(context.Background(), err) +func writePartSmallErrorResponse(ctx context.Context, w http.ResponseWriter, r *http.Request, err PartTooSmall) { + apiError := toAPIError(ctx, err) // Generate complete multipart error response. - errorResponse := getAPIErrorResponse(apiError, r.URL.Path, w.Header().Get(responseRequestIDKey)) + errorResponse := getAPIErrorResponse(ctx, apiError, r.URL.Path, + w.Header().Get(responseRequestIDKey), + w.Header().Get(responseDeploymentIDKey)) cmpErrResp := completeMultipartAPIError{err.PartSize, int64(5242880), err.PartNumber, err.PartETag, errorResponse} encodedErrorResponse := encodeResponse(cmpErrResp) diff --git a/cmd/api-response.go b/cmd/api-response.go index b2c76fcb5..ca5e3314c 100644 --- a/cmd/api-response.go +++ b/cmd/api-response.go @@ -17,6 +17,7 @@ package cmd import ( + "context" "encoding/xml" "net/http" "net/url" @@ -24,6 +25,7 @@ import ( "strings" "time" + "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/handlers" ) @@ -568,7 +570,7 @@ func writeSuccessResponseHeadersOnly(w http.ResponseWriter) { } // writeErrorRespone writes error headers -func writeErrorResponse(w http.ResponseWriter, err APIError, reqURL *url.URL, browser bool) { +func writeErrorResponse(ctx context.Context, w http.ResponseWriter, err APIError, reqURL *url.URL, browser bool) { switch err.Code { case "SlowDown", "XMinioServerNotInitialized", "XMinioReadQuorum", "XMinioWriteQuorum": // Set retry-after header to indicate user-agents to retry request after 120secs. @@ -585,7 +587,7 @@ func writeErrorResponse(w http.ResponseWriter, err APIError, reqURL *url.URL, br } // Generate error response. - errorResponse := getAPIErrorResponse(err, reqURL.Path, w.Header().Get(responseRequestIDKey)) + errorResponse := getAPIErrorResponse(ctx, err, reqURL.Path, w.Header().Get(responseRequestIDKey), w.Header().Get(responseDeploymentIDKey)) encodedErrorResponse := encodeResponse(errorResponse) writeResponse(w, err.HTTPStatusCode, encodedErrorResponse, mimeXML) } @@ -596,9 +598,9 @@ func writeErrorResponseHeadersOnly(w http.ResponseWriter, err APIError) { // writeErrorResponseJSON - writes error response in JSON format; // useful for admin APIs. -func writeErrorResponseJSON(w http.ResponseWriter, err APIError, reqURL *url.URL) { +func writeErrorResponseJSON(ctx context.Context, w http.ResponseWriter, err APIError, reqURL *url.URL) { // Generate error response. - errorResponse := getAPIErrorResponse(err, reqURL.Path, w.Header().Get(responseRequestIDKey)) + errorResponse := getAPIErrorResponse(ctx, err, reqURL.Path, w.Header().Get(responseRequestIDKey), w.Header().Get(responseDeploymentIDKey)) encodedErrorResponse := encodeResponseJSON(errorResponse) writeResponse(w, err.HTTPStatusCode, encodedErrorResponse, mimeJSON) } @@ -606,15 +608,18 @@ func writeErrorResponseJSON(w http.ResponseWriter, err APIError, reqURL *url.URL // writeCustomErrorResponseJSON - similar to writeErrorResponseJSON, // but accepts the error message directly (this allows messages to be // dynamically generated.) -func writeCustomErrorResponseJSON(w http.ResponseWriter, err APIError, +func writeCustomErrorResponseJSON(ctx context.Context, w http.ResponseWriter, err APIError, errBody string, reqURL *url.URL) { + reqInfo := logger.GetReqInfo(ctx) errorResponse := APIErrorResponse{ - Code: err.Code, - Message: errBody, - Resource: reqURL.Path, - RequestID: w.Header().Get(responseRequestIDKey), - HostID: "3L137", + Code: err.Code, + Message: errBody, + Resource: reqURL.Path, + BucketName: reqInfo.BucketName, + Key: reqInfo.ObjectName, + RequestID: w.Header().Get(responseRequestIDKey), + HostID: w.Header().Get(responseDeploymentIDKey), } encodedErrorResponse := encodeResponseJSON(errorResponse) writeResponse(w, err.HTTPStatusCode, encodedErrorResponse, mimeJSON) diff --git a/cmd/auth-handler.go b/cmd/auth-handler.go index f7ffe7875..b50fd47f1 100644 --- a/cmd/auth-handler.go +++ b/cmd/auth-handler.go @@ -416,7 +416,7 @@ func (a authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { a.handler.ServeHTTP(w, r) return } - writeErrorResponse(w, errorCodes.ToAPIErr(ErrSignatureVersionNotSupported), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrSignatureVersionNotSupported), r.URL, guessIsBrowserReq(r)) } // isPutAllowed - check if PUT operation is allowed on the resource, this diff --git a/cmd/bucket-handlers-listobjects.go b/cmd/bucket-handlers-listobjects.go index afdf48cbf..f94c49846 100644 --- a/cmd/bucket-handlers-listobjects.go +++ b/cmd/bucket-handlers-listobjects.go @@ -66,12 +66,12 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -80,14 +80,14 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http // Extract all the listObjectsV2 query params to their native values. prefix, token, startAfter, delimiter, fetchOwner, maxKeys, _, errCode := getListObjectsV2Args(urlValues) if errCode != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) return } // Validate the query params before beginning to serve the request. // fetch-owner is not validated since it is a boolean if s3Error := validateListObjectsArgs(prefix, token, delimiter, maxKeys); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -100,7 +100,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http // marshaled into S3 compatible XML header. listObjectsV2Info, err := listObjectsV2(ctx, bucket, prefix, token, delimiter, maxKeys, fetchOwner, startAfter) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -110,7 +110,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http // Read the decompressed size from the meta.json. actualSize = listObjectsV2Info.Objects[i].GetActualSize() if actualSize < 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidDecompressedSize), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidDecompressedSize), r.URL, guessIsBrowserReq(r)) return } // Set the info.Size to the actualSize. @@ -119,7 +119,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http listObjectsV2Info.Objects[i].ETag = getDecryptedETag(r.Header, listObjectsV2Info.Objects[i], false) listObjectsV2Info.Objects[i].Size, err = listObjectsV2Info.Objects[i].DecryptedSize() if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -148,25 +148,25 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Extract all the litsObjectsV1 query params to their native values. prefix, marker, delimiter, maxKeys, _, s3Error := getListObjectsV1Args(r.URL.Query()) if s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Validate all the query params before beginning to serve the request. if s3Error := validateListObjectsArgs(prefix, marker, delimiter, maxKeys); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -180,7 +180,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http // marshaled into S3 compatible XML header. listObjectsInfo, err := listObjects(ctx, bucket, prefix, marker, delimiter, maxKeys) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -190,7 +190,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http // Read the decompressed size from the meta.json. actualSize = listObjectsInfo.Objects[i].GetActualSize() if actualSize < 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidDecompressedSize), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidDecompressedSize), r.URL, guessIsBrowserReq(r)) return } // Set the info.Size to the actualSize. @@ -199,7 +199,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http listObjectsInfo.Objects[i].ETag = getDecryptedETag(r.Header, listObjectsInfo.Objects[i], false) listObjectsInfo.Objects[i].Size, err = listObjectsInfo.Objects[i].DecryptedSize() if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 39af10edf..a5ddeff4b 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -96,12 +96,12 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r * objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketLocationAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -110,7 +110,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r * getBucketInfo = api.CacheAPI().GetBucketInfo } if _, err := getBucketInfo(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -146,37 +146,37 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketMultipartUploadsAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } prefix, keyMarker, uploadIDMarker, delimiter, maxUploads, _, errCode := getBucketMultipartResources(r.URL.Query()) if errCode != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) return } if maxUploads < 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidMaxUploads), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidMaxUploads), r.URL, guessIsBrowserReq(r)) return } if keyMarker != "" { // Marker not common with prefix is not implemented. if !hasPrefix(keyMarker, prefix) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } } listMultipartsInfo, err := objectAPI.ListMultipartUploads(ctx, bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploads) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // generate response @@ -198,7 +198,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } @@ -208,7 +208,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R } if s3Error := checkRequestAuthType(ctx, r, policy.ListAllMyBucketsAction, "", ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -217,7 +217,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R if globalDNSConfig != nil { dnsBuckets, err := globalDNSConfig.List() if err != nil && err != dns.ErrNoEntriesFound { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } bucketSet := set.NewStringSet() @@ -236,7 +236,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R var err error bucketsInfo, err = listBuckets(ctx) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -260,7 +260,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } @@ -269,7 +269,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, // In the event access is denied, a 200 response should still be returned // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html if s3Error != ErrAccessDenied { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } } @@ -277,14 +277,14 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, // Content-Length is required and should be non-zero // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html if r.ContentLength <= 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return } // Content-Md5 is requied should be set // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html if _, ok := r.Header["Content-Md5"]; !ok { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentMD5), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentMD5), r.URL, guessIsBrowserReq(r)) return } @@ -300,7 +300,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, // Read incoming body XML bytes. if _, err := io.ReadFull(r.Body, deleteXMLBytes); err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, toAdminAPIErr(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAdminAPIErr(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -308,7 +308,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, deleteObjects := &DeleteObjectsRequest{} if err := xml.Unmarshal(deleteXMLBytes, deleteObjects); err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL, guessIsBrowserReq(r)) return } @@ -316,7 +316,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, if globalWORMEnabled { // Not required to check whether given objects exist or not, because // DeleteMultipleObject is always successful irrespective of object existence. - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } @@ -405,7 +405,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } @@ -413,21 +413,21 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req bucket := vars["bucket"] if s3Error := checkRequestAuthType(ctx, r, policy.CreateBucketAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Parse incoming location constraint. location, s3Error := parseLocationConstraint(r) if s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Validate if location sent by the client is valid, reject // requests which do not follow valid region requirements. if !isValidLocation(location) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidRegion), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidRegion), r.URL, guessIsBrowserReq(r)) return } @@ -436,12 +436,12 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req if err == dns.ErrNoEntriesFound { // Proceed to creating a bucket. if err = objectAPI.MakeBucketWithLocation(ctx, bucket, location); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } if err = globalDNSConfig.Put(bucket); err != nil { objectAPI.DeleteBucket(ctx, bucket) - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -451,18 +451,18 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req writeSuccessResponseHeadersOnly(w) return } - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } - writeErrorResponse(w, errorCodes.ToAPIErr(ErrBucketAlreadyOwnedByYou), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrBucketAlreadyOwnedByYou), r.URL, guessIsBrowserReq(r)) return } // Proceed to creating a bucket. err := objectAPI.MakeBucketWithLocation(ctx, bucket, location) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -483,17 +483,17 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if crypto.S3KMS.IsRequested(r.Header) { // SSE-KMS is not supported - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } if !api.EncryptionEnabled() && hasServerSideEncryptionHeader(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } @@ -502,17 +502,17 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h // Require Content-Length to be set in the request size := r.ContentLength if size < 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return } resource, err := getResource(r.URL.Path, r.Host, globalDomainName) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL, guessIsBrowserReq(r)) return } // Make sure that the URL does not contain object name. if bucket != filepath.Clean(resource[1:]) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } @@ -521,7 +521,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h reader, err := r.MultipartReader() if err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) return } @@ -529,7 +529,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h form, err := reader.ReadForm(maxFormMemory) if err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) return } @@ -540,13 +540,13 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h fileBody, fileName, fileSize, formValues, err := extractPostPolicyFormValues(ctx, form) if err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) return } // Check if file is provided, error out otherwise. if fileBody == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrPOSTFileRequired), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrPOSTFileRequired), r.URL, guessIsBrowserReq(r)) return } @@ -568,7 +568,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h if successRedirect != "" { redirectURL, err = url.Parse(successRedirect) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) return } } @@ -576,13 +576,13 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h // Verify policy signature. errCode := doesPolicySignatureMatch(formValues) if errCode != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) return } policyBytes, err := base64.StdEncoding.DecodeString(formValues.Get("Policy")) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) return } @@ -590,13 +590,13 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h if len(policyBytes) > 0 { postPolicyForm, err := parsePostPolicyForm(string(policyBytes)) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedPOSTRequest), r.URL, guessIsBrowserReq(r)) return } // Make sure formValues adhere to policy restrictions. if errCode = checkPostPolicy(formValues, postPolicyForm); errCode != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) return } @@ -605,12 +605,12 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h lengthRange := postPolicyForm.Conditions.ContentLengthRange if lengthRange.Valid { if fileSize < lengthRange.Min { - writeErrorResponse(w, toAPIError(ctx, errDataTooSmall), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, errDataTooSmall), r.URL, guessIsBrowserReq(r)) return } if fileSize > lengthRange.Max || isMaxObjectSize(fileSize) { - writeErrorResponse(w, toAPIError(ctx, errDataTooLarge), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, errDataTooLarge), r.URL, guessIsBrowserReq(r)) return } } @@ -620,14 +620,14 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h metadata := make(map[string]string) err = extractMetadataFromMap(ctx, formValues, metadata) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } hashReader, err := hash.NewReader(fileBody, fileSize, "", "", fileSize) if err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } rawReader := hashReader @@ -652,19 +652,19 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h if crypto.SSEC.IsRequested(formValues) { key, err = ParseSSECustomerHeader(formValues) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } reader, objectEncryptionKey, err = newEncryptReader(hashReader, key, bucket, object, metadata, crypto.S3.IsRequested(formValues)) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } info := ObjectInfo{Size: fileSize} hashReader, err = hash.NewReader(reader, info.EncryptedSize(), "", "", fileSize) // do not try to verify encrypted content if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } pReader = NewPutObjReader(rawReader, hashReader, objectEncryptionKey) @@ -673,7 +673,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h objInfo, err := objectAPI.PutObject(ctx, bucket, object, pReader, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -771,12 +771,12 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http. objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.DeleteBucketAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -786,7 +786,7 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http. } // Attempt to delete bucket. if err := deleteBucket(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -798,7 +798,7 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http. if err := globalDNSConfig.Delete(bucket); err != nil { // Deleting DNS entry failed, attempt to create the bucket again. objectAPI.MakeBucketWithLocation(ctx, bucket, "") - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } diff --git a/cmd/bucket-notification-handlers.go b/cmd/bucket-notification-handlers.go index 401b6ee37..120260520 100644 --- a/cmd/bucket-notification-handlers.go +++ b/cmd/bucket-notification-handlers.go @@ -51,23 +51,23 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if !objAPI.IsNotificationSupported() { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketNotificationAction, bucketName, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } _, err := objAPI.GetBucketInfo(ctx, bucketName) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -76,7 +76,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, if err != nil { // Ignore errNoSuchNotifications to comply with AWS S3. if err != errNoSuchNotifications { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -90,7 +90,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, notificationBytes, err := xml.Marshal(nConfig) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -106,12 +106,12 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if !objectAPI.IsNotificationSupported() { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } @@ -119,19 +119,19 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, bucketName := vars["bucket"] if s3Error := checkRequestAuthType(ctx, r, policy.PutBucketNotificationAction, bucketName, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } _, err := objectAPI.GetBucketInfo(ctx, bucketName) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // PutBucketNotification always needs a Content-Length. if r.ContentLength <= 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return } @@ -143,12 +143,12 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, apiErr = toAPIError(ctx, err) } - writeErrorResponse(w, apiErr, r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, apiErr, r.URL, guessIsBrowserReq(r)) return } if err = saveNotificationConfig(ctx, objectAPI, bucketName, config); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -169,24 +169,24 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit // Validate if bucket exists. objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if !objAPI.IsNotificationSupported() { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } if !objAPI.IsListenBucketSupported() { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } vars := mux.Vars(r) bucketName := vars["bucket"] if s3Error := checkRequestAuthType(ctx, r, policy.ListenBucketNotificationAction, bucketName, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -194,13 +194,13 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit var prefix string if len(values["prefix"]) > 1 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrFilterNamePrefix), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrFilterNamePrefix), r.URL, guessIsBrowserReq(r)) return } if len(values["prefix"]) == 1 { if err := event.ValidateFilterRuleValue(values["prefix"][0]); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -209,13 +209,13 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit var suffix string if len(values["suffix"]) > 1 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrFilterNameSuffix), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrFilterNameSuffix), r.URL, guessIsBrowserReq(r)) return } if len(values["suffix"]) == 1 { if err := event.ValidateFilterRuleValue(values["suffix"][0]); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -228,7 +228,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit for _, s := range values["events"] { eventName, err := event.ParseName(s) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -236,19 +236,19 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit } if _, err := objAPI.GetBucketInfo(ctx, bucketName); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } host, err := xnet.ParseHost(r.RemoteAddr) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } target, err := target.NewHTTPClientTarget(*host, w) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -256,7 +256,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit if err = globalNotificationSys.AddRemoteTarget(bucketName, target, rulesMap); err != nil { logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name) - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } defer globalNotificationSys.RemoveRemoteTarget(bucketName, target.ID()) @@ -264,13 +264,13 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit thisAddr, err := xnet.ParseHost(GetLocalPeer(globalEndpoints)) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } if err = SaveListener(objAPI, bucketName, eventNames, pattern, target.ID(), *thisAddr); err != nil { logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name) - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -280,7 +280,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit if err = RemoveListener(objAPI, bucketName, target.ID(), *thisAddr); err != nil { logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name) - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } diff --git a/cmd/bucket-policy-handlers.go b/cmd/bucket-policy-handlers.go index ac8c59eba..982a41a46 100644 --- a/cmd/bucket-policy-handlers.go +++ b/cmd/bucket-policy-handlers.go @@ -44,7 +44,7 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } @@ -52,43 +52,43 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht bucket := vars["bucket"] if s3Error := checkRequestAuthType(ctx, r, policy.PutBucketPolicyAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Check if bucket exists. if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // Error out if Content-Length is missing. // PutBucketPolicy always needs Content-Length. if r.ContentLength <= 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return } // Error out if Content-Length is beyond allowed size. if r.ContentLength > maxBucketPolicySize { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) return } bucketPolicy, err := policy.ParseConfig(io.LimitReader(r.Body, r.ContentLength), bucket) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedPolicy), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedPolicy), r.URL, guessIsBrowserReq(r)) return } // Version in policy must not be empty if bucketPolicy.Version == "" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedPolicy), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedPolicy), r.URL, guessIsBrowserReq(r)) return } if err = objAPI.SetBucketPolicy(ctx, bucket, bucketPolicy); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -107,7 +107,7 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } @@ -115,18 +115,18 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r bucket := vars["bucket"] if s3Error := checkRequestAuthType(ctx, r, policy.DeleteBucketPolicyAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Check if bucket exists. if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } if err := objAPI.DeleteBucketPolicy(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -145,7 +145,7 @@ func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *ht objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } @@ -153,26 +153,26 @@ func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *ht bucket := vars["bucket"] if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Check if bucket exists. if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // Read bucket access policy. bucketPolicy, err := objAPI.GetBucketPolicy(ctx, bucket) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } policyData, err := json.Marshal(bucketPolicy) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } diff --git a/cmd/copy-part-range.go b/cmd/copy-part-range.go index db1ae3260..2e644ba50 100644 --- a/cmd/copy-part-range.go +++ b/cmd/copy-part-range.go @@ -26,13 +26,13 @@ import ( func writeCopyPartErr(ctx context.Context, w http.ResponseWriter, err error, url *url.URL, browser bool) { switch err { case errInvalidRange: - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidCopyPartRange), url, browser) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopyPartRange), url, browser) return case errInvalidRangeSource: - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidCopyPartRangeSource), url, browser) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopyPartRangeSource), url, browser) return default: - writeErrorResponse(w, toAPIError(ctx, err), url, browser) + writeErrorResponse(ctx, w, toAPIError(ctx, err), url, browser) return } } diff --git a/cmd/dummy-handlers.go b/cmd/dummy-handlers.go index bdac2a590..7fc88f8d2 100644 --- a/cmd/dummy-handlers.go +++ b/cmd/dummy-handlers.go @@ -129,27 +129,27 @@ func (api objectAPIHandlers) GetBucketCorsHandler(w http.ResponseWriter, r *http objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } // Allow getBucketCors if policy action is set, since this is a dummy call // we are simply re-purposing the bucketPolicyAction. if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Validate if bucket exists, before proceeding further... _, err := objAPI.GetBucketInfo(ctx, bucket) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } cors := &corsConfiguration{} if err := xml.NewEncoder(w).Encode(cors); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -165,21 +165,21 @@ func (api objectAPIHandlers) GetBucketTaggingHandler(w http.ResponseWriter, r *h objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } // Allow getBucketTagging if policy action is set, since this is a dummy call // we are simply re-purposing the bucketPolicyAction. if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Validate if bucket exists, before proceeding further... _, err := objAPI.GetBucketInfo(ctx, bucket) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -187,7 +187,7 @@ func (api objectAPIHandlers) GetBucketTaggingHandler(w http.ResponseWriter, r *h tags.TagSet.Tag = append(tags.TagSet.Tag, tagElem{}) if err := xml.NewEncoder(w).Encode(tags); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -204,21 +204,21 @@ func (api objectAPIHandlers) GetObjectTaggingHandler(w http.ResponseWriter, r *h objAPI := api.ObjectAPI() if objAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } // Allow getObjectTagging if policy action is set, since this is a dummy call // we are simply re-purposing the bucketPolicyAction. if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Validate if object exists, before proceeding further... _, err := objAPI.GetObjectInfo(ctx, bucket, object, ObjectOptions{}) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -226,7 +226,7 @@ func (api objectAPIHandlers) GetObjectTaggingHandler(w http.ResponseWriter, r *h tags.TagSet.Tag = append(tags.TagSet.Tag, tagElem{}) if err := xml.NewEncoder(w).Encode(tags); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index ecfe36a5c..d1e0cdf70 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -90,7 +90,7 @@ func setRequestHeaderSizeLimitHandler(h http.Handler) http.Handler { // of the user-defined metadata to 2 KB. func (h requestHeaderSizeLimitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if isHTTPHeaderSizeTooLarge(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMetadataTooLarge), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrMetadataTooLarge), r.URL, guessIsBrowserReq(r)) return } h.Handler.ServeHTTP(w, r) @@ -133,7 +133,7 @@ func filterReservedMetadata(h http.Handler) http.Handler { // would be treated as metadata. func (h reservedMetadataHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if containsReservedMetadata(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrUnsupportedMetadata), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrUnsupportedMetadata), r.URL, guessIsBrowserReq(r)) return } h.Handler.ServeHTTP(w, r) @@ -300,7 +300,7 @@ func (h minioReservedBucketHandler) ServeHTTP(w http.ResponseWriter, r *http.Req // buckets bucketName, _ := urlPath2BucketObjectName(r.URL.Path) if isMinioReservedBucket(bucketName) || isMinioMetaBucket(bucketName) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrAllAccessDisabled), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrAllAccessDisabled), r.URL, guessIsBrowserReq(r)) return } } @@ -363,14 +363,14 @@ func (h timeValidityHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // All our internal APIs are sensitive towards Date // header, for all requests where Date header is not // present we will reject such clients. - writeErrorResponse(w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(errCode), r.URL, guessIsBrowserReq(r)) return } // Verify if the request date header is shifted by less than globalMaxSkewTime parameter in the past // or in the future, reject request otherwise. curTime := UTCNow() if curTime.Sub(amzDate) > globalMaxSkewTime || amzDate.Sub(curTime) > globalMaxSkewTime { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrRequestTimeTooSkewed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrRequestTimeTooSkewed), r.URL, guessIsBrowserReq(r)) return } } @@ -473,14 +473,14 @@ func (h resourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // If bucketName is present and not objectName check for bucket level resource queries. if bucketName != "" && objectName == "" { if ignoreNotImplementedBucketResources(r) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } } // If bucketName and objectName are present check for its resource queries. if bucketName != "" && objectName != "" { if ignoreNotImplementedObjectResources(r) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } } @@ -584,14 +584,14 @@ func hasBadPathComponent(path string) bool { func (h pathValidityHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Check for bad components in URL path. if hasBadPathComponent(r.URL.Path) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL, guessIsBrowserReq(r)) return } // Check for bad components in URL query values. for _, vv := range r.URL.Query() { for _, v := range vv { if hasBadPathComponent(v) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL, guessIsBrowserReq(r)) return } } @@ -635,9 +635,9 @@ func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques sr, err := globalDNSConfig.Get(bucket) if err != nil { if err == dns.ErrNoEntriesFound { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNoSuchBucket), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrNoSuchBucket), r.URL, guessIsBrowserReq(r)) } else { - writeErrorResponse(w, toAPIError(context.Background(), err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, toAPIError(context.Background(), err), r.URL, guessIsBrowserReq(r)) } return } @@ -679,9 +679,9 @@ func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques sr, err := globalDNSConfig.Get(bucket) if err != nil { if err == dns.ErrNoEntriesFound { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNoSuchBucket), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrNoSuchBucket), r.URL, guessIsBrowserReq(r)) } else { - writeErrorResponse(w, toAPIError(context.Background(), err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, toAPIError(context.Background(), err), r.URL, guessIsBrowserReq(r)) } return } @@ -741,7 +741,7 @@ func (l rateLimit) ServeHTTP(w http.ResponseWriter, r *http.Request) { // potential pileup on the server. if err := l.Wait(ctx); err != nil { // Send an S3 compatible error, SlowDown. - writeErrorResponse(w, errorCodes.ToAPIErr(ErrSlowDown), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrSlowDown), r.URL, guessIsBrowserReq(r)) return } @@ -795,7 +795,7 @@ type criticalErrorHandler struct{ handler http.Handler } func (h criticalErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err == logger.ErrCritical { // handle - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInternalError), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrInternalError), r.URL, guessIsBrowserReq(r)) } else if err != nil { panic(err) // forward other panic calls } @@ -814,7 +814,7 @@ func (h sseTLSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodHead { writeErrorResponseHeadersOnly(w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest)) } else { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest), r.URL, guessIsBrowserReq(r)) } return } diff --git a/cmd/handler-utils.go b/cmd/handler-utils.go index 02d7b76a9..1fc5220a4 100644 --- a/cmd/handler-utils.go +++ b/cmd/handler-utils.go @@ -366,10 +366,10 @@ func getResource(path string, host string, domain string) (string, error) { // If none of the http routes match respond with MethodNotAllowed, in JSON func notFoundHandlerJSON(w http.ResponseWriter, r *http.Request) { - writeErrorResponseJSON(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) + writeErrorResponseJSON(context.Background(), w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) } // If none of the http routes match respond with MethodNotAllowed func notFoundHandler(w http.ResponseWriter, r *http.Request) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(context.Background(), w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) } diff --git a/cmd/object-handlers-common.go b/cmd/object-handlers-common.go index a122fcbbe..9e06f4edb 100644 --- a/cmd/object-handlers-common.go +++ b/cmd/object-handlers-common.go @@ -33,8 +33,8 @@ import ( // x-amz-copy-source-if-unmodified-since // x-amz-copy-source-if-match // x-amz-copy-source-if-none-match -func checkCopyObjectPartPreconditions(w http.ResponseWriter, r *http.Request, objInfo ObjectInfo) bool { - return checkCopyObjectPreconditions(w, r, objInfo) +func checkCopyObjectPartPreconditions(ctx context.Context, w http.ResponseWriter, r *http.Request, objInfo ObjectInfo) bool { + return checkCopyObjectPreconditions(ctx, w, r, objInfo) } // Validates the preconditions for CopyObject, returns true if CopyObject operation should not proceed. @@ -43,7 +43,7 @@ func checkCopyObjectPartPreconditions(w http.ResponseWriter, r *http.Request, ob // x-amz-copy-source-if-unmodified-since // x-amz-copy-source-if-match // x-amz-copy-source-if-none-match -func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInfo ObjectInfo) bool { +func checkCopyObjectPreconditions(ctx context.Context, w http.ResponseWriter, r *http.Request, objInfo ObjectInfo) bool { // Return false for methods other than GET and HEAD. if r.Method != "PUT" { return false @@ -75,7 +75,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf if !ifModifiedSince(objInfo.ModTime, givenTime) { // If the object is not modified since the specified time. writeHeaders() - writeErrorResponse(w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) return true } } @@ -89,7 +89,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf if ifModifiedSince(objInfo.ModTime, givenTime) { // If the object is modified since the specified time. writeHeaders() - writeErrorResponse(w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) return true } } @@ -102,7 +102,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf if objInfo.ETag != "" && !isETagEqual(objInfo.ETag, ifMatchETagHeader) { // If the object ETag does not match with the specified ETag. writeHeaders() - writeErrorResponse(w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) return true } } @@ -114,7 +114,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf if objInfo.ETag != "" && isETagEqual(objInfo.ETag, ifNoneMatchETagHeader) { // If the object ETag matches with the specified ETag. writeHeaders() - writeErrorResponse(w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) return true } } @@ -128,7 +128,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf // If-Unmodified-Since // If-Match // If-None-Match -func checkPreconditions(w http.ResponseWriter, r *http.Request, objInfo ObjectInfo) bool { +func checkPreconditions(ctx context.Context, w http.ResponseWriter, r *http.Request, objInfo ObjectInfo) bool { // Return false for methods other than GET and HEAD. if r.Method != "GET" && r.Method != "HEAD" { return false @@ -174,7 +174,7 @@ func checkPreconditions(w http.ResponseWriter, r *http.Request, objInfo ObjectIn if ifModifiedSince(objInfo.ModTime, givenTime) { // If the object is modified since the specified time. writeHeaders() - writeErrorResponse(w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) return true } } @@ -187,7 +187,7 @@ func checkPreconditions(w http.ResponseWriter, r *http.Request, objInfo ObjectIn if !isETagEqual(objInfo.ETag, ifMatchETagHeader) { // If the object ETag does not match with the specified ETag. writeHeaders() - writeErrorResponse(w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrPreconditionFailed), r.URL, guessIsBrowserReq(r)) return true } } diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index c0d7514c2..1236383d8 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -86,15 +86,15 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r // Fetch object stat info. objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if crypto.S3KMS.IsRequested(r.Header) { // SSE-KMS is not supported - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } if !api.EncryptionEnabled() && hasServerSideEncryptionHeader(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrBadRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrBadRequest), r.URL, guessIsBrowserReq(r)) return } vars := mux.Vars(r) @@ -142,19 +142,19 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r } } } - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Get request range. rangeHeader := r.Header.Get("Range") if rangeHeader != "" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrUnsupportedRangeHeader), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrUnsupportedRangeHeader), r.URL, guessIsBrowserReq(r)) return } if r.ContentLength <= 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrEmptyRequestBody), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrEmptyRequestBody), r.URL, guessIsBrowserReq(r)) return } @@ -172,7 +172,7 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r }) writeResponse(w, serr.HTTPStatusCode(), encodedErrorResponse, mimeXML) } else { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) } return } @@ -197,7 +197,7 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r objInfo, err := getObjectInfo(ctx, bucket, object, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -214,7 +214,7 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r }) writeResponse(w, serr.HTTPStatusCode(), encodedErrorResponse, mimeXML) } else { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) } return } @@ -252,15 +252,15 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if crypto.S3.IsRequested(r.Header) || crypto.S3KMS.IsRequested(r.Header) { // If SSE-S3 or SSE-KMS present -> AWS fails with undefined error - writeErrorResponse(w, errorCodes.ToAPIErr(ErrBadRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrBadRequest), r.URL, guessIsBrowserReq(r)) return } if !api.EncryptionEnabled() && hasServerSideEncryptionHeader(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrBadRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrBadRequest), r.URL, guessIsBrowserReq(r)) return } vars := mux.Vars(r) @@ -268,7 +268,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req object := vars["object"] if vid := r.URL.Query().Get("versionId"); vid != "" && vid != "null" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) return } @@ -313,7 +313,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req } } } - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -331,7 +331,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req // parse error and treat it as regular Get // request like Amazon S3. if err == errInvalidRange { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidRange), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidRange), r.URL, guessIsBrowserReq(r)) return } @@ -341,7 +341,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req gr, err := getObjectNInfo(ctx, bucket, object, rs, r.Header, readLock, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } defer gr.Close() @@ -351,13 +351,13 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req if objectAPI.IsEncryptionSupported() { objInfo.UserDefined = CleanMinioInternalMetadataKeys(objInfo.UserDefined) if _, err = DecryptObjectInfo(&objInfo, r.Header); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } // Validate pre-conditions if any. - if checkPreconditions(w, r, objInfo) { + if checkPreconditions(ctx, w, r, objInfo) { return } @@ -375,7 +375,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req } if err = setObjectHeaders(w, objInfo, rs); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -391,14 +391,14 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req // Write object content to response body if _, err = io.Copy(httpWriter, gr); err != nil { if !httpWriter.HasWritten() && !statusCodeWritten { // write error response only if no data or headers has been written to client yet - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) } return } if err = httpWriter.Close(); err != nil { if !httpWriter.HasWritten() && !statusCodeWritten { // write error response only if no data or headers has been written to client yet - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -440,7 +440,7 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re return } if !api.EncryptionEnabled() && hasServerSideEncryptionHeader(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrBadRequest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrBadRequest), r.URL, guessIsBrowserReq(r)) return } vars := mux.Vars(r) @@ -543,7 +543,7 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re } // Validate pre-conditions if any. - if checkPreconditions(w, r, objInfo) { + if checkPreconditions(ctx, w, r, objInfo) { return } @@ -649,15 +649,15 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if crypto.S3KMS.IsRequested(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported return } if !api.EncryptionEnabled() && (hasServerSideEncryptionHeader(r.Header) || crypto.SSECopy.IsRequested(r.Header)) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } vars := mux.Vars(r) @@ -665,7 +665,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re dstObject := vars["object"] if s3Error := checkRequestAuthType(ctx, r, policy.PutObjectAction, dstBucket, dstObject); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -684,7 +684,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re // its non "null" value, we should error out since we do not support // any versions other than "null". if vid := u.Query().Get("versionId"); vid != "" && vid != "null" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) return } // Note that url.Parse does the unescaping @@ -695,7 +695,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re // its non "null" value, we should error out since we do not support // any versions other than "null". if vid != "null" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) return } } @@ -703,18 +703,18 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re srcBucket, srcObject := path2BucketAndObject(cpSrcPath) // If source object is empty or bucket is empty, reply back invalid copy source. if srcObject == "" || srcBucket == "" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.GetObjectAction, srcBucket, srcObject); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Check if metadata directive is valid. if !isMetadataDirectiveValid(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidMetadataDirective), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidMetadataDirective), r.URL, guessIsBrowserReq(r)) return } // This request header needs to be set prior to setting ObjectOptions @@ -726,7 +726,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re srcOpts, err := copySrcOpts(ctx, r, srcBucket, srcObject) if err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // convert copy src encryption options for GET calls @@ -738,14 +738,14 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re dstOpts, err = copyDstOpts(ctx, r, dstBucket, dstObject, nil) if err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // Deny if WORM is enabled if globalWORMEnabled { if _, err = objectAPI.GetObjectInfo(ctx, dstBucket, dstObject, dstOpts); err == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } } @@ -765,20 +765,20 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re var rs *HTTPRangeSpec gr, err := getObjectNInfo(ctx, srcBucket, srcObject, rs, r.Header, lock, getOpts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } defer gr.Close() srcInfo := gr.ObjInfo // Verify before x-amz-copy-source preconditions before continuing with CopyObject. - if checkCopyObjectPreconditions(w, r, srcInfo) { + if checkCopyObjectPreconditions(ctx, w, r, srcInfo) { return } /// maximum Upload size for object in a single CopyObject operation. if isMaxObjectSize(srcInfo.Size) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) return } @@ -796,7 +796,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if crypto.IsEncrypted(srcInfo.UserDefined) { actualSize, err = srcInfo.DecryptedSize() if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } length = actualSize @@ -855,7 +855,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re srcInfo.Reader, err = hash.NewReader(reader, length, "", "", actualSize) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -866,12 +866,12 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if objectAPI.IsEncryptionSupported() && !isCompressed { // Encryption parameters not applicable for this object. if !crypto.IsEncrypted(srcInfo.UserDefined) && crypto.SSECopy.IsRequested(r.Header) { - writeErrorResponse(w, toAPIError(ctx, errInvalidEncryptionParameters), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, errInvalidEncryptionParameters), r.URL, guessIsBrowserReq(r)) return } // Encryption parameters not present for this object. if crypto.SSEC.IsEncrypted(srcInfo.UserDefined) && !crypto.SSECopy.IsRequested(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidSSECustomerAlgorithm), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidSSECustomerAlgorithm), r.URL, guessIsBrowserReq(r)) return } @@ -887,7 +887,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if sseC { newKey, err = ParseSSECustomerRequest(r) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -901,7 +901,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if sseCopyC && sseC { oldKey, err = ParseSSECopyCustomerRequest(r.Header, srcInfo.UserDefined) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -914,7 +914,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re // In case of SSE-S3 oldKey and newKey aren't used - the KMS manages the keys. if err = rotateKey(oldKey, newKey, srcBucket, srcObject, encMetadata); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -949,7 +949,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if isTargetEncrypted { reader, objEncKey, err = newEncryptReader(srcInfo.Reader, newKey, dstBucket, dstObject, encMetadata, sseS3) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -962,7 +962,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re srcInfo.Reader, err = hash.NewReader(reader, targetSize, "", "", targetSize) // do not try to verify encrypted content if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -974,7 +974,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re srcInfo.UserDefined, err = getCpObjMetadataFromHeader(ctx, r, srcInfo.UserDefined) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -999,7 +999,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if !isMetadataReplace(r.Header) && srcInfo.metadataOnly && !crypto.IsEncrypted(srcInfo.UserDefined) { // If x-amz-metadata-directive is not set to REPLACE then we need // to error out if source and destination are same. - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidCopyDest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopyDest), r.URL, guessIsBrowserReq(r)) return } @@ -1009,20 +1009,20 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re var dstRecords []dns.SrvRecord dstRecords, err = globalDNSConfig.Get(dstBucket) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // Send PutObject request to appropriate instance (in federated deployment) client, rerr := getRemoteInstanceClient(r, getHostFromSrv(dstRecords)) if rerr != nil { - writeErrorResponse(w, toAPIError(ctx, rerr), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, rerr), r.URL, guessIsBrowserReq(r)) return } remoteObjInfo, rerr := client.PutObject(dstBucket, dstObject, srcInfo.Reader, srcInfo.Size, "", "", srcInfo.UserDefined, dstOpts.ServerSideEncryption) if rerr != nil { - writeErrorResponse(w, toAPIError(ctx, rerr), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, rerr), r.URL, guessIsBrowserReq(r)) return } objInfo.ETag = remoteObjInfo.ETag @@ -1032,7 +1032,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re // object is same then only metadata is updated. objInfo, err = objectAPI.CopyObject(ctx, srcBucket, srcObject, dstBucket, dstObject, srcInfo, srcOpts, dstOpts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -1081,15 +1081,15 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if crypto.S3KMS.IsRequested(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported return } if !api.EncryptionEnabled() && hasServerSideEncryptionHeader(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } vars := mux.Vars(r) @@ -1098,14 +1098,14 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // X-Amz-Copy-Source shouldn't be set for this call. if _, ok := r.Header["X-Amz-Copy-Source"]; ok { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) return } // Validate storage class metadata if present if _, ok := r.Header[amzStorageClassCanonical]; ok { if !isValidStorageClassMeta(r.Header.Get(amzStorageClassCanonical)) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidStorageClass), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidStorageClass), r.URL, guessIsBrowserReq(r)) return } } @@ -1113,7 +1113,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Get Content-Md5 sent by client and verify if valid md5Bytes, err := checkValidMD5(r.Header) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidDigest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidDigest), r.URL, guessIsBrowserReq(r)) return } /// if Content-Length is unknown/missing, deny the request @@ -1122,30 +1122,30 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req if rAuthType == authTypeStreamingSigned { if sizeStr, ok := r.Header["X-Amz-Decoded-Content-Length"]; ok { if sizeStr[0] == "" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return } size, err = strconv.ParseInt(sizeStr[0], 10, 64) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } } if size == -1 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return } /// maximum Upload size for objects in a single operation if isMaxObjectSize(size) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) return } metadata, err := extractMetadata(ctx, r) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1180,7 +1180,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Check if put is allowed if s3Err = isPutAllowed(rAuthType, bucket, object, r); s3Err != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL, guessIsBrowserReq(r)) return } @@ -1189,19 +1189,19 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Initialize stream signature verifier. reader, s3Err = newSignV4ChunkedReader(r) if s3Err != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL, guessIsBrowserReq(r)) return } case authTypeSignedV2, authTypePresignedV2: s3Err = isReqAuthenticatedV2(r) if s3Err != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL, guessIsBrowserReq(r)) return } case authTypePresigned, authTypeSigned: if s3Err = reqSignatureV4Verify(r, globalServerConfig.GetRegion()); s3Err != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL, guessIsBrowserReq(r)) return } if !skipContentSha256Cksum(r) { @@ -1222,7 +1222,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req var actualReader *hash.Reader actualReader, err = hash.NewReader(reader, size, md5hex, sha256hex, actualSize) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1242,7 +1242,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req hashReader, err := hash.NewReader(reader, size, md5hex, sha256hex, actualSize) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1264,7 +1264,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Deny if WORM is enabled if globalWORMEnabled { if _, err = objectAPI.GetObjectInfo(ctx, bucket, object, opts); err == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } } @@ -1274,13 +1274,13 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req if hasServerSideEncryptionHeader(r.Header) && !hasSuffix(object, slashSeparator) { // handle SSE requests reader, objectEncryptionKey, err = EncryptRequest(hashReader, r, bucket, object, metadata) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } info := ObjectInfo{Size: size} hashReader, err = hash.NewReader(reader, info.EncryptedSize(), "", "", size) // do not try to verify encrypted content if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } pReader = NewPutObjReader(rawReader, hashReader, objectEncryptionKey) @@ -1297,7 +1297,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Create the object.. objInfo, err := putObject(ctx, bucket, object, pReader, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1358,15 +1358,15 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if crypto.S3KMS.IsRequested(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported return } if !api.EncryptionEnabled() && hasServerSideEncryptionHeader(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } vars := mux.Vars(r) @@ -1374,7 +1374,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r object := vars["object"] if s3Error := checkRequestAuthType(ctx, r, policy.PutObjectAction, bucket, object); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -1396,7 +1396,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r // Deny if WORM is enabled if globalWORMEnabled { if _, err = objectAPI.GetObjectInfo(ctx, bucket, object, opts); err == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } } @@ -1404,7 +1404,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r // Validate storage class metadata if present if _, ok := r.Header[amzStorageClassCanonical]; ok { if !isValidStorageClassMeta(r.Header.Get(amzStorageClassCanonical)) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidStorageClass), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidStorageClass), r.URL, guessIsBrowserReq(r)) return } } @@ -1414,7 +1414,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r if objectAPI.IsEncryptionSupported() { if hasServerSideEncryptionHeader(r.Header) { if err = setEncryptionMetadata(r, bucket, object, encMetadata); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // Set this for multipart only operations, we need to differentiate during @@ -1426,7 +1426,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r // Extract metadata that needs to be saved. metadata, err := extractMetadata(ctx, r) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1455,7 +1455,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r } uploadID, err := newMultipartUpload(ctx, bucket, object, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1474,15 +1474,15 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if crypto.S3KMS.IsRequested(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported return } if !api.EncryptionEnabled() && (hasServerSideEncryptionHeader(r.Header) || crypto.SSECopy.IsRequested(r.Header)) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } @@ -1491,7 +1491,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt dstObject := vars["object"] if s3Error := checkRequestAuthType(ctx, r, policy.PutObjectAction, dstBucket, dstObject); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -1508,7 +1508,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt // its non "null" value, we should error out since we do not support // any versions other than "null". if vid := u.Query().Get("versionId"); vid != "" && vid != "null" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) return } // Note that url.Parse does the unescaping @@ -1519,7 +1519,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt // its non "null" value, we should error out since we do not support // any versions other than "null". if vid != "null" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) return } } @@ -1527,12 +1527,12 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt srcBucket, srcObject := path2BucketAndObject(cpSrcPath) // If source object is empty or bucket is empty, reply back invalid copy source. if srcObject == "" || srcBucket == "" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.GetObjectAction, srcBucket, srcObject); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -1541,20 +1541,20 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt partID, err := strconv.Atoi(partIDString) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL, guessIsBrowserReq(r)) return } // check partID with maximum part ID for multipart objects if isMaxPartID(partID) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidMaxParts), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidMaxParts), r.URL, guessIsBrowserReq(r)) return } var srcOpts, dstOpts ObjectOptions srcOpts, err = copySrcOpts(ctx, r, srcBucket, srcObject) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // convert copy src and dst encryption options for GET/PUT calls @@ -1564,14 +1564,14 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt } dstOpts, err = copyDstOpts(ctx, r, dstBucket, dstObject, nil) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // Deny if WORM is enabled if globalWORMEnabled { if _, err = objectAPI.GetObjectInfo(ctx, dstBucket, dstObject, dstOpts); err == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } } @@ -1599,7 +1599,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt gr, err := getObjectNInfo(ctx, srcBucket, srcObject, rs, r.Header, readLock, getOpts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } defer gr.Close() @@ -1609,7 +1609,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt if crypto.IsEncrypted(srcInfo.UserDefined) { actualPartSize, err = srcInfo.DecryptedSize() if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -1621,20 +1621,20 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt } // Verify before x-amz-copy-source preconditions before continuing with CopyObject. - if checkCopyObjectPartPreconditions(w, r, srcInfo) { + if checkCopyObjectPartPreconditions(ctx, w, r, srcInfo) { return } // Get the object offset & length startOffset, length, err := rs.GetOffsetLength(actualPartSize) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } /// maximum copy size for multipart objects in a single operation if isMaxAllowedPartSize(length) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) return } @@ -1644,7 +1644,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt var li ListPartsInfo li, err = objectAPI.ListObjectParts(ctx, dstBucket, dstObject, uploadID, 0, 1, dstOpts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1674,7 +1674,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt srcInfo.Reader, err = hash.NewReader(reader, length, "", "", actualPartSize) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1686,22 +1686,22 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt if objectAPI.IsEncryptionSupported() && !isCompressed { li, lerr := objectAPI.ListObjectParts(ctx, dstBucket, dstObject, uploadID, 0, 1, dstOpts) if lerr != nil { - writeErrorResponse(w, toAPIError(ctx, lerr), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, lerr), r.URL, guessIsBrowserReq(r)) return } li.UserDefined = CleanMinioInternalMetadataKeys(li.UserDefined) dstOpts, err = copyDstOpts(ctx, r, dstBucket, dstObject, li.UserDefined) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } if crypto.IsEncrypted(li.UserDefined) { if !crypto.SSEC.IsRequested(r.Header) && crypto.SSEC.IsEncrypted(li.UserDefined) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrSSEMultipartEncrypted), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrSSEMultipartEncrypted), r.URL, guessIsBrowserReq(r)) return } if crypto.S3.IsEncrypted(li.UserDefined) && crypto.SSEC.IsRequested(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrSSEMultipartEncrypted), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrSSEMultipartEncrypted), r.URL, guessIsBrowserReq(r)) return } isEncrypted = true @@ -1709,13 +1709,13 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt if crypto.SSEC.IsRequested(r.Header) { key, err = ParseSSECustomerRequest(r) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } objectEncryptionKey, err = decryptObjectInfo(key, dstBucket, dstObject, li.UserDefined) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1727,14 +1727,14 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt partEncryptionKey := mac.Sum(nil) reader, err = sio.EncryptReader(reader, sio.Config{Key: partEncryptionKey}) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } info := ObjectInfo{Size: length} srcInfo.Reader, err = hash.NewReader(reader, info.EncryptedSize(), "", "", length) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } pReader = NewPutObjReader(rawReader, srcInfo.Reader, objectEncryptionKey) @@ -1746,7 +1746,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt partInfo, err := objectAPI.CopyObjectPart(ctx, srcBucket, srcObject, dstBucket, dstObject, uploadID, partID, startOffset, length, srcInfo, srcOpts, dstOpts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1769,15 +1769,15 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if crypto.S3KMS.IsRequested(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) // SSE-KMS is not supported return } if !api.EncryptionEnabled() && hasServerSideEncryptionHeader(r.Header) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) return } vars := mux.Vars(r) @@ -1786,14 +1786,14 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http // X-Amz-Copy-Source shouldn't be set for this call. if _, ok := r.Header["X-Amz-Copy-Source"]; ok { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidCopySource), r.URL, guessIsBrowserReq(r)) return } // get Content-Md5 sent by client and verify if valid md5Bytes, err := checkValidMD5(r.Header) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidDigest), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidDigest), r.URL, guessIsBrowserReq(r)) return } @@ -1805,24 +1805,24 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http if rAuthType == authTypeStreamingSigned { if sizeStr, ok := r.Header["X-Amz-Decoded-Content-Length"]; ok { if sizeStr[0] == "" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return } size, err = strconv.ParseInt(sizeStr[0], 10, 64) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } } if size == -1 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMissingContentLength), r.URL, guessIsBrowserReq(r)) return } /// maximum Upload size for multipart objects in a single operation if isMaxAllowedPartSize(size) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrEntityTooLarge), r.URL, guessIsBrowserReq(r)) return } @@ -1831,13 +1831,13 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http partID, err := strconv.Atoi(partIDString) if err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL, guessIsBrowserReq(r)) return } // check partID with maximum part ID for multipart objects if isMaxPartID(partID) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidMaxParts), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidMaxParts), r.URL, guessIsBrowserReq(r)) return } @@ -1849,7 +1849,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http ) reader = r.Body if s3Error = isPutAllowed(rAuthType, bucket, object, r); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -1858,17 +1858,17 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http // Initialize stream signature verifier. reader, s3Error = newSignV4ChunkedReader(r) if s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } case authTypeSignedV2, authTypePresignedV2: if s3Error = isReqAuthenticatedV2(r); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } case authTypePresigned, authTypeSigned: if s3Error = reqSignatureV4Verify(r, globalServerConfig.GetRegion()); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } @@ -1886,14 +1886,14 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http if crypto.SSEC.IsRequested(r.Header) { opts, err = putOpts(ctx, r, bucket, object, nil) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } var li ListPartsInfo li, err = objectAPI.ListObjectParts(ctx, bucket, object, uploadID, 0, 1, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // Read compression metadata preserved in the init multipart for the decision. @@ -1907,7 +1907,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http var actualReader *hash.Reader actualReader, err = hash.NewReader(reader, size, md5hex, sha256hex, actualSize) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1928,7 +1928,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http hashReader, err := hash.NewReader(reader, size, md5hex, sha256hex, actualSize) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } rawReader := hashReader @@ -1937,7 +1937,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http // Deny if WORM is enabled if globalWORMEnabled { if _, err = objectAPI.GetObjectInfo(ctx, bucket, object, opts); err == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } } @@ -1948,20 +1948,20 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http var li ListPartsInfo li, err = objectAPI.ListObjectParts(ctx, bucket, object, uploadID, 0, 1, ObjectOptions{}) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } li.UserDefined = CleanMinioInternalMetadataKeys(li.UserDefined) if crypto.IsEncrypted(li.UserDefined) { if !crypto.SSEC.IsRequested(r.Header) && crypto.SSEC.IsEncrypted(li.UserDefined) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrSSEMultipartEncrypted), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrSSEMultipartEncrypted), r.URL, guessIsBrowserReq(r)) return } isEncrypted = true // to detect SSE-S3 encryption opts, err = putOpts(ctx, r, bucket, object, li.UserDefined) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -1969,7 +1969,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http if crypto.SSEC.IsRequested(r.Header) { key, err = ParseSSECustomerRequest(r) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -1977,7 +1977,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http // Calculating object encryption key objectEncryptionKey, err = decryptObjectInfo(key, bucket, object, li.UserDefined) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } var partIDbin [4]byte @@ -1989,13 +1989,13 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http reader, err = sio.EncryptReader(hashReader, sio.Config{Key: partEncryptionKey}) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } info := ObjectInfo{Size: size} hashReader, err = hash.NewReader(reader, info.EncryptedSize(), "", "", size) // do not try to verify encrypted content if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } pReader = NewPutObjReader(rawReader, hashReader, objectEncryptionKey) @@ -2009,7 +2009,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http partInfo, err := putObjectPart(ctx, bucket, object, uploadID, partID, pReader, opts) if err != nil { // Verify if the underlying error is signature mismatch. - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -2038,7 +2038,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } abortMultipartUpload := objectAPI.AbortMultipartUpload @@ -2047,25 +2047,25 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, } if s3Error := checkRequestAuthType(ctx, r, policy.AbortMultipartUploadAction, bucket, object); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Deny if WORM is enabled if globalWORMEnabled { if _, err := objectAPI.GetObjectInfo(ctx, bucket, object, ObjectOptions{}); err == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } } uploadID, _, _, _, s3Error := getObjectResources(r.URL.Query()) if s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } if err := abortMultipartUpload(ctx, bucket, object, uploadID); err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -2084,32 +2084,32 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.ListMultipartUploadPartsAction, bucket, object); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } uploadID, partNumberMarker, maxParts, _, s3Error := getObjectResources(r.URL.Query()) if s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } if partNumberMarker < 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidPartNumberMarker), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPartNumberMarker), r.URL, guessIsBrowserReq(r)) return } if maxParts < 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidMaxParts), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidMaxParts), r.URL, guessIsBrowserReq(r)) return } var opts ObjectOptions listPartsInfo, err := objectAPI.ListObjectParts(ctx, bucket, object, uploadID, partNumberMarker, maxParts, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } var ssec bool @@ -2117,7 +2117,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht var li ListPartsInfo li, err = objectAPI.ListObjectParts(ctx, bucket, object, uploadID, 0, 1, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } if crypto.IsEncrypted(li.UserDefined) { @@ -2130,7 +2130,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht // Calculating object encryption key objectEncryptionKey, err = decryptObjectInfo(key, bucket, object, li.UserDefined) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -2193,19 +2193,19 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.PutObjectAction, bucket, object); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } // Deny if WORM is enabled if globalWORMEnabled { if _, err := objectAPI.GetObjectInfo(ctx, bucket, object, ObjectOptions{}); err == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } } @@ -2213,26 +2213,26 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite // Get upload id. uploadID, _, _, _, s3Error := getObjectResources(r.URL.Query()) if s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } completeMultipartBytes, err := goioutil.ReadAll(r.Body) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } complMultipartUpload := &CompleteMultipartUpload{} if err = xml.Unmarshal(completeMultipartBytes, complMultipartUpload); err != nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL, guessIsBrowserReq(r)) return } if len(complMultipartUpload.Parts) == 0 { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMalformedXML), r.URL, guessIsBrowserReq(r)) return } if !sort.IsSorted(CompletedParts(complMultipartUpload.Parts)) { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidPartOrder), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPartOrder), r.URL, guessIsBrowserReq(r)) return } var objectEncryptionKey []byte @@ -2242,7 +2242,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite var li ListPartsInfo li, err = objectAPI.ListObjectParts(ctx, bucket, object, uploadID, 0, 1, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } if crypto.IsEncrypted(li.UserDefined) { @@ -2253,7 +2253,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite // Calculating object encryption key objectEncryptionKey, err = decryptObjectInfo(key, bucket, object, li.UserDefined) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -2267,7 +2267,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite for { listPartsInfo, err := objectAPI.ListObjectParts(ctx, bucket, object, uploadID, partNumberMarker, maxParts, opts) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } for _, part := range listPartsInfo.Parts { @@ -2295,7 +2295,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite if bkPartInfo, ok := partsMap[strconv.Itoa(part.PartNumber)]; ok { bkETag := tryDecryptETag(objectEncryptionKey, bkPartInfo.ETag, ssec) if bkETag != part.ETag { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrInvalidPart), r.URL, guessIsBrowserReq(r)) return } part.ETag = bkPartInfo.ETag @@ -2317,10 +2317,10 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite switch oErr := err.(type) { case PartTooSmall: // Write part too small error. - writePartSmallErrorResponse(w, r, oErr) + writePartSmallErrorResponse(ctx, w, r, oErr) default: // Handle all other generic issues. - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) } return } @@ -2331,7 +2331,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite response := generateCompleteMultpartUploadResponse(bucket, object, location, objInfo.ETag) encodedSuccessResponse := encodeResponse(response) if err != nil { - writeErrorResponse(w, toAdminAPIErr(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAdminAPIErr(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -2374,17 +2374,17 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. objectAPI := api.ObjectAPI() if objectAPI == nil { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } if s3Error := checkRequestAuthType(ctx, r, policy.DeleteObjectAction, bucket, object); s3Error != ErrNone { - writeErrorResponse(w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) return } if vid := r.URL.Query().Get("versionId"); vid != "" && vid != "null" { - writeErrorResponse(w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNoSuchVersion), r.URL, guessIsBrowserReq(r)) return } @@ -2392,14 +2392,14 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. if globalWORMEnabled { // Not required to check whether given object exists or not, because // DeleteObject is always successful irrespective of object existence. - writeErrorResponse(w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL, guessIsBrowserReq(r)) return } if globalDNSConfig != nil { _, err := globalDNSConfig.Get(bucket) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } } @@ -2409,7 +2409,7 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. switch err.(type) { case BucketNotFound: // When bucket doesn't exist specially handle it. - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } // Ignore delete object errors while replying to client, since we are suppposed to reply only 204. diff --git a/cmd/object-handlers_test.go b/cmd/object-handlers_test.go index fddf94858..f26a7a3c9 100644 --- a/cmd/object-handlers_test.go +++ b/cmd/object-handlers_test.go @@ -364,6 +364,8 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a } } + ctx := context.Background() + // test cases with inputs and expected result for GetObject. testCases := []struct { bucketName string @@ -396,7 +398,9 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), getGetObjectURL("", bucketName, "abcd"), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrNoSuchKey), + getGetObjectURL("", bucketName, "abcd"), "", "")), expectedRespStatus: http.StatusNotFound, }, // Test case - 3. @@ -420,7 +424,9 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidRange), getGetObjectURL("", bucketName, objectName), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrInvalidRange), + getGetObjectURL("", bucketName, objectName), "", "")), expectedRespStatus: http.StatusRequestedRangeNotSatisfiable, }, // Test case - 5. @@ -446,7 +452,9 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: "Invalid-AccessID", secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), getGetObjectURL("", bucketName, objectName), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrInvalidAccessKeyID), + getGetObjectURL("", bucketName, objectName), "", "")), expectedRespStatus: http.StatusForbidden, }, // Test case - 7. @@ -458,8 +466,9 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName), - getGetObjectURL("", bucketName, "../../etc"), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrInvalidObjectName), + getGetObjectURL("", bucketName, "../../etc"), "", "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 8. @@ -471,8 +480,9 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), - "/"+bucketName+"/"+". ./. ./etc", "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrNoSuchKey), + "/"+bucketName+"/"+". ./. ./etc", "", "")), expectedRespStatus: http.StatusNotFound, }, // Test case - 9. @@ -484,8 +494,9 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidObjectName), - "/"+bucketName+"/"+". ./../etc", "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrInvalidObjectName), + "/"+bucketName+"/"+". ./../etc", "", "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 10. @@ -497,8 +508,10 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrNoSuchKey), - getGetObjectURL("", bucketName, "etc/path/proper/.../etc"), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrNoSuchKey), + getGetObjectURL("", bucketName, "etc/path/proper/.../etc"), + "", "")), expectedRespStatus: http.StatusNotFound, }, } @@ -527,11 +540,28 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a // read the response body. actualContent, err := ioutil.ReadAll(rec.Body) if err != nil { - t.Fatalf("Test %d: %s: Failed parsing response body: %v", i+1, instanceType, err) + t.Fatalf("Test %d: %s: Failed reading response body: %v", i+1, instanceType, err) } + + if rec.Code == http.StatusOK || rec.Code == http.StatusPartialContent { + if !bytes.Equal(testCase.expectedContent, actualContent) { + t.Errorf("Test %d: %s: Object content differs from expected value %s, got %s", i+1, instanceType, testCase.expectedContent, string(actualContent)) + } + continue + } + // Verify whether the bucket obtained object is same as the one created. - if !bytes.Equal(testCase.expectedContent, actualContent) { - t.Errorf("Test %d: %s: Object content differs from expected value %s, got %s", i+1, instanceType, testCase.expectedContent, string(actualContent)) + actualError := &APIErrorResponse{} + if err = xml.Unmarshal(actualContent, actualError); err != nil { + t.Fatalf("Test %d: %s: Failed parsing response body: %v", i+1, instanceType, err) + } + + if actualError.BucketName != testCase.bucketName { + t.Fatalf("Test %d: %s: Unexpected bucket name, expected %s, got %s", i+1, instanceType, testCase.bucketName, actualError.BucketName) + } + + if actualError.Key != testCase.objectName { + t.Fatalf("Test %d: %s: Unexpected object name, expected %s, got %s", i+1, instanceType, testCase.objectName, actualError.Key) } // Verify response of the V2 signed HTTP request. @@ -559,11 +589,28 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a // read the response body. actualContent, err = ioutil.ReadAll(recV2.Body) if err != nil { + t.Fatalf("Test %d: %s: Failed to read response body: %v", i+1, instanceType, err) + } + + if rec.Code == http.StatusOK || rec.Code == http.StatusPartialContent { + // Verify whether the bucket obtained object is same as the one created. + if !bytes.Equal(testCase.expectedContent, actualContent) { + t.Errorf("Test %d: %s: Object content differs from expected value.", i+1, instanceType) + } + continue + } + + actualError = &APIErrorResponse{} + if err = xml.Unmarshal(actualContent, actualError); err != nil { t.Fatalf("Test %d: %s: Failed parsing response body: %v", i+1, instanceType, err) } - // Verify whether the bucket obtained object is same as the one created. - if !bytes.Equal(testCase.expectedContent, actualContent) { - t.Errorf("Test %d: %s: Object content differs from expected value.", i+1, instanceType) + + if actualError.BucketName != testCase.bucketName { + t.Fatalf("Test %d: %s: Unexpected bucket name, expected %s, got %s", i+1, instanceType, testCase.bucketName, actualError.BucketName) + } + + if actualError.Key != testCase.objectName { + t.Fatalf("Test %d: %s: Unexpected object name, expected %s, got %s", i+1, instanceType, testCase.objectName, actualError.Key) } } @@ -2646,8 +2693,9 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(toAPIError(ctx, InvalidPart{}), - getGetObjectURL("", bucketName, objectName), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + toAPIError(ctx, InvalidPart{}), + getGetObjectURL("", bucketName, objectName), "", "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 2. @@ -2661,8 +2709,9 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrMalformedXML), - getGetObjectURL("", bucketName, objectName), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrMalformedXML), + getGetObjectURL("", bucketName, objectName), "", "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 3. @@ -2676,8 +2725,9 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(toAPIError(ctx, InvalidUploadID{UploadID: "abc"}), - getGetObjectURL("", bucketName, objectName), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + toAPIError(ctx, InvalidUploadID{UploadID: "abc"}), + getGetObjectURL("", bucketName, objectName), "", "")), expectedRespStatus: http.StatusNotFound, }, // Test case - 4. @@ -2691,8 +2741,8 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s secretKey: credentials.SecretKey, expectedContent: encodeResponse(completeMultipartAPIError{int64(4), int64(5242880), 1, "e2fc714c4727ee9395f324cd2e7f331f", - getAPIErrorResponse(toAPIError(ctx, PartTooSmall{PartNumber: 1}), - getGetObjectURL("", bucketName, objectName), "")}), + getAPIErrorResponse(ctx, toAPIError(ctx, PartTooSmall{PartNumber: 1}), + getGetObjectURL("", bucketName, objectName), "", "")}), expectedRespStatus: http.StatusBadRequest, }, // Test case - 5. @@ -2705,8 +2755,9 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(toAPIError(ctx, InvalidPart{}), - getGetObjectURL("", bucketName, objectName), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + toAPIError(ctx, InvalidPart{}), + getGetObjectURL("", bucketName, objectName), "", "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 6. @@ -2720,8 +2771,9 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidPartOrder), - getGetObjectURL("", bucketName, objectName), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrInvalidPartOrder), + getGetObjectURL("", bucketName, objectName), "", "")), expectedRespStatus: http.StatusBadRequest, }, // Test case - 7. @@ -2735,8 +2787,9 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: "Invalid-AccessID", secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(ErrInvalidAccessKeyID), - getGetObjectURL("", bucketName, objectName), "")), + expectedContent: encodeResponse(getAPIErrorResponse(ctx, + getAPIError(ErrInvalidAccessKeyID), + getGetObjectURL("", bucketName, objectName), "", "")), expectedRespStatus: http.StatusForbidden, }, // Test case - 8. @@ -2788,11 +2841,27 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s if err != nil { t.Fatalf("Test %d : Minio %s: Failed parsing response body: %v", i+1, instanceType, err) } - // Verify whether the bucket obtained object is same as the one created. - if !bytes.Equal(testCase.expectedContent, actualContent) { - t.Errorf("Test %d : Minio %s: Object content differs from expected value.", i+1, instanceType) + + if rec.Code == http.StatusOK { + // Verify whether the bucket obtained object is same as the one created. + if !bytes.Equal(testCase.expectedContent, actualContent) { + t.Errorf("Test %d : Minio %s: Object content differs from expected value.", i+1, instanceType) + } + continue + } + + actualError := &APIErrorResponse{} + if err = xml.Unmarshal(actualContent, actualError); err != nil { + t.Errorf("Minio %s: error response failed to parse error XML", instanceType) + } + + if actualError.BucketName != bucketName { + t.Errorf("Minio %s: error response bucket name differs from expected value", instanceType) } + if actualError.Key != objectName { + t.Errorf("Minio %s: error response object name differs from expected value", instanceType) + } } // Testing for anonymous API request. diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index 14ad50ac5..09624573a 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -1741,9 +1741,6 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, obj ObjectLayer, testName, bucketN t.Fatal(failTestStr(anonTestStr, fmt.Sprintf("Object API Nil Test expected to fail with %d, but failed with %d", accesDeniedHTTPStatus, rec.Code))) } - // expected error response in bytes when objectLayer is not initialized, or set to `nil`. - expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrAccessDenied), getGetObjectURL("", bucketName, objectName), "")) - // HEAD HTTTP request doesn't contain response body. if anonReq.Method != "HEAD" { // read the response body. @@ -1752,9 +1749,18 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, obj ObjectLayer, testName, bucketN if err != nil { t.Fatal(failTestStr(anonTestStr, fmt.Sprintf("Failed parsing response body: %v", err))) } - // verify whether actual error response (from the response body), matches the expected error response. - if !bytes.Equal(expectedErrResponse, actualContent) { - t.Fatal(failTestStr(anonTestStr, "error response content differs from expected value")) + + actualError := &APIErrorResponse{} + if err = xml.Unmarshal(actualContent, actualError); err != nil { + t.Fatal(failTestStr(anonTestStr, "error response failed to parse error XML")) + } + + if actualError.BucketName != bucketName { + t.Fatal(failTestStr(anonTestStr, "error response bucket name differs from expected value")) + } + + if actualError.Key != objectName { + t.Fatal(failTestStr(anonTestStr, "error response object name differs from expected value")) } } @@ -1804,11 +1810,18 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, obj ObjectLayer, testName, bucketN if err != nil { t.Fatal(failTestStr(unknownSignTestStr, fmt.Sprintf("Failed parsing response body: %v", err))) } - // verify whether actual error response (from the response body), matches the expected error response. - if !bytes.Equal(expectedErrResponse, actualContent) { - fmt.Println(string(expectedErrResponse)) - fmt.Println(string(actualContent)) - t.Fatal(failTestStr(unknownSignTestStr, "error response content differs from expected value")) + + actualError := &APIErrorResponse{} + if err = xml.Unmarshal(actualContent, actualError); err != nil { + t.Fatal(failTestStr(unknownSignTestStr, "error response failed to parse error XML")) + } + + if actualError.BucketName != bucketName { + t.Fatal(failTestStr(unknownSignTestStr, "error response bucket name differs from expected value")) + } + + if actualError.Key != objectName { + t.Fatal(failTestStr(unknownSignTestStr, "error response object name differs from expected value")) } } @@ -1843,9 +1856,6 @@ func ExecObjectLayerAPINilTest(t TestErrHandler, bucketName, objectName, instanc if rec.Code != serverNotInitializedErr { t.Errorf("Object API Nil Test expected to fail with %d, but failed with %d", serverNotInitializedErr, rec.Code) } - // expected error response in bytes when objectLayer is not initialized, or set to `nil`. - expectedErrResponse := encodeResponse(getAPIErrorResponse(getAPIError(ErrServerNotInitialized), - getGetObjectURL("", bucketName, objectName), "")) // HEAD HTTP Request doesn't contain body in its response, // for other type of HTTP requests compare the response body content with the expected one. @@ -1855,9 +1865,18 @@ func ExecObjectLayerAPINilTest(t TestErrHandler, bucketName, objectName, instanc if err != nil { t.Fatalf("Minio %s: Failed parsing response body: %v", instanceType, err) } - // verify whether actual error response (from the response body), matches the expected error response. - if !bytes.Equal(expectedErrResponse, actualContent) { - t.Errorf("Minio %s: Object content differs from expected value", instanceType) + + actualError := &APIErrorResponse{} + if err = xml.Unmarshal(actualContent, actualError); err != nil { + t.Errorf("Minio %s: error response failed to parse error XML", instanceType) + } + + if actualError.BucketName != bucketName { + t.Errorf("Minio %s: error response bucket name differs from expected value", instanceType) + } + + if actualError.Key != objectName { + t.Errorf("Minio %s: error response object name differs from expected value", instanceType) } } } diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index c96aa8a80..c13965ad9 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -894,7 +894,7 @@ func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) { // Extract incoming metadata if any. metadata, err := extractMetadata(context.Background(), r) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } @@ -952,13 +952,13 @@ func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) { var objectEncryptionKey []byte reader, objectEncryptionKey, err = EncryptRequest(hashReader, r, bucket, object, metadata) if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } info := ObjectInfo{Size: size} hashReader, err = hash.NewReader(reader, info.EncryptedSize(), "", "", size) // do not try to verify encrypted content if err != nil { - writeErrorResponse(w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } pReader = NewPutObjReader(rawReader, hashReader, objectEncryptionKey)