From fdf3d647937e104e13e7e33506cc8ac9febad8a9 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 10 Mar 2016 02:24:52 -0800 Subject: [PATCH] error: Add proper prefixes for s3Error codes. This patch adds 'Err' prefix for all standard API error codes and also adds a proper type for them. --- api-errors.go | 182 +++++++++++++++--------------- api-response.go | 6 +- auth-handler.go | 18 +-- bucket-handlers.go | 182 ++++++++++++++---------------- bucket-policy-handlers.go | 38 +++---- generic-handlers.go | 14 +-- object-handlers.go | 228 +++++++++++++++++++------------------- pkg/fs/fs-bucket_test.go | 6 +- 8 files changed, 334 insertions(+), 340 deletions(-) diff --git a/api-errors.go b/api-errors.go index 05462aa74..4b28ac8bb 100644 --- a/api-errors.go +++ b/api-errors.go @@ -40,269 +40,275 @@ type APIErrorResponse struct { HostID string `xml:"HostId"` } +// APIErrorCode type of error status. +type APIErrorCode int + // Error codes, non exhaustive list - http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html const ( - None = iota - AccessDenied - BadDigest - BucketAlreadyExists - EntityTooSmall - EntityTooLarge - IncompleteBody - InternalError - InvalidAccessKeyID - InvalidBucketName - InvalidDigest - InvalidRange - InvalidMaxKeys - InvalidMaxUploads - InvalidMaxParts - InvalidPartNumberMarker - InvalidRequestBody - InvalidCopySource - InvalidCopyDest - InvalidPolicyDocument - MalformedXML - MissingContentLength - MissingContentMD5 - MissingRequestBodyError - NoSuchBucket - NoSuchBucketPolicy - NoSuchKey - NoSuchUpload - NotImplemented - RequestTimeTooSkewed - SignatureDoesNotMatch - MethodNotAllowed - InvalidPart - InvalidPartOrder - AuthorizationHeaderMalformed - MalformedPOSTRequest - SignatureVersionNotSupported - BucketNotEmpty - RootPathFull - ObjectExistsAsPrefix - AllAccessDisabled - MalformedPolicy + ErrNone APIErrorCode = iota + ErrAccessDenied + ErrBadDigest + ErrBucketAlreadyExists + ErrEntityTooSmall + ErrEntityTooLarge + ErrIncompleteBody + ErrInternalError + ErrInvalidAccessKeyID + ErrInvalidBucketName + ErrInvalidDigest + ErrInvalidRange + ErrInvalidMaxKeys + ErrInvalidMaxUploads + ErrInvalidMaxParts + ErrInvalidPartNumberMarker + ErrInvalidRequestBody + ErrInvalidCopySource + ErrInvalidCopyDest + ErrInvalidPolicyDocument + ErrMalformedXML + ErrMissingContentLength + ErrMissingContentMD5 + ErrMissingRequestBodyError + ErrNoSuchBucket + ErrNoSuchBucketPolicy + ErrNoSuchKey + ErrNoSuchUpload + ErrNotImplemented + ErrRequestTimeTooSkewed + ErrSignatureDoesNotMatch + ErrMethodNotAllowed + ErrInvalidPart + ErrInvalidPartOrder + ErrAuthorizationHeaderMalformed + ErrMalformedPOSTRequest + ErrSignatureVersionNotSupported + ErrBucketNotEmpty + ErrRootPathFull + ErrObjectExistsAsPrefix + ErrAllAccessDisabled + ErrMalformedPolicy + // Add new error codes here. ) -// APIError code to Error structure map -var errorCodeResponse = map[int]APIError{ - InvalidCopyDest: { +// error code to APIError structure, these fields carry respective +// descriptions for all the error responses. +var errorCodeResponse = map[APIErrorCode]APIError{ + ErrInvalidCopyDest: { Code: "InvalidRequest", Description: "This copy request is illegal because it is trying to copy an object to itself.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidCopySource: { + ErrInvalidCopySource: { Code: "InvalidArgument", Description: "Copy Source must mention the source bucket and key: sourcebucket/sourcekey.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidRequestBody: { + ErrInvalidRequestBody: { Code: "InvalidArgument", Description: "Body shouldn't be set for this request.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidMaxUploads: { + ErrInvalidMaxUploads: { Code: "InvalidArgument", Description: "Argument maxUploads must be an integer between 0 and 2147483647.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidMaxKeys: { + ErrInvalidMaxKeys: { Code: "InvalidArgument", Description: "Argument maxKeys must be an integer between 0 and 2147483647.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidMaxParts: { + ErrInvalidMaxParts: { Code: "InvalidArgument", Description: "Argument maxParts must be an integer between 1 and 10000.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidPartNumberMarker: { + ErrInvalidPartNumberMarker: { Code: "InvalidArgument", Description: "Argument partNumberMarker must be an integer.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidPolicyDocument: { + ErrInvalidPolicyDocument: { Code: "InvalidPolicyDocument", Description: "The content of the form does not meet the conditions specified in the policy document.", HTTPStatusCode: http.StatusBadRequest, }, - AccessDenied: { + ErrAccessDenied: { Code: "AccessDenied", Description: "Access Denied.", HTTPStatusCode: http.StatusForbidden, }, - BadDigest: { + ErrBadDigest: { Code: "BadDigest", Description: "The Content-Md5 you specified did not match what we received.", HTTPStatusCode: http.StatusBadRequest, }, - BucketAlreadyExists: { + ErrBucketAlreadyExists: { Code: "BucketAlreadyExists", Description: "The requested bucket name is not available.", HTTPStatusCode: http.StatusConflict, }, - EntityTooSmall: { + ErrEntityTooSmall: { Code: "EntityTooSmall", Description: "Your proposed upload is smaller than the minimum allowed object size.", HTTPStatusCode: http.StatusBadRequest, }, - EntityTooLarge: { + ErrEntityTooLarge: { Code: "EntityTooLarge", Description: "Your proposed upload exceeds the maximum allowed object size.", HTTPStatusCode: http.StatusBadRequest, }, - IncompleteBody: { + ErrIncompleteBody: { Code: "IncompleteBody", Description: "You did not provide the number of bytes specified by the Content-Length HTTP header.", HTTPStatusCode: http.StatusBadRequest, }, - InternalError: { + ErrInternalError: { Code: "InternalError", Description: "We encountered an internal error, please try again.", HTTPStatusCode: http.StatusInternalServerError, }, - InvalidAccessKeyID: { + ErrInvalidAccessKeyID: { Code: "InvalidAccessKeyID", Description: "The access key ID you provided does not exist in our records.", HTTPStatusCode: http.StatusForbidden, }, - InvalidBucketName: { + ErrInvalidBucketName: { Code: "InvalidBucketName", Description: "The specified bucket is not valid.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidDigest: { + ErrInvalidDigest: { Code: "InvalidDigest", Description: "The Content-Md5 you specified is not valid.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidRange: { + ErrInvalidRange: { Code: "InvalidRange", Description: "The requested range cannot be satisfied.", HTTPStatusCode: http.StatusRequestedRangeNotSatisfiable, }, - MalformedXML: { + ErrMalformedXML: { Code: "MalformedXML", Description: "The XML you provided was not well-formed or did not validate against our published schema.", HTTPStatusCode: http.StatusBadRequest, }, - MissingContentLength: { + ErrMissingContentLength: { Code: "MissingContentLength", Description: "You must provide the Content-Length HTTP header.", HTTPStatusCode: http.StatusLengthRequired, }, - MissingContentMD5: { + ErrMissingContentMD5: { Code: "MissingContentMD5", Description: "Missing required header for this request: Content-Md5.", HTTPStatusCode: http.StatusBadRequest, }, - MissingRequestBodyError: { + ErrMissingRequestBodyError: { Code: "MissingRequestBodyError", Description: "Request body is empty.", HTTPStatusCode: http.StatusLengthRequired, }, - NoSuchBucket: { + ErrNoSuchBucket: { Code: "NoSuchBucket", Description: "The specified bucket does not exist.", HTTPStatusCode: http.StatusNotFound, }, - NoSuchBucketPolicy: { + ErrNoSuchBucketPolicy: { Code: "NoSuchBucketPolicy", Description: "The specified bucket does not have a bucket policy.", HTTPStatusCode: http.StatusNotFound, }, - NoSuchKey: { + ErrNoSuchKey: { Code: "NoSuchKey", Description: "The specified key does not exist.", HTTPStatusCode: http.StatusNotFound, }, - NoSuchUpload: { + ErrNoSuchUpload: { Code: "NoSuchUpload", Description: "The specified multipart upload does not exist.", HTTPStatusCode: http.StatusNotFound, }, - NotImplemented: { + ErrNotImplemented: { Code: "NotImplemented", Description: "A header you provided implies functionality that is not implemented.", HTTPStatusCode: http.StatusNotImplemented, }, - RequestTimeTooSkewed: { + ErrRequestTimeTooSkewed: { Code: "RequestTimeTooSkewed", Description: "The difference between the request time and the server's time is too large.", HTTPStatusCode: http.StatusForbidden, }, - SignatureDoesNotMatch: { + ErrSignatureDoesNotMatch: { Code: "SignatureDoesNotMatch", Description: "The request signature we calculated does not match the signature you provided.", HTTPStatusCode: http.StatusForbidden, }, - MethodNotAllowed: { + ErrMethodNotAllowed: { Code: "MethodNotAllowed", Description: "The specified method is not allowed against this resource.", HTTPStatusCode: http.StatusMethodNotAllowed, }, - InvalidPart: { + ErrInvalidPart: { Code: "InvalidPart", Description: "One or more of the specified parts could not be found.", HTTPStatusCode: http.StatusBadRequest, }, - InvalidPartOrder: { + ErrInvalidPartOrder: { Code: "InvalidPartOrder", Description: "The list of parts was not in ascending order. The parts list must be specified in order by part number.", HTTPStatusCode: http.StatusBadRequest, }, - AuthorizationHeaderMalformed: { + ErrAuthorizationHeaderMalformed: { Code: "AuthorizationHeaderMalformed", Description: "The authorization header is malformed; the region is wrong; expecting 'us-east-1'.", HTTPStatusCode: http.StatusBadRequest, }, - MalformedPOSTRequest: { + ErrMalformedPOSTRequest: { Code: "MalformedPOSTRequest", Description: "The body of your POST request is not well-formed multipart/form-data.", HTTPStatusCode: http.StatusBadRequest, }, - SignatureVersionNotSupported: { + ErrSignatureVersionNotSupported: { Code: "InvalidRequest", Description: "The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.", HTTPStatusCode: http.StatusBadRequest, }, - BucketNotEmpty: { + ErrBucketNotEmpty: { Code: "BucketNotEmpty", Description: "The bucket you tried to delete is not empty.", HTTPStatusCode: http.StatusConflict, }, - RootPathFull: { + ErrRootPathFull: { Code: "RootPathFull", Description: "Root path has reached its minimum free disk threshold. Please delete few objects to proceed.", HTTPStatusCode: http.StatusInternalServerError, }, - ObjectExistsAsPrefix: { + ErrObjectExistsAsPrefix: { Code: "ObjectExistsAsPrefix", Description: "An object already exists as your prefix, choose a different prefix to proceed.", HTTPStatusCode: http.StatusConflict, }, - AllAccessDisabled: { + ErrAllAccessDisabled: { Code: "AllAccessDisabled", Description: "All access to this bucket has been disabled.", HTTPStatusCode: http.StatusForbidden, }, - MalformedPolicy: { + ErrMalformedPolicy: { Code: "MalformedPolicy", Description: "Policy has invalid resource", HTTPStatusCode: http.StatusBadRequest, }, + // Add your error structure here. } -// errorCodeError provides errorCode to Error. It returns empty if the code provided is unknown -func getErrorCode(code int) APIError { +// getAPIError provides API Error for input API error code. +func getAPIError(code APIErrorCode) APIError { return errorCodeResponse[code] } // getErrorResponse gets in standard error and resource value and // provides a encodable populated response values -func getErrorResponse(err APIError, resource string) APIErrorResponse { +func getAPIErrorResponse(err APIError, resource string) APIErrorResponse { var data = APIErrorResponse{} data.Code = err.Code data.Message = err.Description diff --git a/api-response.go b/api-response.go index 2b75f0efa..4990941de 100644 --- a/api-response.go +++ b/api-response.go @@ -423,10 +423,10 @@ func writeSuccessNoContent(w http.ResponseWriter) { } // writeErrorRespone write error headers -func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorType int, resource string) { - error := getErrorCode(errorType) +func writeErrorResponse(w http.ResponseWriter, req *http.Request, errorCode APIErrorCode, resource string) { + error := getAPIError(errorCode) // generate error response - errorResponse := getErrorResponse(error, resource) + errorResponse := getAPIErrorResponse(error, resource) encodedErrorResponse := encodeResponse(errorResponse) // set common headers setCommonHeaders(w) diff --git a/auth-handler.go b/auth-handler.go index 718abc201..d4e2e0f2c 100644 --- a/auth-handler.go +++ b/auth-handler.go @@ -106,31 +106,31 @@ func getRequestAuthType(r *http.Request) authType { } // Verify if request has valid AWS Signature Version '4'. -func isSignV4ReqAuthenticated(sign *signature4.Sign, r *http.Request) (match bool, s3Error int) { +func isReqAuthenticated(sign *signature4.Sign, r *http.Request) (s3Error APIErrorCode) { auth := sign.SetHTTPRequestToVerify(r) if isRequestSignatureV4(r) { dummyPayload := sha256.Sum256([]byte("")) ok, err := auth.DoesSignatureMatch(hex.EncodeToString(dummyPayload[:])) if err != nil { errorIf(err.Trace(), "Signature verification failed.", nil) - return false, InternalError + return ErrInternalError } if !ok { - return false, SignatureDoesNotMatch + return ErrSignatureDoesNotMatch } - return ok, None + return ErrNone } else if isRequestPresignedSignatureV4(r) { ok, err := auth.DoesPresignedSignatureMatch() if err != nil { errorIf(err.Trace(), "Presigned signature verification failed.", nil) - return false, InternalError + return ErrInternalError } if !ok { - return false, SignatureDoesNotMatch + return ErrSignatureDoesNotMatch } - return ok, None + return ErrNone } - return false, AccessDenied + return ErrAccessDenied } // authHandler - handles all the incoming authorization headers and @@ -160,7 +160,7 @@ func (a authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } a.handler.ServeHTTP(w, r) default: - writeErrorResponse(w, r, SignatureVersionNotSupported, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureVersionNotSupported, r.URL.Path) return } } diff --git a/bucket-handlers.go b/bucket-handlers.go index 2c440fac1..f4b4d8d27 100644 --- a/bucket-handlers.go +++ b/bucket-handlers.go @@ -38,26 +38,26 @@ import ( ) // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html -func enforceBucketPolicy(action string, bucket string, reqURL *url.URL) (isAllowed bool, s3Error int) { +func enforceBucketPolicy(action string, bucket string, reqURL *url.URL) (s3Error APIErrorCode) { // Read saved bucket policy. policy, err := readBucketPolicy(bucket) if err != nil { errorIf(err.Trace(bucket), "GetBucketPolicy failed.", nil) switch err.ToGoError().(type) { case fs.BucketNotFound: - return false, NoSuchBucket + return ErrNoSuchBucket case fs.BucketNameInvalid: - return false, InvalidBucketName + return ErrInvalidBucketName default: // For any other error just return AccessDenied. - return false, AccessDenied + return ErrAccessDenied } } // Parse the saved policy. accessPolicy, e := accesspolicy.Validate(policy) if e != nil { errorIf(probe.NewError(e), "Parse policy failed.", nil) - return false, AccessDenied + return ErrAccessDenied } // Construct resource in 'arn:aws:s3:::examplebucket' format. @@ -71,9 +71,9 @@ func enforceBucketPolicy(action string, bucket string, reqURL *url.URL) (isAllow // Validate action, resource and conditions with current policy statements. if !bucketPolicyEvalStatements(action, resource, conditions, accessPolicy.Statements) { - return false, AccessDenied + return ErrAccessDenied } - return true, None + return ErrNone } // GetBucketLocationHandler - GET Bucket location. @@ -86,17 +86,16 @@ func (api storageAPI) GetBucketLocationHandler(w http.ResponseWriter, r *http.Re switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:GetBucketLocation", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:GetBucketLocation", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } case authTypeSigned, authTypePresigned: - match, s3Error := isSignV4ReqAuthenticated(api.Signature, r) - if !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -107,11 +106,11 @@ func (api storageAPI) GetBucketLocationHandler(w http.ResponseWriter, r *http.Re errorIf(err.Trace(), "GetBucketMetadata failed.", nil) switch err.ToGoError().(type) { case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -142,17 +141,16 @@ func (api storageAPI) ListMultipartUploadsHandler(w http.ResponseWriter, r *http switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:ListBucketMultipartUploads", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:ListBucketMultipartUploads", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } case authTypePresigned, authTypeSigned: - match, s3Error := isSignV4ReqAuthenticated(api.Signature, r) - if !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -160,7 +158,7 @@ func (api storageAPI) ListMultipartUploadsHandler(w http.ResponseWriter, r *http resources := getBucketMultipartResources(r.URL.Query()) if resources.MaxUploads < 0 { - writeErrorResponse(w, r, InvalidMaxUploads, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidMaxUploads, r.URL.Path) return } if resources.MaxUploads == 0 { @@ -172,9 +170,9 @@ func (api storageAPI) ListMultipartUploadsHandler(w http.ResponseWriter, r *http errorIf(err.Trace(), "ListMultipartUploads failed.", nil) switch err.ToGoError().(type) { case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -200,17 +198,16 @@ func (api storageAPI) ListObjectsHandler(w http.ResponseWriter, r *http.Request) switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:ListBucket", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:ListBucket", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } case authTypeSigned, authTypePresigned: - match, s3Error := isSignV4ReqAuthenticated(api.Signature, r) - if !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -219,7 +216,7 @@ func (api storageAPI) ListObjectsHandler(w http.ResponseWriter, r *http.Request) // TODO handle encoding type. prefix, marker, delimiter, maxkeys, _ := getBucketResources(r.URL.Query()) if maxkeys < 0 { - writeErrorResponse(w, r, InvalidMaxKeys, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidMaxKeys, r.URL.Path) return } if maxkeys == 0 { @@ -239,16 +236,16 @@ func (api storageAPI) ListObjectsHandler(w http.ResponseWriter, r *http.Request) } switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) default: errorIf(err.Trace(), "ListObjects failed.", nil) - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } } @@ -261,10 +258,10 @@ func (api storageAPI) ListBucketsHandler(w http.ResponseWriter, r *http.Request) switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeSigned, authTypePresigned: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -282,7 +279,7 @@ func (api storageAPI) ListBucketsHandler(w http.ResponseWriter, r *http.Request) return } errorIf(err.Trace(), "ListBuckets failed.", nil) - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } // DeleteMultipleObjectsHandler - deletes multiple objects. @@ -293,14 +290,14 @@ func (api storageAPI) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *htt // Content-Length is required and should be non-zero // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html if r.ContentLength <= 0 { - writeErrorResponse(w, r, MissingContentLength, r.URL.Path) + writeErrorResponse(w, r, ErrMissingContentLength, r.URL.Path) return } // Content-Md5 is requied should be set // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html if _, ok := r.Header["Content-Md5"]; !ok { - writeErrorResponse(w, r, MissingContentMD5, r.URL.Path) + writeErrorResponse(w, r, ErrMissingContentMD5, r.URL.Path) return } @@ -314,18 +311,18 @@ func (api storageAPI) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *htt _, e := io.ReadFull(r.Body, deleteXMLBytes) if e != nil { errorIf(probe.NewError(e), "DeleteMultipleObjects failed.", nil) - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) return } switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:DeleteObject", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:DeleteObject", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -334,11 +331,11 @@ func (api storageAPI) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *htt ok, err := auth.DoesPresignedSignatureMatch() if err != nil { errorIf(err.Trace(r.URL.String()), "Presigned signature verification failed.", nil) - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } case authTypeSigned: @@ -350,16 +347,16 @@ func (api storageAPI) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *htt ok, err := auth.DoesSignatureMatch(hex.EncodeToString(sha.Sum(nil))) if err != nil { errorIf(err.Trace(), "DeleteMultipleObjects failed.", nil) - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } // Verify content md5. if r.Header.Get("Content-Md5") != base64.StdEncoding.EncodeToString(mdSh.Sum(nil)) { - writeErrorResponse(w, r, BadDigest, r.URL.Path) + writeErrorResponse(w, r, ErrBadDigest, r.URL.Path) return } } @@ -367,7 +364,7 @@ func (api storageAPI) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *htt // Unmarshal list of keys to be deleted. deleteObjects := &DeleteObjectsRequest{} if e := xml.Unmarshal(deleteXMLBytes, deleteObjects); e != nil { - writeErrorResponse(w, r, MalformedXML, r.URL.Path) + writeErrorResponse(w, r, ErrMalformedXML, r.URL.Path) return } @@ -385,32 +382,32 @@ func (api storageAPI) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *htt switch err.ToGoError().(type) { case fs.BucketNameInvalid: deleteErrors = append(deleteErrors, DeleteError{ - Code: errorCodeResponse[InvalidBucketName].Code, - Message: errorCodeResponse[InvalidBucketName].Description, + Code: errorCodeResponse[ErrInvalidBucketName].Code, + Message: errorCodeResponse[ErrInvalidBucketName].Description, Key: object.ObjectName, }) case fs.BucketNotFound: deleteErrors = append(deleteErrors, DeleteError{ - Code: errorCodeResponse[NoSuchBucket].Code, - Message: errorCodeResponse[NoSuchBucket].Description, + Code: errorCodeResponse[ErrNoSuchBucket].Code, + Message: errorCodeResponse[ErrNoSuchBucket].Description, Key: object.ObjectName, }) case fs.ObjectNotFound: deleteErrors = append(deleteErrors, DeleteError{ - Code: errorCodeResponse[NoSuchKey].Code, - Message: errorCodeResponse[NoSuchKey].Description, + Code: errorCodeResponse[ErrNoSuchKey].Code, + Message: errorCodeResponse[ErrNoSuchKey].Description, Key: object.ObjectName, }) case fs.ObjectNameInvalid: deleteErrors = append(deleteErrors, DeleteError{ - Code: errorCodeResponse[NoSuchKey].Code, - Message: errorCodeResponse[NoSuchKey].Description, + Code: errorCodeResponse[ErrNoSuchKey].Code, + Message: errorCodeResponse[ErrNoSuchKey].Description, Key: object.ObjectName, }) default: deleteErrors = append(deleteErrors, DeleteError{ - Code: errorCodeResponse[InternalError].Code, - Message: errorCodeResponse[InternalError].Description, + Code: errorCodeResponse[ErrInternalError].Code, + Message: errorCodeResponse[ErrInternalError].Description, Key: object.ObjectName, }) } @@ -437,11 +434,11 @@ func (api storageAPI) PutBucketHandler(w http.ResponseWriter, r *http.Request) { switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:CreateBucket", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:CreateBucket", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -449,11 +446,11 @@ func (api storageAPI) PutBucketHandler(w http.ResponseWriter, r *http.Request) { ok, err := auth.DoesPresignedSignatureMatch() if err != nil { errorIf(err.Trace(r.URL.String()), "Presigned signature verification failed.", nil) - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } case authTypeSigned: @@ -461,7 +458,7 @@ func (api storageAPI) PutBucketHandler(w http.ResponseWriter, r *http.Request) { locationBytes, e := ioutil.ReadAll(r.Body) if e != nil { errorIf(probe.NewError(e), "MakeBucket failed.", nil) - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) return } sh := sha256.New() @@ -469,11 +466,11 @@ func (api storageAPI) PutBucketHandler(w http.ResponseWriter, r *http.Request) { ok, err := auth.DoesSignatureMatch(hex.EncodeToString(sh.Sum(nil))) if err != nil { errorIf(err.Trace(), "MakeBucket failed.", nil) - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } } @@ -484,11 +481,11 @@ func (api storageAPI) PutBucketHandler(w http.ResponseWriter, r *http.Request) { errorIf(err.Trace(), "MakeBucket failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketExists: - writeErrorResponse(w, r, BucketAlreadyExists, r.URL.Path) + writeErrorResponse(w, r, ErrBucketAlreadyExists, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -527,29 +524,20 @@ func extractHTTPFormValues(reader *multipart.Reader) (io.Reader, map[string]stri // This implementation of the POST operation handles object creation with a specified // signature policy in multipart/form-data func (api storageAPI) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Request) { - // if body of request is non-nil then check for validity of Content-Length - if r.Body != nil { - /// if Content-Length is unknown/missing, deny the request - if r.ContentLength == -1 { - writeErrorResponse(w, r, MissingContentLength, 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, e := r.MultipartReader() if e != nil { errorIf(probe.NewError(e), "Unable to initialize multipart reader.", nil) - writeErrorResponse(w, r, MalformedPOSTRequest, r.URL.Path) + writeErrorResponse(w, r, ErrMalformedPOSTRequest, r.URL.Path) return } fileBody, formValues, err := extractHTTPFormValues(reader) if err != nil { errorIf(err.Trace(), "Unable to parse form values.", nil) - writeErrorResponse(w, r, MalformedPOSTRequest, r.URL.Path) + writeErrorResponse(w, r, ErrMalformedPOSTRequest, r.URL.Path) return } bucket := mux.Vars(r)["bucket"] @@ -564,16 +552,16 @@ func (api storageAPI) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Req ok, err = auth.DoesPolicySignatureMatch(formValues) if err != nil { errorIf(err.Trace(), "Unable to verify signature.", nil) - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if err = signature4.ApplyPolicyCond(formValues); err != nil { errorIf(err.Trace(), "Invalid request, policy doesn't match with the endpoint.", nil) - writeErrorResponse(w, r, MalformedPOSTRequest, r.URL.Path) + writeErrorResponse(w, r, ErrMalformedPOSTRequest, r.URL.Path) return } metadata, err := api.Filesystem.CreateObject(bucket, object, "", -1, fileBody, nil) @@ -581,19 +569,19 @@ func (api storageAPI) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Req errorIf(err.Trace(), "CreateObject failed.", nil) switch err.ToGoError().(type) { case fs.RootPathFull: - writeErrorResponse(w, r, RootPathFull, r.URL.Path) + writeErrorResponse(w, r, ErrRootPathFull, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BadDigest: - writeErrorResponse(w, r, BadDigest, r.URL.Path) + writeErrorResponse(w, r, ErrBadDigest, r.URL.Path) case fs.IncompleteBody: - writeErrorResponse(w, r, IncompleteBody, r.URL.Path) + writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path) case fs.InvalidDigest: - writeErrorResponse(w, r, InvalidDigest, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidDigest, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -616,10 +604,10 @@ func (api storageAPI) HeadBucketHandler(w http.ResponseWriter, r *http.Request) switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypePresigned, authTypeSigned: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -630,11 +618,11 @@ func (api storageAPI) HeadBucketHandler(w http.ResponseWriter, r *http.Request) errorIf(err.Trace(), "GetBucketMetadata failed.", nil) switch err.ToGoError().(type) { case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -649,16 +637,16 @@ func (api storageAPI) DeleteBucketHandler(w http.ResponseWriter, r *http.Request switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:DeleteBucket", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:DeleteBucket", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } case authTypePresigned, authTypeSigned: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -669,11 +657,11 @@ func (api storageAPI) DeleteBucketHandler(w http.ResponseWriter, r *http.Request errorIf(err.Trace(), "DeleteBucket failed.", nil) switch err.ToGoError().(type) { case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.BucketNotEmpty: - writeErrorResponse(w, r, BucketNotEmpty, r.URL.Path) + writeErrorResponse(w, r, ErrBucketNotEmpty, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } diff --git a/bucket-policy-handlers.go b/bucket-policy-handlers.go index 3d0a7535d..d75968831 100644 --- a/bucket-policy-handlers.go +++ b/bucket-policy-handlers.go @@ -139,12 +139,12 @@ func (api storageAPI) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Requ // incoming request is not chunked. if !contains(r.TransferEncoding, "chunked") { if r.ContentLength == -1 || r.ContentLength == 0 { - writeErrorResponse(w, r, MissingContentLength, r.URL.Path) + writeErrorResponse(w, r, ErrMissingContentLength, r.URL.Path) return } // If Content-Length is greater than maximum allowed policy size. if r.ContentLength > maxAccessPolicySize { - writeErrorResponse(w, r, EntityTooLarge, r.URL.Path) + writeErrorResponse(w, r, ErrEntityTooLarge, r.URL.Path) return } } @@ -155,14 +155,14 @@ func (api storageAPI) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Requ accessPolicyBytes, e := ioutil.ReadAll(io.LimitReader(r.Body, maxAccessPolicySize)) if e != nil { errorIf(probe.NewError(e).Trace(bucket), "Reading policy failed.", nil) - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) return } // Parse access access. accessPolicy, e := accesspolicy.Validate(accessPolicyBytes) if e != nil { - writeErrorResponse(w, r, InvalidPolicyDocument, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidPolicyDocument, r.URL.Path) return } @@ -171,7 +171,7 @@ func (api storageAPI) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Requ for _, resource := range statement.Resources { resourcePrefix := strings.SplitAfter(resource, accesspolicy.AWSResourcePrefix)[1] if !strings.HasPrefix(resourcePrefix, bucket) { - writeErrorResponse(w, r, MalformedPolicy, r.URL.Path) + writeErrorResponse(w, r, ErrMalformedPolicy, r.URL.Path) return } } @@ -183,11 +183,11 @@ func (api storageAPI) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Requ ok, err := auth.DoesPresignedSignatureMatch() if err != nil { errorIf(err.Trace(r.URL.String()), "Presigned signature verification failed.", nil) - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } } else if isRequestSignatureV4(r) { @@ -196,11 +196,11 @@ func (api storageAPI) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Requ ok, err := api.Signature.DoesSignatureMatch(hex.EncodeToString(sh.Sum(nil))) if err != nil { errorIf(err.Trace(string(accessPolicyBytes)), "SaveBucketPolicy failed.", nil) - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } } @@ -211,9 +211,9 @@ func (api storageAPI) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Requ errorIf(err.Trace(bucket), "SaveBucketPolicy failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -229,7 +229,7 @@ func (api storageAPI) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.R bucket := vars["bucket"] // Validate incoming signature. - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -240,11 +240,11 @@ func (api storageAPI) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.R errorIf(err.Trace(bucket), "DeleteBucketPolicy failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketPolicyNotFound: - writeErrorResponse(w, r, NoSuchBucketPolicy, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucketPolicy, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -260,7 +260,7 @@ func (api storageAPI) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Requ bucket := vars["bucket"] // Validate incoming signature. - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -271,11 +271,11 @@ func (api storageAPI) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Requ errorIf(err.Trace(bucket), "GetBucketPolicy failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketPolicyNotFound: - writeErrorResponse(w, r, NoSuchBucketPolicy, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucketPolicy, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } diff --git a/generic-handlers.go b/generic-handlers.go index 5410317ac..cb33cd1fc 100644 --- a/generic-handlers.go +++ b/generic-handlers.go @@ -86,7 +86,7 @@ func (h cacheControlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // For all browser requests set appropriate Cache-Control policies match, e := regexp.MatchString(privateBucket+`/([^/]+\.js|favicon.ico)`, r.URL.Path) if e != nil { - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) return } if match { @@ -114,7 +114,7 @@ func setPrivateBucketHandler(h http.Handler) http.Handler { func (h minioPrivateBucketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // For all non browser requests, reject access to 'privateBucket'. if !strings.Contains(r.Header.Get("User-Agent"), "Mozilla") && path.Clean(r.URL.Path) == privateBucket { - writeErrorResponse(w, r, AllAccessDisabled, r.URL.Path) + writeErrorResponse(w, r, ErrAllAccessDisabled, r.URL.Path) return } h.handler.ServeHTTP(w, r) @@ -184,13 +184,13 @@ func (h timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // All our internal APIs are sensitive towards Date // header, for all requests where Date header is not // present we will reject such clients. - writeErrorResponse(w, r, RequestTimeTooSkewed, r.URL.Path) + writeErrorResponse(w, r, ErrRequestTimeTooSkewed, r.URL.Path) return } // Verify if the request date header is more than 5minutes // late, reject such clients. if time.Now().UTC().Sub(date)/time.Minute > time.Duration(5)*time.Minute { - writeErrorResponse(w, r, RequestTimeTooSkewed, r.URL.Path) + writeErrorResponse(w, r, ErrRequestTimeTooSkewed, r.URL.Path) return } } @@ -237,20 +237,20 @@ func (h resourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // level resource queries. if bucketName != "" && objectName == "" { if ignoreNotImplementedBucketResources(r) { - writeErrorResponse(w, r, NotImplemented, r.URL.Path) + writeErrorResponse(w, r, ErrNotImplemented, r.URL.Path) return } } // If bucketName and objectName are present check for its resource queries. if bucketName != "" && objectName != "" { if ignoreNotImplementedObjectResources(r) { - writeErrorResponse(w, r, NotImplemented, r.URL.Path) + writeErrorResponse(w, r, ErrNotImplemented, r.URL.Path) return } } // A put method on path "/" doesn't make sense, ignore it. if r.Method == "PUT" && r.URL.Path == "/" { - writeErrorResponse(w, r, NotImplemented, r.URL.Path) + writeErrorResponse(w, r, ErrNotImplemented, r.URL.Path) return } h.handler.ServeHTTP(w, r) diff --git a/object-handlers.go b/object-handlers.go index a4b9d9013..c8b9c5333 100644 --- a/object-handlers.go +++ b/object-handlers.go @@ -64,16 +64,16 @@ func (api storageAPI) GetObjectHandler(w http.ResponseWriter, r *http.Request) { switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:GetObject", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:GetObject", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } case authTypePresigned, authTypeSigned: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -84,15 +84,15 @@ func (api storageAPI) GetObjectHandler(w http.ResponseWriter, r *http.Request) { errorIf(err.Trace(), "GetObject failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -100,7 +100,7 @@ func (api storageAPI) GetObjectHandler(w http.ResponseWriter, r *http.Request) { var hrange *httpRange hrange, err = getRequestedRange(r.Header.Get("Range"), metadata.Size) if err != nil { - writeErrorResponse(w, r, InvalidRange, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidRange, r.URL.Path) return } @@ -231,7 +231,7 @@ func (api storageAPI) HeadObjectHandler(w http.ResponseWriter, r *http.Request) bucket = vars["bucket"] object = vars["object"] - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -240,15 +240,15 @@ func (api storageAPI) HeadObjectHandler(w http.ResponseWriter, r *http.Request) if err != nil { switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -288,16 +288,16 @@ func (api storageAPI) CopyObjectHandler(w http.ResponseWriter, r *http.Request) switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:GetBucketLocation", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:GetBucketLocation", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } case authTypePresigned, authTypeSigned: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -323,13 +323,13 @@ func (api storageAPI) CopyObjectHandler(w http.ResponseWriter, r *http.Request) } // If source object is empty, reply back error. if sourceObject == "" { - writeErrorResponse(w, r, InvalidCopySource, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidCopySource, r.URL.Path) return } // Source and destination objects cannot be same, reply back error. if sourceObject == object && sourceBucket == bucket { - writeErrorResponse(w, r, InvalidCopyDest, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidCopyDest, r.URL.Path) return } @@ -338,22 +338,22 @@ func (api storageAPI) CopyObjectHandler(w http.ResponseWriter, r *http.Request) errorIf(err.Trace(), "GetObjectMetadata failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, objectSource) + writeErrorResponse(w, r, ErrInvalidBucketName, objectSource) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, objectSource) + writeErrorResponse(w, r, ErrNoSuchBucket, objectSource) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, objectSource) + writeErrorResponse(w, r, ErrNoSuchKey, objectSource) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, objectSource) + writeErrorResponse(w, r, ErrNoSuchKey, objectSource) default: - writeErrorResponse(w, r, InternalError, objectSource) + writeErrorResponse(w, r, ErrInternalError, objectSource) } return } /// maximum Upload size for object in a single CopyObject operation. if isMaxObjectSize(metadata.Size) { - writeErrorResponse(w, r, EntityTooLarge, objectSource) + writeErrorResponse(w, r, ErrEntityTooLarge, objectSource) return } @@ -380,21 +380,21 @@ func (api storageAPI) CopyObjectHandler(w http.ResponseWriter, r *http.Request) errorIf(err.Trace(), "CreateObject failed.", nil) switch err.ToGoError().(type) { case fs.RootPathFull: - writeErrorResponse(w, r, RootPathFull, r.URL.Path) + writeErrorResponse(w, r, ErrRootPathFull, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BadDigest: - writeErrorResponse(w, r, BadDigest, r.URL.Path) + writeErrorResponse(w, r, ErrBadDigest, r.URL.Path) case fs.IncompleteBody: - writeErrorResponse(w, r, IncompleteBody, r.URL.Path) + writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path) case fs.InvalidDigest: - writeErrorResponse(w, r, InvalidDigest, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidDigest, r.URL.Path) case fs.ObjectExistsAsPrefix: - writeErrorResponse(w, r, ObjectExistsAsPrefix, r.URL.Path) + writeErrorResponse(w, r, ErrObjectExistsAsPrefix, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -413,7 +413,7 @@ func (api storageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Request) { // 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 { - writeErrorResponse(w, r, InvalidCopySource, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidCopySource, r.URL.Path) return } vars := mux.Vars(r) @@ -423,18 +423,18 @@ func (api storageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Request) { // get Content-Md5 sent by client and verify if valid md5 := r.Header.Get("Content-Md5") if !isValidMD5(md5) { - writeErrorResponse(w, r, InvalidDigest, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidDigest, r.URL.Path) return } /// if Content-Length is unknown/missing, deny the request size := r.ContentLength if size == -1 && !contains(r.TransferEncoding, "chunked") { - writeErrorResponse(w, r, MissingContentLength, r.URL.Path) + writeErrorResponse(w, r, ErrMissingContentLength, r.URL.Path) return } /// maximum Upload size for objects in a single operation if isMaxObjectSize(size) { - writeErrorResponse(w, r, EntityTooLarge, r.URL.Path) + writeErrorResponse(w, r, ErrEntityTooLarge, r.URL.Path) return } @@ -445,11 +445,11 @@ func (api storageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Request) { switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:PutObject", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:PutObject", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -461,11 +461,11 @@ func (api storageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Request) { ok, err = auth.DoesPresignedSignatureMatch() if err != nil { errorIf(err.Trace(r.URL.String()), "Presigned signature verification failed.", nil) - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } // Create presigned object. @@ -478,23 +478,23 @@ func (api storageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Request) { errorIf(err.Trace(), "CreateObject failed.", nil) switch err.ToGoError().(type) { case fs.RootPathFull: - writeErrorResponse(w, r, RootPathFull, r.URL.Path) + writeErrorResponse(w, r, ErrRootPathFull, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BadDigest: - writeErrorResponse(w, r, BadDigest, r.URL.Path) + writeErrorResponse(w, r, ErrBadDigest, r.URL.Path) case fs.SignDoesNotMatch: - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) case fs.IncompleteBody: - writeErrorResponse(w, r, IncompleteBody, r.URL.Path) + writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path) case fs.InvalidDigest: - writeErrorResponse(w, r, InvalidDigest, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidDigest, r.URL.Path) case fs.ObjectExistsAsPrefix: - writeErrorResponse(w, r, ObjectExistsAsPrefix, r.URL.Path) + writeErrorResponse(w, r, ErrObjectExistsAsPrefix, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -516,12 +516,12 @@ func (api storageAPI) NewMultipartUploadHandler(w http.ResponseWriter, r *http.R switch getRequestAuthType(r) { case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:PutObject", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:PutObject", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } default: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -532,17 +532,17 @@ func (api storageAPI) NewMultipartUploadHandler(w http.ResponseWriter, r *http.R errorIf(err.Trace(), "NewMultipartUpload failed.", nil) switch err.ToGoError().(type) { case fs.RootPathFull: - writeErrorResponse(w, r, RootPathFull, r.URL.Path) + writeErrorResponse(w, r, ErrRootPathFull, r.URL.Path) case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -564,20 +564,20 @@ func (api storageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http.Reques // get Content-Md5 sent by client and verify if valid md5 := r.Header.Get("Content-Md5") if !isValidMD5(md5) { - writeErrorResponse(w, r, InvalidDigest, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidDigest, r.URL.Path) return } /// if Content-Length is unknown/missing, throw away size := r.ContentLength if size == -1 { - writeErrorResponse(w, r, MissingContentLength, r.URL.Path) + writeErrorResponse(w, r, ErrMissingContentLength, r.URL.Path) return } /// maximum Upload size for multipart objects in a single operation if isMaxObjectSize(size) { - writeErrorResponse(w, r, EntityTooLarge, r.URL.Path) + writeErrorResponse(w, r, ErrEntityTooLarge, r.URL.Path) return } @@ -586,7 +586,7 @@ func (api storageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http.Reques partID, e := strconv.Atoi(partIDString) if e != nil { - writeErrorResponse(w, r, InvalidPart, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidPart, r.URL.Path) return } @@ -597,7 +597,7 @@ func (api storageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http.Reques switch getRequestAuthType(r) { case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:PutObject", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:PutObject", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -610,11 +610,11 @@ func (api storageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http.Reques ok, err = auth.DoesPresignedSignatureMatch() if err != nil { errorIf(err.Trace(r.URL.String()), "Presigned signature verification failed.", nil) - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } partMD5, err = api.Filesystem.CreateObjectPart(bucket, object, uploadID, md5, partID, size, r.Body, nil) @@ -625,19 +625,19 @@ func (api storageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http.Reques errorIf(err.Trace(), "CreateObjectPart failed.", nil) switch err.ToGoError().(type) { case fs.RootPathFull: - writeErrorResponse(w, r, RootPathFull, r.URL.Path) + writeErrorResponse(w, r, ErrRootPathFull, r.URL.Path) case fs.InvalidUploadID: - writeErrorResponse(w, r, NoSuchUpload, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path) case fs.BadDigest: - writeErrorResponse(w, r, BadDigest, r.URL.Path) + writeErrorResponse(w, r, ErrBadDigest, r.URL.Path) case fs.SignDoesNotMatch: - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) case fs.IncompleteBody: - writeErrorResponse(w, r, IncompleteBody, r.URL.Path) + writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path) case fs.InvalidDigest: - writeErrorResponse(w, r, InvalidDigest, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidDigest, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -656,12 +656,12 @@ func (api storageAPI) AbortMultipartUploadHandler(w http.ResponseWriter, r *http switch getRequestAuthType(r) { case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:AbortMultipartUpload", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:AbortMultipartUpload", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } default: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -673,17 +673,17 @@ func (api storageAPI) AbortMultipartUploadHandler(w http.ResponseWriter, r *http errorIf(err.Trace(), "AbortMutlipartUpload failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.InvalidUploadID: - writeErrorResponse(w, r, NoSuchUpload, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -699,12 +699,12 @@ func (api storageAPI) ListObjectPartsHandler(w http.ResponseWriter, r *http.Requ switch getRequestAuthType(r) { case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:ListMultipartUploadParts", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:ListMultipartUploadParts", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } default: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -712,11 +712,11 @@ func (api storageAPI) ListObjectPartsHandler(w http.ResponseWriter, r *http.Requ objectResourcesMetadata := getObjectResources(r.URL.Query()) if objectResourcesMetadata.PartNumberMarker < 0 { - writeErrorResponse(w, r, InvalidPartNumberMarker, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidPartNumberMarker, r.URL.Path) return } if objectResourcesMetadata.MaxParts < 0 { - writeErrorResponse(w, r, InvalidMaxParts, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidMaxParts, r.URL.Path) return } if objectResourcesMetadata.MaxParts == 0 { @@ -728,17 +728,17 @@ func (api storageAPI) ListObjectPartsHandler(w http.ResponseWriter, r *http.Requ errorIf(err.Trace(), "ListObjectParts failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.InvalidUploadID: - writeErrorResponse(w, r, NoSuchUpload, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -767,11 +767,11 @@ func (api storageAPI) CompleteMultipartUploadHandler(w http.ResponseWriter, r *h switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:PutObject", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:PutObject", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -783,11 +783,11 @@ func (api storageAPI) CompleteMultipartUploadHandler(w http.ResponseWriter, r *h ok, err = auth.DoesPresignedSignatureMatch() if err != nil { errorIf(err.Trace(r.URL.String()), "Presigned signature verification failed.", nil) - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } if !ok { - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) return } // Complete multipart upload presigned. @@ -800,27 +800,27 @@ func (api storageAPI) CompleteMultipartUploadHandler(w http.ResponseWriter, r *h errorIf(err.Trace(), "CompleteMultipartUpload failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.InvalidUploadID: - writeErrorResponse(w, r, NoSuchUpload, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path) case fs.InvalidPart: - writeErrorResponse(w, r, InvalidPart, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidPart, r.URL.Path) case fs.InvalidPartOrder: - writeErrorResponse(w, r, InvalidPartOrder, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidPartOrder, r.URL.Path) case fs.SignDoesNotMatch: - writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path) case fs.IncompleteBody: - writeErrorResponse(w, r, IncompleteBody, r.URL.Path) + writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path) case fs.MalformedXML: - writeErrorResponse(w, r, MalformedXML, r.URL.Path) + writeErrorResponse(w, r, ErrMalformedXML, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } return } @@ -846,16 +846,16 @@ func (api storageAPI) DeleteObjectHandler(w http.ResponseWriter, r *http.Request switch getRequestAuthType(r) { default: // For all unknown auth types return error. - writeErrorResponse(w, r, AccessDenied, r.URL.Path) + writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path) return case authTypeAnonymous: // http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html - if isAllowed, s3Error := enforceBucketPolicy("s3:DeleteObject", bucket, r.URL); !isAllowed { + if s3Error := enforceBucketPolicy("s3:DeleteObject", bucket, r.URL); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } case authTypeSigned, authTypePresigned: - if match, s3Error := isSignV4ReqAuthenticated(api.Signature, r); !match { + if s3Error := isReqAuthenticated(api.Signature, r); s3Error != ErrNone { writeErrorResponse(w, r, s3Error, r.URL.Path) return } @@ -865,15 +865,15 @@ func (api storageAPI) DeleteObjectHandler(w http.ResponseWriter, r *http.Request errorIf(err.Trace(), "DeleteObject failed.", nil) switch err.ToGoError().(type) { case fs.BucketNameInvalid: - writeErrorResponse(w, r, InvalidBucketName, r.URL.Path) + writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path) case fs.BucketNotFound: - writeErrorResponse(w, r, NoSuchBucket, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path) case fs.ObjectNotFound: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) case fs.ObjectNameInvalid: - writeErrorResponse(w, r, NoSuchKey, r.URL.Path) + writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path) default: - writeErrorResponse(w, r, InternalError, r.URL.Path) + writeErrorResponse(w, r, ErrInternalError, r.URL.Path) } } writeSuccessNoContent(w) diff --git a/pkg/fs/fs-bucket_test.go b/pkg/fs/fs-bucket_test.go index cecf6fc49..981f1b8b4 100644 --- a/pkg/fs/fs-bucket_test.go +++ b/pkg/fs/fs-bucket_test.go @@ -40,7 +40,7 @@ func TestListBuckets(t *testing.T) { // Create a few buckets. for i := 0; i < 10; i++ { - err = filesystem.MakeBucket("testbucket."+strconv.Itoa(i), "public-read") + err = filesystem.MakeBucket("testbucket." + strconv.Itoa(i)) if err != nil { t.Fatal(err) } @@ -53,7 +53,7 @@ func TestListBuckets(t *testing.T) { } if len(metadatas) != 10 { - t.Errorf("incorrect length of metadatas (%i)\n", len(metadatas)) + t.Errorf("incorrect length of metadatas (%d)\n", len(metadatas)) } // Iterate over the buckets, ensuring that the name is correct. @@ -101,7 +101,7 @@ func BenchmarkListBuckets(b *testing.B) { // Create a few buckets. for i := 0; i < 20; i++ { - err = filesystem.MakeBucket("bucket."+strconv.Itoa(i), "public-read") + err = filesystem.MakeBucket("bucket." + strconv.Itoa(i)) if err != nil { b.Fatal(err) }