From 4917038f5532d28ad3dab1876ca490acd0820698 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 10 Aug 2016 18:47:49 -0700 Subject: [PATCH] Move the ObjectAPI() resource to be beginning of each handlers. We should return back proper errors so that the clients can retry until server has been initialized. --- cmd/api-errors.go | 6 ++ cmd/bucket-handlers-listobjects.go | 22 +++--- cmd/bucket-handlers.go | 88 +++++++++++++--------- cmd/bucket-notification-handlers.go | 36 ++++----- cmd/bucket-policy-handlers.go | 24 +++++- cmd/object-handlers.go | 113 +++++++++++++++------------- 6 files changed, 171 insertions(+), 118 deletions(-) diff --git a/cmd/api-errors.go b/cmd/api-errors.go index ca8800e20..760dba2a7 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -134,6 +134,7 @@ const ( ErrObjectExistsAsDirectory ErrPolicyNesting ErrInvalidObjectName + ErrServerNotInitialized // Add new extended error codes here. // Please open a https://github.com/minio/minio/issues before adding // new error codes here. @@ -556,6 +557,11 @@ var errorCodeResponse = map[APIErrorCode]APIError{ Description: "Object name contains unsupported characters. Unsupported characters are `^*|\\\"", HTTPStatusCode: http.StatusBadRequest, }, + ErrServerNotInitialized: { + Code: "XMinioServerNotInitialized", + Description: "Server not initialized, please try again.", + HTTPStatusCode: http.StatusServiceUnavailable, + }, // Add your error structure here. } diff --git a/cmd/bucket-handlers-listobjects.go b/cmd/bucket-handlers-listobjects.go index f0b80f3ac..8e9dcd4ee 100644 --- a/cmd/bucket-handlers-listobjects.go +++ b/cmd/bucket-handlers-listobjects.go @@ -64,6 +64,12 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http vars := mux.Vars(r) bucket := vars["bucket"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -97,11 +103,6 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http writeErrorResponse(w, r, s3Error, r.URL.Path) return } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } // Inititate a list objects operation based on the input params. // On success would return back ListObjectsInfo object to be // marshalled into S3 compatible XML header. @@ -129,6 +130,12 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http vars := mux.Vars(r) bucket := vars["bucket"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -156,11 +163,6 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http return } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } // Inititate a list objects operation based on the input params. // On success would return back ListObjectsInfo object to be // marshalled into S3 compatible XML header. diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 0125e5e08..d8bc8d7a2 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -64,6 +64,12 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r * vars := mux.Vars(r) bucket := vars["bucket"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -82,11 +88,6 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r * } } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } if _, err := objectAPI.GetBucketInfo(bucket); err != nil { errorIf(err, "Unable to fetch bucket info.") writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path) @@ -118,6 +119,12 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, vars := mux.Vars(r) bucket := vars["bucket"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -149,11 +156,6 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, } } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } listMultipartsInfo, err := objectAPI.ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploads) if err != nil { errorIf(err, "Unable to list multipart uploads.") @@ -174,17 +176,19 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, // This implementation of the GET operation returns a list of all buckets // owned by the authenticated sender of the request. func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.Request) { + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // List buckets does not support bucket policies, no need to enforce it. if s3Error := checkAuth(r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } + // Invoke the list buckets. bucketsInfo, err := objectAPI.ListBuckets() if err != nil { errorIf(err, "Unable to list buckets.") @@ -206,6 +210,12 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, vars := mux.Vars(r) bucket := vars["bucket"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -332,6 +342,12 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, // ---------- // This implementation of the PUT operation creates a new bucket for authenticated request func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Request) { + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // PutBucket does not support policies, use checkAuth to validate signature. if s3Error := checkAuth(r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) @@ -348,11 +364,6 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req return } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } // Proceed to creating a bucket. err := objectAPI.MakeBucket(bucket) if err != nil { @@ -370,6 +381,12 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req // This implementation of the POST operation handles object creation with a specified // signature policy in multipart/form-data func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Request) { + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // Here the parameter is the size of the form data that should // be loaded in memory, the remaining being put in temporary files. reader, err := r.MultipartReader() @@ -410,11 +427,6 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h metadata := make(map[string]string) // Nothing to store right now. - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } md5Sum, err := objectAPI.PutObject(bucket, object, -1, fileBody, metadata) if err != nil { errorIf(err, "Unable to create object.") @@ -464,6 +476,12 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re vars := mux.Vars(r) bucket := vars["bucket"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -482,11 +500,6 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re } } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } if _, err := objectAPI.GetBucketInfo(bucket); err != nil { errorIf(err, "Unable to fetch bucket info.") writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path) @@ -497,6 +510,12 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re // DeleteBucketHandler - Delete bucket func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // DeleteBucket does not support bucket policies, use checkAuth to validate signature. if s3Error := checkAuth(r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) @@ -506,11 +525,6 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http. vars := mux.Vars(r) bucket := vars["bucket"] - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } // Attempt to delete bucket. if err := objectAPI.DeleteBucket(bucket); err != nil { errorIf(err, "Unable to delete a bucket.") @@ -519,10 +533,10 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http. } // Delete bucket access policy, if present - ignore any errors. - removeBucketPolicy(bucket, api.ObjectAPI) + removeBucketPolicy(bucket, objectAPI) // Delete notification config, if present - ignore any errors. - removeNotificationConfig(bucket, api.ObjectAPI) + removeNotificationConfig(bucket, objectAPI) // Write success response. writeSuccessNoContent(w) diff --git a/cmd/bucket-notification-handlers.go b/cmd/bucket-notification-handlers.go index 7d4c53da7..7dce07ba1 100644 --- a/cmd/bucket-notification-handlers.go +++ b/cmd/bucket-notification-handlers.go @@ -39,6 +39,12 @@ const ( // not enabled on the bucket, the operation returns an empty // NotificationConfiguration element. func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // Validate request authorization. if s3Error := checkAuth(r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) @@ -47,11 +53,6 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, vars := mux.Vars(r) bucket := vars["bucket"] // Attempt to successfully load notification config. - objAPI := api.ObjectAPI() - if objAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } nConfig, err := loadNotificationConfig(bucket, objAPI) if err != nil && err != errNoSuchNotifications { errorIf(err, "Unable to read notification configuration.") @@ -83,6 +84,12 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, // By default, your bucket has no event notifications configured. That is, // the notification configuration will be an empty NotificationConfiguration. func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // Validate request authorization. if s3Error := checkAuth(r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) @@ -91,11 +98,6 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, vars := mux.Vars(r) bucket := vars["bucket"] - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } _, err := objectAPI.GetBucketInfo(bucket) if err != nil { errorIf(err, "Unable to find bucket info.") @@ -214,6 +216,13 @@ func sendBucketNotification(w http.ResponseWriter, arnListenerCh <-chan []Notifi // ListenBucketNotificationHandler - list bucket notifications. func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { + // Validate if bucket exists. + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // Validate request authorization. if s3Error := checkAuth(r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) @@ -229,13 +238,6 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit return } - // Validate if bucket exists. - objAPI := api.ObjectAPI() - if objAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } - _, err := objAPI.GetBucketInfo(bucket) if err != nil { errorIf(err, "Unable to bucket info.") diff --git a/cmd/bucket-policy-handlers.go b/cmd/bucket-policy-handlers.go index 5cb206115..161e25eed 100644 --- a/cmd/bucket-policy-handlers.go +++ b/cmd/bucket-policy-handlers.go @@ -126,6 +126,12 @@ func bucketPolicyConditionMatch(conditions map[string]set.StringSet, statement p // This implementation of the PUT operation uses the policy // subresource to add to or replace a policy on a bucket func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + vars := mux.Vars(r) bucket := vars["bucket"] switch getRequestAuthType(r) { @@ -180,7 +186,7 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht } // Save bucket policy. - if err = writeBucketPolicy(bucket, api.ObjectAPI, bytes.NewReader(policyBytes), int64(len(policyBytes))); err != nil { + if err = writeBucketPolicy(bucket, objAPI, bytes.NewReader(policyBytes), int64(len(policyBytes))); err != nil { errorIf(err, "Unable to write bucket policy.") switch err.(type) { case BucketNameInvalid: @@ -203,6 +209,12 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht // This implementation of the DELETE operation uses the policy // subresource to add to remove a policy on a bucket. func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + vars := mux.Vars(r) bucket := vars["bucket"] @@ -219,7 +231,7 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r } // Delete bucket access policy. - if err := removeBucketPolicy(bucket, api.ObjectAPI); err != nil { + if err := removeBucketPolicy(bucket, objAPI); err != nil { errorIf(err, "Unable to remove bucket policy.") switch err.(type) { case BucketNameInvalid: @@ -244,6 +256,12 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r // This operation uses the policy // subresource to return the policy of a specified bucket. func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + vars := mux.Vars(r) bucket := vars["bucket"] @@ -260,7 +278,7 @@ func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *ht } // Read bucket access policy. - policy, err := readBucketPolicy(bucket, api.ObjectAPI) + policy, err := readBucketPolicy(bucket, objAPI) if err != nil { errorIf(err, "Unable to read bucket policy.") switch err.(type) { diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index d99f4e870..979331882 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -84,6 +84,13 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req bucket = vars["bucket"] object = vars["object"] + // Fetch object stat info. + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -101,12 +108,6 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req return } } - // Fetch object stat info. - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } objInfo, err := objectAPI.GetObjectInfo(bucket, object) if err != nil { errorIf(err, "Unable to fetch object info.") @@ -195,6 +196,12 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re bucket = vars["bucket"] object = vars["object"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -213,11 +220,6 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re } } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } objInfo, err := objectAPI.GetObjectInfo(bucket, object) if err != nil { errorIf(err, "Unable to fetch object info.") @@ -250,6 +252,12 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re bucket := vars["bucket"] object := vars["object"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -299,11 +307,6 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re return } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } objInfo, err := objectAPI.GetObjectInfo(sourceBucket, sourceObject) if err != nil { errorIf(err, "Unable to fetch object info.") @@ -389,6 +392,12 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re // ---------- // This implementation of the PUT operation adds an object to a bucket. func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Request) { + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // If the matching failed, it means that the X-Amz-Copy-Source was // wrong, fail right here. if _, ok := r.Header["X-Amz-Copy-Source"]; ok { @@ -433,11 +442,6 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Make sure we hex encode md5sum here. metadata["md5Sum"] = hex.EncodeToString(md5Bytes) - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } var md5Sum string switch rAuthType { default: @@ -505,6 +509,12 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r bucket = vars["bucket"] object = vars["object"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -526,11 +536,6 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r // Extract metadata that needs to be saved. metadata := extractMetadataFromHeader(r.Header) - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } uploadID, err := objectAPI.NewMultipartUpload(bucket, object, metadata) if err != nil { errorIf(err, "Unable to initiate new multipart upload id.") @@ -552,6 +557,12 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http bucket := vars["bucket"] object := vars["object"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // get Content-Md5 sent by client and verify if valid md5Bytes, err := checkValidMD5(r.Header.Get("Content-Md5")) if err != nil { @@ -599,11 +610,6 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http return } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } var partMD5 string incomingMD5 := hex.EncodeToString(md5Bytes) switch rAuthType { @@ -650,6 +656,12 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, bucket := vars["bucket"] object := vars["object"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -668,11 +680,6 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter, } } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } uploadID, _, _, _ := getObjectResources(r.URL.Query()) if err := objectAPI.AbortMultipartUpload(bucket, object, uploadID); err != nil { errorIf(err, "Unable to abort multipart upload.") @@ -688,6 +695,12 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht bucket := vars["bucket"] object := vars["object"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -715,11 +728,6 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht writeErrorResponse(w, r, ErrInvalidMaxParts, r.URL.Path) return } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } listPartsInfo, err := objectAPI.ListObjectParts(bucket, object, uploadID, partNumberMarker, maxParts) if err != nil { errorIf(err, "Unable to list uploaded parts.") @@ -740,6 +748,12 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite bucket := vars["bucket"] object := vars["object"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + // Get upload id. uploadID, _, _, _ := getObjectResources(r.URL.Query()) @@ -801,12 +815,8 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite return } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } doneCh := make(chan struct{}) + // Signal that completeMultipartUpload is over via doneCh go func(doneCh chan<- struct{}) { md5Sum, err = objectAPI.CompleteMultipartUpload(bucket, object, uploadID, completeParts) @@ -870,6 +880,12 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. bucket := vars["bucket"] object := vars["object"] + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, r, ErrServerNotInitialized, r.URL.Path) + return + } + switch getRequestAuthType(r) { default: // For all unknown auth types return error. @@ -887,11 +903,6 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. return } } - objectAPI := api.ObjectAPI() - if objectAPI == nil { - writeErrorResponse(w, r, ErrInternalError, r.URL.Path) - return - } /// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html /// Ignore delete object errors, since we are suppposed to reply /// only 204.