From a55a298e00d3931cf46b46363f5700a03e3fc66f Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 12 Nov 2018 11:07:43 -0800 Subject: [PATCH] Make sure to log unhandled errors always (#6784) In many situations, while testing we encounter ErrInternalError, to reduce logging we have removed logging from quite a few places which is acceptable but when ErrInternalError occurs we should have a facility to log the corresponding error, this helps to debug Minio server. --- cmd/acl-handlers.go | 8 +- cmd/admin-handlers.go | 140 +++++++++++++--------------- cmd/admin-handlers_test.go | 4 +- cmd/admin-heal-ops.go | 18 ++-- cmd/api-errors.go | 7 +- cmd/api-errors_test.go | 4 +- cmd/api-response-multipart.go | 7 +- cmd/auth-handler.go | 16 ++-- cmd/auth-handler_test.go | 11 ++- cmd/bucket-handlers-listobjects.go | 8 +- cmd/bucket-handlers.go | 40 ++++---- cmd/bucket-notification-handlers.go | 36 ++++--- cmd/bucket-policy-handlers.go | 15 ++- cmd/encryption-v1.go | 2 +- cmd/generic-handlers.go | 2 +- cmd/object-handlers.go | 120 ++++++++++++------------ cmd/object-handlers_test.go | 10 +- cmd/test-utils_test.go | 5 +- 18 files changed, 228 insertions(+), 225 deletions(-) diff --git a/cmd/acl-handlers.go b/cmd/acl-handlers.go index 5849eb7db..639e82d2d 100644 --- a/cmd/acl-handlers.go +++ b/cmd/acl-handlers.go @@ -78,7 +78,7 @@ func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http. // Before proceeding validate if bucket exists. _, err := objAPI.GetBucketInfo(ctx, bucket) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) 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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -128,7 +128,7 @@ func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http. // Before proceeding validate if object exists. _, err := objAPI.GetObjectInfo(ctx, bucket, object, ObjectOptions{}) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) 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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 6988a4850..f4538694b 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -71,7 +71,9 @@ var ( // ----------- // Returns Administration API version func (a adminAPIHandlers) VersionHandler(w http.ResponseWriter, r *http.Request) { - adminAPIErr := checkAdminRequestAuthType(r, "") + ctx := newContext(r, w, "Version") + + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -79,8 +81,7 @@ func (a adminAPIHandlers) VersionHandler(w http.ResponseWriter, r *http.Request) jsonBytes, err := json.Marshal(adminAPIVersionInfo) if err != nil { - writeErrorResponseJSON(w, ErrInternalError, r.URL) - logger.LogIf(context.Background(), err) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -91,7 +92,9 @@ func (a adminAPIHandlers) VersionHandler(w http.ResponseWriter, r *http.Request) // ---------- // Returns server version and uptime. func (a adminAPIHandlers) ServiceStatusHandler(w http.ResponseWriter, r *http.Request) { - adminAPIErr := checkAdminRequestAuthType(r, "") + ctx := newContext(r, w, "ServiceStatus") + + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -107,8 +110,7 @@ func (a adminAPIHandlers) ServiceStatusHandler(w http.ResponseWriter, r *http.Re // of read-quorum availability. uptime, err := getPeerUptimes(globalAdminPeers) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) - logger.LogIf(context.Background(), err) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -121,8 +123,7 @@ func (a adminAPIHandlers) ServiceStatusHandler(w http.ResponseWriter, r *http.Re // Marshal API response jsonBytes, err := json.Marshal(serverStatus) if err != nil { - writeErrorResponseJSON(w, ErrInternalError, r.URL) - logger.LogIf(context.Background(), err) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } // Reply with storage information (across nodes in a @@ -136,7 +137,9 @@ func (a adminAPIHandlers) ServiceStatusHandler(w http.ResponseWriter, r *http.Re // Restarts/Stops minio server gracefully. In a distributed setup, // restarts all the servers in the cluster. func (a adminAPIHandlers) ServiceStopNRestartHandler(w http.ResponseWriter, r *http.Request) { - adminAPIErr := checkAdminRequestAuthType(r, "") + ctx := newContext(r, w, "ServiceStopNRestart") + + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -145,7 +148,7 @@ func (a adminAPIHandlers) ServiceStopNRestartHandler(w http.ResponseWriter, r *h var sa madmin.ServiceAction err := json.NewDecoder(r.Body).Decode(&sa) if err != nil { - logger.LogIf(context.Background(), err) + logger.LogIf(ctx, err) writeErrorResponseJSON(w, ErrRequestBodyParse, r.URL) return } @@ -158,7 +161,7 @@ func (a adminAPIHandlers) ServiceStopNRestartHandler(w http.ResponseWriter, r *h serviceSig = serviceStop default: writeErrorResponseJSON(w, ErrMalformedPOSTRequest, r.URL) - logger.LogIf(context.Background(), errors.New("Invalid service action received")) + logger.LogIf(ctx, errors.New("Invalid service action received")) return } @@ -227,10 +230,12 @@ type ServerInfo struct { // ---------- // Get server information func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Request) { + ctx := newContext(r, w, "ServerInfo") + // Authenticate request // Setting the region as empty so as the mc server info command is irrespective to the region. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -255,7 +260,7 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque serverInfoData, err := peer.cmdRunner.ServerInfo() if err != nil { reqInfo := (&logger.ReqInfo{}).AppendTags("peerAddress", peer.addr) - ctx := logger.SetReqInfo(context.Background(), reqInfo) + ctx := logger.SetReqInfo(ctx, reqInfo) logger.LogIf(ctx, err) reply[idx].Error = err.Error() return @@ -270,8 +275,7 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque // Marshal API response jsonBytes, err := json.Marshal(reply) if err != nil { - writeErrorResponseJSON(w, ErrInternalError, r.URL) - logger.LogIf(context.Background(), err) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -292,7 +296,9 @@ type StartProfilingResult struct { // ---------- // Enable server profiling func (a adminAPIHandlers) StartProfilingHandler(w http.ResponseWriter, r *http.Request) { - adminAPIErr := checkAdminRequestAuthType(r, "") + ctx := newContext(r, w, "StartProfiling") + + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -351,7 +357,9 @@ func (f dummyFileInfo) Sys() interface{} { return f.sys } // ---------- // Download profiling information of all nodes in a zip format func (a adminAPIHandlers) DownloadProfilingHandler(w http.ResponseWriter, r *http.Request) { - adminAPIErr := checkAdminRequestAuthType(r, "") + ctx := newContext(r, w, "DownloadProfiling") + + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -368,7 +376,7 @@ func (a adminAPIHandlers) DownloadProfilingHandler(w http.ResponseWriter, r *htt // Get profiling data from a node data, err := peer.cmdRunner.DownloadProfilingData() if err != nil { - logger.LogIf(context.Background(), fmt.Errorf("Unable to download profiling data from node `%s`, reason: %s", peer.addr, err.Error())) + logger.LogIf(ctx, fmt.Errorf("Unable to download profiling data from node `%s`, reason: %s", peer.addr, err.Error())) continue } @@ -475,7 +483,7 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -570,8 +578,7 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) { StartTime: nh.startTime, }) if err != nil { - logger.LogIf(context.Background(), err) - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAdminAPIErrCode(ctx, err), r.URL) return } // Client token not specified but a heal sequence exists on a path, @@ -630,7 +637,7 @@ func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Reques } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -638,22 +645,20 @@ func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Reques config, err := readServerConfig(ctx, objectAPI) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } configData, err := json.MarshalIndent(config, "", "\t") if err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } password := config.GetCredential().SecretKey econfigData, err := madmin.EncryptData(password, configData) if err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -692,7 +697,7 @@ func (a adminAPIHandlers) GetConfigKeysHandler(w http.ResponseWriter, r *http.Re } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -707,14 +712,13 @@ func (a adminAPIHandlers) GetConfigKeysHandler(w http.ResponseWriter, r *http.Re config, err := readServerConfig(ctx, objectAPI) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } configData, err := json.Marshal(config) if err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -736,8 +740,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 { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -746,12 +749,12 @@ func (a adminAPIHandlers) GetConfigKeysHandler(w http.ResponseWriter, r *http.Re // toAdminAPIErrCode - converts errXLWriteQuorum error to admin API // specific error. -func toAdminAPIErrCode(err error) APIErrorCode { +func toAdminAPIErrCode(ctx context.Context, err error) APIErrorCode { switch err { case errXLWriteQuorum: return ErrAdminConfigNoQuorum default: - return toAPIErrorCode(err) + return toAPIErrorCode(ctx, err) } } @@ -767,7 +770,7 @@ func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) { } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -782,8 +785,7 @@ func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) accessKey := vars["accessKey"] if err := globalIAMSys.DeleteUser(accessKey); err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) } } @@ -799,7 +801,7 @@ func (a adminAPIHandlers) ListUsers(w http.ResponseWriter, r *http.Request) { } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -807,22 +809,20 @@ func (a adminAPIHandlers) ListUsers(w http.ResponseWriter, r *http.Request) { allCredentials, err := globalIAMSys.ListUsers() if err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } data, err := json.Marshal(allCredentials) if err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, ErrInternalError, r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } password := globalServerConfig.GetCredential().SecretKey econfigData, err := madmin.EncryptData(password, data) if err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, ErrInternalError, r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -841,7 +841,7 @@ func (a adminAPIHandlers) SetUserStatus(w http.ResponseWriter, r *http.Request) } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -864,8 +864,7 @@ func (a adminAPIHandlers) SetUserStatus(w http.ResponseWriter, r *http.Request) } if err := globalIAMSys.SetUserStatus(accessKey, madmin.AccountStatus(status)); err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } } @@ -882,7 +881,7 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -925,8 +924,7 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { } if err = globalIAMSys.SetUser(accessKey, uinfo); err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } } @@ -943,7 +941,7 @@ func (a adminAPIHandlers) ListCannedPolicies(w http.ResponseWriter, r *http.Requ } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -951,14 +949,12 @@ func (a adminAPIHandlers) ListCannedPolicies(w http.ResponseWriter, r *http.Requ policies, err := globalIAMSys.ListCannedPolicies() if err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } if err = json.NewEncoder(w).Encode(policies); err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -980,7 +976,7 @@ func (a adminAPIHandlers) RemoveCannedPolicy(w http.ResponseWriter, r *http.Requ policyName := vars["name"] // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -993,8 +989,7 @@ func (a adminAPIHandlers) RemoveCannedPolicy(w http.ResponseWriter, r *http.Requ } if err := globalIAMSys.DeleteCannedPolicy(policyName); err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } } @@ -1014,7 +1009,7 @@ func (a adminAPIHandlers) AddCannedPolicy(w http.ResponseWriter, r *http.Request policyName := vars["name"] // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -1051,8 +1046,7 @@ func (a adminAPIHandlers) AddCannedPolicy(w http.ResponseWriter, r *http.Request } if err = globalIAMSys.SetCannedPolicy(policyName, *iamPolicy); err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } } @@ -1073,7 +1067,7 @@ func (a adminAPIHandlers) SetUserPolicy(w http.ResponseWriter, r *http.Request) policyName := vars["name"] // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -1092,8 +1086,7 @@ func (a adminAPIHandlers) SetUserPolicy(w http.ResponseWriter, r *http.Request) } if err := globalIAMSys.SetUserPolicy(accessKey, policyName); err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) } } @@ -1109,7 +1102,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -1172,7 +1165,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques } if err = saveServerConfig(ctx, objectAPI, &config); err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -1214,7 +1207,7 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re } // Validate request signature. - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -1223,15 +1216,14 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re // Load config configStruct, err := readServerConfig(ctx, objectAPI) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } // Convert config to json bytes configBytes, err := json.Marshal(configStruct) if err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -1303,7 +1295,7 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re } if err = saveServerConfig(ctx, objectAPI, &config); err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -1334,7 +1326,7 @@ func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter, } // Authenticate request - adminAPIErr := checkAdminRequestAuthType(r, "") + adminAPIErr := checkAdminRequestAuthType(ctx, r, "") if adminAPIErr != ErrNone { writeErrorResponseJSON(w, adminAPIErr, r.URL) return @@ -1364,7 +1356,7 @@ func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter, creds, err := auth.CreateCredentials(req.AccessKey, req.SecretKey) if err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } @@ -1379,7 +1371,7 @@ func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter, globalActiveCred = creds if err = saveServerConfig(ctx, objectAPI, globalServerConfig); err != nil { - writeErrorResponseJSON(w, toAdminAPIErrCode(err), r.URL) + writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL) return } diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index ba552603b..6dcea33cf 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -867,12 +867,12 @@ func TestToAdminAPIErr(t *testing.T) { // 3. Non-admin API specific error. { err: errDiskNotFound, - expectedAPIErr: toAPIErrorCode(errDiskNotFound), + expectedAPIErr: toAPIErrorCode(context.Background(), errDiskNotFound), }, } for i, test := range testCases { - actualErr := toAdminAPIErrCode(test.err) + actualErr := toAdminAPIErrCode(context.Background(), test.err) if actualErr != test.expectedAPIErr { t.Errorf("Test %d: Expected %v but received %v", i+1, test.expectedAPIErr, actualErr) diff --git a/cmd/admin-heal-ops.go b/cmd/admin-heal-ops.go index e1f3c68ff..86e3b5677 100644 --- a/cmd/admin-heal-ops.go +++ b/cmd/admin-heal-ops.go @@ -62,8 +62,8 @@ var ( errHealPushStopNDiscard = fmt.Errorf("heal push stopped due to heal stop signal") errHealStopSignalled = fmt.Errorf("heal stop signaled") - errFnHealFromAPIErr = func(err error) error { - errCode := toAPIErrorCode(err) + errFnHealFromAPIErr = func(ctx context.Context, err error) error { + errCode := toAPIErrorCode(ctx, err) apiErr := getAPIError(errCode) return fmt.Errorf("Heal internal error: %s: %s", apiErr.Code, apiErr.Description) @@ -150,7 +150,7 @@ func (ahs *allHealState) stopHealSequence(path string) ([]byte, APIErrorCode) { } b, err := json.Marshal(&hsp) - return b, toAdminAPIErrCode(err) + return b, toAdminAPIErrCode(context.Background(), err) } // LaunchNewHealSequence - launches a background routine that performs @@ -254,7 +254,7 @@ func (ahs *allHealState) LaunchNewHealSequence(h *healSequence) ( StartTime: h.startTime, }) if err != nil { - logger.LogIf(context.Background(), err) + logger.LogIf(h.ctx, err) return nil, ErrInternalError, "" } return b, ErrNone, "" @@ -302,7 +302,7 @@ func (ahs *allHealState) PopHealStatusJSON(path string, jbytes, err := json.Marshal(h.currentStatus) if err != nil { - logger.LogIf(context.Background(), err) + logger.LogIf(h.ctx, err) return nil, ErrInternalError } @@ -592,7 +592,7 @@ func (h *healSequence) healConfig() error { objectInfos, err := objectAPI.ListObjectsHeal(h.ctx, minioMetaBucket, minioConfigPrefix, marker, "", 1000) if err != nil { - return errFnHealFromAPIErr(err) + return errFnHealFromAPIErr(h.ctx, err) } for index := range objectInfos.Objects { @@ -639,7 +639,7 @@ func (h *healSequence) healDiskFormat() error { // return any error, ignore error returned when disks have // already healed. if err != nil && err != errNoHealRequired { - return errFnHealFromAPIErr(err) + return errFnHealFromAPIErr(h.ctx, err) } // Healing succeeded notify the peers to reload format and re-initialize disks. @@ -671,7 +671,7 @@ func (h *healSequence) healBuckets() error { buckets, err := objectAPI.ListBucketsHeal(h.ctx) if err != nil { - return errFnHealFromAPIErr(err) + return errFnHealFromAPIErr(h.ctx, err) } for _, bucket := range buckets { @@ -738,7 +738,7 @@ func (h *healSequence) healBucket(bucket string) error { objectInfos, err := objectAPI.ListObjectsHeal(h.ctx, bucket, h.objPrefix, marker, "", entries) if err != nil { - return errFnHealFromAPIErr(err) + return errFnHealFromAPIErr(h.ctx, err) } g := errgroup.WithNErrs(len(objectInfos.Objects)) diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 85bb51f40..97b7b7fe4 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -23,6 +23,7 @@ import ( "net/http" "github.com/minio/minio/cmd/crypto" + "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/dns" "github.com/minio/minio/pkg/event" @@ -1440,7 +1441,7 @@ var errorCodeResponse = map[APIErrorCode]APIError{ // toAPIErrorCode - Converts embedded errors. Convenience // function written to handle all cases where we have known types of // errors returned by underlying layers. -func toAPIErrorCode(err error) (apiErr APIErrorCode) { +func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) { if err == nil { return ErrNone } @@ -1767,6 +1768,10 @@ func toAPIErrorCode(err error) (apiErr APIErrorCode) { apiErr = ErrObjectTampered default: apiErr = ErrInternalError + // Make sure to log the errors which we cannot translate + // to a meaningful S3 API errors. This is added to aid in + // debugging unexpected/unhandled errors. + logger.LogIf(ctx, err) } return apiErr diff --git a/cmd/api-errors_test.go b/cmd/api-errors_test.go index 723580f0f..e2bfd283d 100644 --- a/cmd/api-errors_test.go +++ b/cmd/api-errors_test.go @@ -17,6 +17,7 @@ package cmd import ( + "context" "errors" "testing" @@ -64,8 +65,9 @@ var toAPIErrorCodeTests = []struct { } func TestAPIErrCode(t *testing.T) { + ctx := context.Background() for i, testCase := range toAPIErrorCodeTests { - errCode := toAPIErrorCode(testCase.err) + errCode := toAPIErrorCode(ctx, testCase.err) if errCode != testCase.errCode { t.Errorf("Test %d: Expected error code %d, got %d", i+1, testCase.errCode, errCode) } diff --git a/cmd/api-response-multipart.go b/cmd/api-response-multipart.go index d5e8212cc..dcb25273a 100644 --- a/cmd/api-response-multipart.go +++ b/cmd/api-response-multipart.go @@ -16,7 +16,10 @@ package cmd -import "net/http" +import ( + "context" + "net/http" +) // Represents additional fields necessary for ErrPartTooSmall S3 error. type completeMultipartAPIError struct { @@ -42,7 +45,7 @@ type completeMultipartAPIError struct { // of this function. func writePartSmallErrorResponse(w http.ResponseWriter, r *http.Request, err PartTooSmall) { - apiError := getAPIError(toAPIErrorCode(err)) + apiError := getAPIError(toAPIErrorCode(context.Background(), err)) // Generate complete multipart error response. errorResponse := getAPIErrorResponse(apiError, r.URL.Path, w.Header().Get(responseRequestIDKey)) cmpErrResp := completeMultipartAPIError{err.PartSize, int64(5242880), err.PartNumber, err.PartETag, errorResponse} diff --git a/cmd/auth-handler.go b/cmd/auth-handler.go index 4440231a2..27b2fea39 100644 --- a/cmd/auth-handler.go +++ b/cmd/auth-handler.go @@ -119,7 +119,7 @@ func getRequestAuthType(r *http.Request) authType { // checkAdminRequestAuthType checks whether the request is a valid signature V2 or V4 request. // It does not accept presigned or JWT or anonymous requests. -func checkAdminRequestAuthType(r *http.Request, region string) APIErrorCode { +func checkAdminRequestAuthType(ctx context.Context, r *http.Request, region string) APIErrorCode { s3Err := ErrAccessDenied if _, ok := r.Header["X-Amz-Content-Sha256"]; ok && getRequestAuthType(r) == authTypeSigned && !skipContentSha256Cksum(r) { @@ -136,11 +136,11 @@ func checkAdminRequestAuthType(r *http.Request, region string) APIErrorCode { } // we only support V4 (no presign) with auth body - s3Err = isReqAuthenticated(r, region) + s3Err = isReqAuthenticated(ctx, r, region) } if s3Err != ErrNone { reqInfo := (&logger.ReqInfo{}).AppendTags("requestHeaders", dumpRequest(r)) - ctx := logger.SetReqInfo(context.Background(), reqInfo) + ctx := logger.SetReqInfo(ctx, reqInfo) logger.LogIf(ctx, errors.New(getAPIError(s3Err).Description)) } return s3Err @@ -194,10 +194,10 @@ func getClaimsFromToken(r *http.Request, cred auth.Credentials) (map[string]inte p := &jwtgo.Parser{} jtoken, err := p.ParseWithClaims(token, jwtgo.MapClaims(claims), stsTokenCallback) if err != nil { - return nil, toAPIErrorCode(errAuthentication) + return nil, toAPIErrorCode(context.Background(), errAuthentication) } if !jtoken.Valid { - return nil, toAPIErrorCode(errAuthentication) + return nil, toAPIErrorCode(context.Background(), errAuthentication) } return claims, ErrNone } @@ -224,7 +224,7 @@ func checkRequestAuthType(ctx context.Context, r *http.Request, action policy.Ac case policy.GetBucketLocationAction, policy.ListAllMyBucketsAction: region = "" } - if s3Err = isReqAuthenticated(r, region); s3Err != ErrNone { + if s3Err = isReqAuthenticated(ctx, r, region); s3Err != ErrNone { return s3Err } cred, owner, s3Err = getReqAccessKeyV4(r, region) @@ -310,7 +310,7 @@ func reqSignatureV4Verify(r *http.Request, region string) (s3Error APIErrorCode) } // Verify if request has valid AWS Signature Version '4'. -func isReqAuthenticated(r *http.Request, region string) (s3Error APIErrorCode) { +func isReqAuthenticated(ctx context.Context, r *http.Request, region string) (s3Error APIErrorCode) { if errCode := reqSignatureV4Verify(r, region); errCode != ErrNone { return errCode } @@ -347,7 +347,7 @@ func isReqAuthenticated(r *http.Request, region string) (s3Error APIErrorCode) { // The verification happens implicit during reading. reader, err := hash.NewReader(r.Body, -1, hex.EncodeToString(contentMD5), hex.EncodeToString(contentSHA256), -1) if err != nil { - return toAPIErrorCode(err) + return toAPIErrorCode(ctx, err) } r.Body = ioutil.NopCloser(reader) return ErrNone diff --git a/cmd/auth-handler_test.go b/cmd/auth-handler_test.go index 7a15fb3fd..a2dc0cec8 100644 --- a/cmd/auth-handler_test.go +++ b/cmd/auth-handler_test.go @@ -18,6 +18,7 @@ package cmd import ( "bytes" + "context" "io" "io/ioutil" "net/http" @@ -377,11 +378,12 @@ func TestIsReqAuthenticated(t *testing.T) { {mustNewSignedRequest("GET", "http://127.0.0.1:9000", 0, nil, t), ErrNone}, } + ctx := context.Background() // Validates all testcases. for i, testCase := range testCases { - if s3Error := isReqAuthenticated(testCase.req, globalServerConfig.GetRegion()); s3Error != testCase.s3Error { - if _, err := ioutil.ReadAll(testCase.req.Body); toAPIErrorCode(err) != testCase.s3Error { - t.Fatalf("Test %d: Unexpected S3 error: want %d - got %d (got after reading request %d)", i, testCase.s3Error, s3Error, toAPIErrorCode(err)) + if s3Error := isReqAuthenticated(ctx, testCase.req, globalServerConfig.GetRegion()); s3Error != testCase.s3Error { + if _, err := ioutil.ReadAll(testCase.req.Body); toAPIErrorCode(ctx, err) != testCase.s3Error { + t.Fatalf("Test %d: Unexpected S3 error: want %d - got %d (got after reading request %d)", i, testCase.s3Error, s3Error, toAPIErrorCode(ctx, err)) } } } @@ -413,8 +415,9 @@ func TestCheckAdminRequestAuthType(t *testing.T) { {Request: mustNewPresignedV2Request("GET", "http://127.0.0.1:9000", 0, nil, t), ErrCode: ErrAccessDenied}, {Request: mustNewPresignedRequest("GET", "http://127.0.0.1:9000", 0, nil, t), ErrCode: ErrAccessDenied}, } + ctx := context.Background() for i, testCase := range testCases { - if s3Error := checkAdminRequestAuthType(testCase.Request, globalServerConfig.GetRegion()); s3Error != testCase.ErrCode { + if s3Error := checkAdminRequestAuthType(ctx, testCase.Request, globalServerConfig.GetRegion()); s3Error != testCase.ErrCode { t.Errorf("Test %d: Unexpected s3error returned wanted %d, got %d", i, testCase.ErrCode, s3Error) } } diff --git a/cmd/bucket-handlers-listobjects.go b/cmd/bucket-handlers-listobjects.go index 6ce1c142e..17aa87007 100644 --- a/cmd/bucket-handlers-listobjects.go +++ b/cmd/bucket-handlers-listobjects.go @@ -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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -118,7 +118,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http } else if crypto.IsEncrypted(listObjectsV2Info.Objects[i].UserDefined) { listObjectsV2Info.Objects[i].Size, err = listObjectsV2Info.Objects[i].DecryptedSize() if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -182,7 +182,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -200,7 +200,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http } else if crypto.IsEncrypted(listObjectsInfo.Objects[i].UserDefined) { listObjectsInfo.Objects[i].Size, err = listObjectsInfo.Objects[i].DecryptedSize() if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 6320524a5..2b60e39ed 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -174,7 +174,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, listMultipartsInfo, err := objectAPI.ListMultipartUploads(ctx, bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploads) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } // generate response @@ -214,7 +214,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } bucketSet := set.NewStringSet() @@ -233,7 +233,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R var err error bucketsInfo, err = listBuckets(ctx) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -354,8 +354,8 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, } // Error during delete should be collected separately. deleteErrors = append(deleteErrors, DeleteError{ - Code: errorCodeResponse[toAPIErrorCode(err)].Code, - Message: errorCodeResponse[toAPIErrorCode(err)].Description, + Code: errorCodeResponse[toAPIErrorCode(ctx, err)].Code, + Message: errorCodeResponse[toAPIErrorCode(ctx, err)].Description, Key: object.ObjectName, }) } @@ -432,12 +432,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } if err = globalDNSConfig.Put(bucket); err != nil { objectAPI.DeleteBucket(ctx, bucket) - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -447,7 +447,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req writeSuccessResponseHeadersOnly(w) return } - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -458,7 +458,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req // Proceed to creating a bucket. err := objectAPI.MakeBucketWithLocation(ctx, bucket, location) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -589,12 +589,12 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h lengthRange := postPolicyForm.Conditions.ContentLengthRange if lengthRange.Valid { if fileSize < lengthRange.Min { - writeErrorResponse(w, toAPIErrorCode(errDataTooSmall), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, errDataTooSmall), r.URL) return } if fileSize > lengthRange.Max || isMaxObjectSize(fileSize) { - writeErrorResponse(w, toAPIErrorCode(errDataTooLarge), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, errDataTooLarge), r.URL) return } } @@ -610,7 +610,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h hashReader, err := hash.NewReader(fileBody, fileSize, "", "", fileSize) if err != nil { logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -621,19 +621,19 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h if crypto.SSEC.IsRequested(formValues) { key, err = ParseSSECustomerHeader(formValues) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } reader, err = newEncryptReader(hashReader, key, bucket, object, metadata, crypto.S3.IsRequested(formValues)) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) 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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -641,7 +641,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h objInfo, err := objectAPI.PutObject(ctx, bucket, object, hashReader, metadata, ObjectOptions{}) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -721,7 +721,7 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re getBucketInfo = api.CacheAPI().GetBucketInfo } if _, err := getBucketInfo(ctx, bucket); err != nil { - writeErrorResponseHeadersOnly(w, toAPIErrorCode(err)) + writeErrorResponseHeadersOnly(w, toAPIErrorCode(ctx, err)) return } @@ -754,7 +754,7 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http. } // Attempt to delete bucket. if err := deleteBucket(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -766,7 +766,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } diff --git a/cmd/bucket-notification-handlers.go b/cmd/bucket-notification-handlers.go index d54f0fc8c..4fbec0312 100644 --- a/cmd/bucket-notification-handlers.go +++ b/cmd/bucket-notification-handlers.go @@ -67,7 +67,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, _, err := objAPI.GetBucketInfo(ctx, bucketName) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) 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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -90,8 +90,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, notificationBytes, err := xml.Marshal(nConfig) if err != nil { - logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -126,7 +125,7 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, _, err := objectAPI.GetBucketInfo(ctx, bucketName) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -141,7 +140,7 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, if err != nil { apiErr := ErrMalformedXML if event.IsEventError(err) { - apiErr = toAPIErrorCode(err) + apiErr = toAPIErrorCode(ctx, err) } writeErrorResponse(w, apiErr, r.URL) @@ -149,7 +148,7 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, } if err = saveNotificationConfig(ctx, objectAPI, bucketName, config); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -194,7 +193,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit } if len(values["prefix"]) == 1 { if err := event.ValidateFilterRuleValue(values["prefix"][0]); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -207,7 +206,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit } if len(values["suffix"]) == 1 { if err := event.ValidateFilterRuleValue(values["suffix"][0]); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -220,7 +219,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit for _, s := range values["events"] { eventName, err := event.ParseName(s) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -228,19 +227,19 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit } if _, err := objAPI.GetBucketInfo(ctx, bucketName); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } host, err := xnet.ParseHost(r.RemoteAddr) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } target, err := target.NewHTTPClientTarget(*host, w) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -248,8 +247,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) - logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } defer globalNotificationSys.RemoveRemoteTarget(bucketName, target.ID()) @@ -257,14 +255,13 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit thisAddr, err := xnet.ParseHost(GetLocalPeer(globalEndpoints)) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } if err = SaveListener(objAPI, bucketName, eventNames, pattern, target.ID(), *thisAddr); err != nil { logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name) - logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -274,8 +271,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) - logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } diff --git a/cmd/bucket-policy-handlers.go b/cmd/bucket-policy-handlers.go index 117963fdb..06fc83f6a 100644 --- a/cmd/bucket-policy-handlers.go +++ b/cmd/bucket-policy-handlers.go @@ -58,7 +58,7 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht // Check if bucket exists. if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -88,7 +88,7 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht } if err = objAPI.SetBucketPolicy(ctx, bucket, bucketPolicy); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -121,12 +121,12 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r // Check if bucket exists. if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } if err := objAPI.DeleteBucketPolicy(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -159,21 +159,20 @@ func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *ht // Check if bucket exists. if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } // Read bucket access policy. bucketPolicy, err := objAPI.GetBucketPolicy(ctx, bucket) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } policyData, err := json.Marshal(bucketPolicy) if err != nil { - logger.LogIf(ctx, err) - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } diff --git a/cmd/encryption-v1.go b/cmd/encryption-v1.go index c3e5604be..050b6b27b 100644 --- a/cmd/encryption-v1.go +++ b/cmd/encryption-v1.go @@ -1062,7 +1062,7 @@ func DecryptCopyObjectInfo(info *ObjectInfo, headers http.Header) (apiErr APIErr } var err error if info.Size, err = info.DecryptedSize(); err != nil { - apiErr = toAPIErrorCode(err) + apiErr = toAPIErrorCode(context.Background(), err) } } return diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index f07df2d65..650dc4ac3 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -655,7 +655,7 @@ func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques if err == dns.ErrNoEntriesFound { writeErrorResponse(w, ErrNoSuchBucket, r.URL) } else { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(context.Background(), err), r.URL) } return } diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 0fc8f02e1..cf251034d 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -124,7 +124,7 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r } _, err := getObjectInfo(ctx, bucket, object, ObjectOptions{}) - if toAPIErrorCode(err) == ErrNoSuchKey { + if toAPIErrorCode(ctx, err) == ErrNoSuchKey { s3Error = ErrNoSuchKey } } @@ -166,7 +166,7 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r gr, err := getObjectNInfo(ctx, bucket, object, nil, r.Header, readLock, ObjectOptions{}) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } defer gr.Close() @@ -257,14 +257,14 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r s3s, err := s3select.New(reader, objInfo.GetActualSize(), selectReq) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } // Parses the select query and checks for an error _, _, _, _, _, _, err = s3select.ParseSelect(s3s) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -343,7 +343,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req } _, err := getObjectInfo(ctx, bucket, object, opts) - if toAPIErrorCode(err) == ErrNoSuchKey { + if toAPIErrorCode(ctx, err) == ErrNoSuchKey { s3Error = ErrNoSuchKey } } @@ -377,7 +377,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } defer gr.Close() @@ -386,7 +386,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req if objectAPI.IsEncryptionSupported() { if _, err = DecryptObjectInfo(objInfo, r.Header); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -409,8 +409,8 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req } } - if hErr := setObjectHeaders(w, objInfo, rs); hErr != nil { - writeErrorResponse(w, toAPIErrorCode(hErr), r.URL) + if err = setObjectHeaders(w, objInfo, rs); err != nil { + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -426,14 +426,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) } 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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -507,7 +507,7 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re IsOwner: false, }) { _, err := getObjectInfo(ctx, bucket, object, opts) - if toAPIErrorCode(err) == ErrNoSuchKey { + if toAPIErrorCode(ctx, err) == ErrNoSuchKey { s3Error = ErrNoSuchKey } } @@ -536,13 +536,13 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re objInfo, err := getObjectInfo(ctx, bucket, object, opts) if err != nil { - writeErrorResponseHeadersOnly(w, toAPIErrorCode(err)) + writeErrorResponseHeadersOnly(w, toAPIErrorCode(ctx, err)) return } if objectAPI.IsEncryptionSupported() { if _, err = DecryptObjectInfo(objInfo, r.Header); err != nil { - writeErrorResponseHeadersOnly(w, toAPIErrorCode(err)) + writeErrorResponseHeadersOnly(w, toAPIErrorCode(ctx, err)) return } } @@ -556,7 +556,7 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re case crypto.SSEC.IsEncrypted(objInfo.UserDefined): // Validate the SSE-C Key set in the header. if _, err = crypto.SSEC.UnsealObjectKey(r.Header, objInfo.UserDefined, bucket, object); err != nil { - writeErrorResponseHeadersOnly(w, toAPIErrorCode(err)) + writeErrorResponseHeadersOnly(w, toAPIErrorCode(ctx, err)) return } w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm)) @@ -571,8 +571,8 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re } // Set standard object headers. - if hErr := setObjectHeaders(w, objInfo, rs); hErr != nil { - writeErrorResponseHeadersOnly(w, toAPIErrorCode(hErr)) + if err = setObjectHeaders(w, objInfo, rs); err != nil { + writeErrorResponseHeadersOnly(w, toAPIErrorCode(ctx, err)) return } @@ -716,7 +716,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re var rs *HTTPRangeSpec gr, err := getObjectNInfo(ctx, srcBucket, srcObject, rs, r.Header, lock, srcOpts) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } defer gr.Close() @@ -758,7 +758,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -797,7 +797,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re srcInfo.Reader, err = hash.NewReader(reader, length, "", "", actualSize) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -805,7 +805,7 @@ 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, toAPIErrorCode(errInvalidEncryptionParameters), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, errInvalidEncryptionParameters), r.URL) return } // Encryption parameters not present for this object. @@ -825,7 +825,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if sseC { newKey, err = ParseSSECustomerRequest(r) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -838,7 +838,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -848,7 +848,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -880,7 +880,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re if isTargetEncrypted { reader, err = newEncryptReader(reader, newKey, dstBucket, dstObject, encMetadata, sseS3) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -893,7 +893,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -966,7 +966,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -1059,7 +1059,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req } size, err = strconv.ParseInt(sizeStr[0], 10, 64) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -1154,7 +1154,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1174,7 +1174,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } opts := ObjectOptions{} @@ -1190,13 +1190,13 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req if hasServerSideEncryptionHeader(r.Header) && !hasSuffix(object, slashSeparator) { // handle SSE requests reader, err = EncryptRequest(hashReader, r, bucket, object, metadata) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) 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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -1212,7 +1212,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Create the object.. objInfo, err := putObject(ctx, bucket, object, hashReader, metadata, opts) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1309,7 +1309,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } // Set this for multipart only operations, we need to differentiate during @@ -1345,7 +1345,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r } uploadID, err := newMultipartUpload(ctx, bucket, object, metadata, opts) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1447,7 +1447,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt gr, err := getObjectNInfo(ctx, srcBucket, srcObject, rs, r.Header, readLock, srcOpts) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } defer gr.Close() @@ -1457,7 +1457,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt if crypto.IsEncrypted(srcInfo.UserDefined) { actualPartSize, err = srcInfo.DecryptedSize() if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -1476,7 +1476,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt // Get the object offset & length startOffset, length, err := rs.GetOffsetLength(actualPartSize) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1492,7 +1492,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt var li ListPartsInfo li, err = objectAPI.ListObjectParts(ctx, dstBucket, dstObject, uploadID, 0, 1) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1522,7 +1522,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt srcInfo.Reader, err = hash.NewReader(reader, length, "", "", actualPartSize) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1540,14 +1540,14 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt if crypto.SSEC.IsRequested(r.Header) { key, err = ParseSSECustomerRequest(r) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } var objectEncryptionKey []byte objectEncryptionKey, err = decryptObjectInfo(key, dstBucket, dstObject, li.UserDefined) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1559,14 +1559,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } info := ObjectInfo{Size: length} srcInfo.Reader, err = hash.NewReader(reader, info.EncryptedSize(), "", "", length) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -1577,7 +1577,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1634,7 +1634,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http } size, err = strconv.ParseInt(sizeStr[0], 10, 64) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -1709,7 +1709,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http var li ListPartsInfo li, err = objectAPI.ListObjectParts(ctx, bucket, object, uploadID, 0, 1) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } // Read compression metadata preserved in the init multipart for the decision. @@ -1723,7 +1723,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1744,7 +1744,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http hashReader, err := hash.NewReader(reader, size, md5hex, sha256hex, actualSize) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1762,7 +1762,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http var li ListPartsInfo li, err = objectAPI.ListObjectParts(ctx, bucket, object, uploadID, 0, 1) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } if crypto.IsEncrypted(li.UserDefined) { @@ -1775,7 +1775,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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -1784,7 +1784,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http var objectEncryptionKey []byte objectEncryptionKey, err = decryptObjectInfo(key, bucket, object, li.UserDefined) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1797,14 +1797,14 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http reader, err = sio.EncryptReader(hashReader, sio.Config{Key: partEncryptionKey}) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) 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, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } } @@ -1817,7 +1817,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http partInfo, err := putObjectPart(ctx, bucket, object, uploadID, partID, hashReader, opts) if err != nil { // Verify if the underlying error is signature mismatch. - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } if isCompressed { @@ -1871,7 +1871,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, return } if err := abortMultipartUpload(ctx, bucket, object, uploadID); err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } @@ -1914,7 +1914,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht } listPartsInfo, err := objectAPI.ListObjectParts(ctx, bucket, object, uploadID, partNumberMarker, maxParts) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) return } response := generateListPartsResponse(listPartsInfo) @@ -2003,7 +2003,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite writePartSmallErrorResponse(w, r, oErr) default: // Handle all other generic issues. - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) } return } @@ -2080,7 +2080,7 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. if err == dns.ErrNoEntriesFound { writeErrorResponse(w, ErrNoSuchBucket, r.URL) } else { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL) } return } @@ -2088,7 +2088,7 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. // http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html if err := deleteObject(ctx, objectAPI, api.CacheAPI(), bucket, object, r); err != nil { - switch toAPIErrorCode(err) { + switch toAPIErrorCode(ctx, err) { case ErrNoSuchBucket: // When bucket doesn't exist specially handle it. writeErrorResponse(w, ErrNoSuchBucket, r.URL) diff --git a/cmd/object-handlers_test.go b/cmd/object-handlers_test.go index 29f2625a8..4d7bc2307 100644 --- a/cmd/object-handlers_test.go +++ b/cmd/object-handlers_test.go @@ -2533,6 +2533,8 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s successResponse := generateCompleteMultpartUploadResponse(bucketName, objectName, getGetObjectURL("", bucketName, objectName), s3MD5) encodedSuccessResponse := encodeResponse(successResponse) + ctx := context.Background() + testCases := []struct { bucket string object string @@ -2555,7 +2557,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidPart{})), + expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(ctx, InvalidPart{})), getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusBadRequest, }, @@ -2585,7 +2587,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidUploadID{UploadID: "abc"})), + expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(ctx, InvalidUploadID{UploadID: "abc"})), getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusNotFound, }, @@ -2600,7 +2602,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s secretKey: credentials.SecretKey, expectedContent: encodeResponse(completeMultipartAPIError{int64(4), int64(5242880), 1, "e2fc714c4727ee9395f324cd2e7f331f", - getAPIErrorResponse(getAPIError(toAPIErrorCode(PartTooSmall{PartNumber: 1})), + getAPIErrorResponse(getAPIError(toAPIErrorCode(ctx, PartTooSmall{PartNumber: 1})), getGetObjectURL("", bucketName, objectName), "")}), expectedRespStatus: http.StatusBadRequest, }, @@ -2614,7 +2616,7 @@ func testAPICompleteMultipartHandler(obj ObjectLayer, instanceType, bucketName s accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(InvalidPart{})), + expectedContent: encodeResponse(getAPIErrorResponse(getAPIError(toAPIErrorCode(ctx, InvalidPart{})), getGetObjectURL("", bucketName, objectName), "")), expectedRespStatus: http.StatusBadRequest, }, diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index 7525b3d30..b360b3925 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -2354,8 +2354,9 @@ func TestToErrIsNil(t *testing.T) { if toStorageErr(nil) != nil { t.Errorf("Test expected to return nil, failed instead got a non-nil value %s", toStorageErr(nil)) } - if toAPIErrorCode(nil) != ErrNone { - t.Errorf("Test expected error code to be ErrNone, failed instead provided %d", toAPIErrorCode(nil)) + ctx := context.Background() + if toAPIErrorCode(ctx, nil) != ErrNone { + t.Errorf("Test expected error code to be ErrNone, failed instead provided %d", toAPIErrorCode(ctx, nil)) } }