mirror of
https://github.com/minio/minio.git
synced 2024-12-24 22:25:54 -05:00
Merge pull request #1209 from harshavardhana/err-naming
error: Add proper prefixes for s3Error codes.
This commit is contained in:
commit
b5c77b641d
182
api-errors.go
182
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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user