mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
handlers: overhaul entire writErrorResponse, simplify. (#1472)
This commit is contained in:
parent
ba5805e60a
commit
17868ccd7f
@ -108,8 +108,8 @@ const (
|
||||
// Add new error codes here.
|
||||
|
||||
// Extended errors.
|
||||
ErrInsufficientReadResources
|
||||
ErrInsufficientWriteResources
|
||||
ErrReadQuorum
|
||||
ErrWriteQuorum
|
||||
)
|
||||
|
||||
// error code to APIError structure, these fields carry respective
|
||||
@ -190,15 +190,15 @@ var errorCodeResponse = map[APIErrorCode]APIError{
|
||||
Description: "We encountered an internal error, please try again.",
|
||||
HTTPStatusCode: http.StatusInternalServerError,
|
||||
},
|
||||
ErrInsufficientReadResources: {
|
||||
Code: "InternalError",
|
||||
Description: "We cannot satisfy sufficient read resources requested at this moment, please try again.",
|
||||
HTTPStatusCode: http.StatusInternalServerError,
|
||||
ErrReadQuorum: {
|
||||
Code: "ReadQuorum",
|
||||
Description: "Multiple disk failures, unable to reconstruct data.",
|
||||
HTTPStatusCode: http.StatusServiceUnavailable,
|
||||
},
|
||||
ErrInsufficientWriteResources: {
|
||||
Code: "InternalError",
|
||||
Description: "We cannot satisfy sufficient write resources requested at this moment, please try again.",
|
||||
HTTPStatusCode: http.StatusInternalServerError,
|
||||
ErrWriteQuorum: {
|
||||
Code: "WriteQuorum",
|
||||
Description: "Multiple disks failures, unable to write data.",
|
||||
HTTPStatusCode: http.StatusServiceUnavailable,
|
||||
},
|
||||
ErrInvalidAccessKeyID: {
|
||||
Code: "InvalidAccessKeyID",
|
||||
@ -418,6 +418,52 @@ var errorCodeResponse = map[APIErrorCode]APIError{
|
||||
// Add your error structure here.
|
||||
}
|
||||
|
||||
// toAPIErrorCode - Converts embedded errors. Convenience
|
||||
// function written to handle all cases where we have known types of
|
||||
// errors returned by underlying layers.
|
||||
func toAPIErrorCode(err error) (apiErr APIErrorCode) {
|
||||
if err == nil {
|
||||
return ErrNone
|
||||
}
|
||||
// Verify if the underlying error is signature mismatch.
|
||||
if err == errSignatureMismatch {
|
||||
return ErrSignatureDoesNotMatch
|
||||
}
|
||||
switch err.(type) {
|
||||
case StorageFull:
|
||||
apiErr = ErrStorageFull
|
||||
case BadDigest:
|
||||
apiErr = ErrBadDigest
|
||||
case IncompleteBody:
|
||||
apiErr = ErrIncompleteBody
|
||||
case ObjectExistsAsPrefix:
|
||||
apiErr = ErrObjectExistsAsPrefix
|
||||
case BucketNameInvalid:
|
||||
apiErr = ErrInvalidBucketName
|
||||
case BucketNotFound:
|
||||
apiErr = ErrNoSuchBucket
|
||||
case BucketNotEmpty:
|
||||
apiErr = ErrBucketNotEmpty
|
||||
case BucketExists:
|
||||
apiErr = ErrBucketAlreadyOwnedByYou
|
||||
case ObjectNotFound:
|
||||
apiErr = ErrNoSuchKey
|
||||
case ObjectNameInvalid:
|
||||
apiErr = ErrNoSuchKey
|
||||
case InvalidUploadID:
|
||||
apiErr = ErrNoSuchUpload
|
||||
case InvalidPart:
|
||||
apiErr = ErrInvalidPart
|
||||
case InsufficientWriteQuorum:
|
||||
apiErr = ErrWriteQuorum
|
||||
case InsufficientReadQuorum:
|
||||
apiErr = ErrReadQuorum
|
||||
default:
|
||||
apiErr = ErrInternalError
|
||||
}
|
||||
return apiErr
|
||||
}
|
||||
|
||||
// getAPIError provides API Error for input API error code.
|
||||
func getAPIError(code APIErrorCode) APIError {
|
||||
return errorCodeResponse[code]
|
||||
|
@ -118,14 +118,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *
|
||||
|
||||
if _, err := api.ObjectAPI.GetBucketInfo(bucket); err != nil {
|
||||
errorIf(err, "GetBucketInfo failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
@ -196,12 +189,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter,
|
||||
listMultipartsInfo, err := api.ObjectAPI.ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploads)
|
||||
if err != nil {
|
||||
errorIf(err, "ListMultipartUploads failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
// generate response
|
||||
@ -281,16 +269,7 @@ func (api objectAPIHandlers) ListObjectsHandler(w http.ResponseWriter, r *http.R
|
||||
return
|
||||
}
|
||||
errorIf(err, "ListObjects failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
}
|
||||
|
||||
// ListBucketsHandler - GET Service
|
||||
@ -344,13 +323,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
|
||||
return
|
||||
}
|
||||
errorIf(err, "ListBuckets failed.", nil)
|
||||
switch err.(type) {
|
||||
case StorageInsufficientReadResources:
|
||||
writeErrorResponse(w, r, ErrInsufficientReadResources, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
}
|
||||
|
||||
// DeleteMultipleObjectsHandler - deletes multiple objects.
|
||||
@ -419,38 +392,11 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
||||
})
|
||||
} else {
|
||||
errorIf(err, "DeleteObject failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
deleteErrors = append(deleteErrors, DeleteError{
|
||||
Code: errorCodeResponse[ErrInvalidBucketName].Code,
|
||||
Message: errorCodeResponse[ErrInvalidBucketName].Description,
|
||||
Key: object.ObjectName,
|
||||
})
|
||||
case BucketNotFound:
|
||||
deleteErrors = append(deleteErrors, DeleteError{
|
||||
Code: errorCodeResponse[ErrNoSuchBucket].Code,
|
||||
Message: errorCodeResponse[ErrNoSuchBucket].Description,
|
||||
Key: object.ObjectName,
|
||||
})
|
||||
case ObjectNotFound:
|
||||
deleteErrors = append(deleteErrors, DeleteError{
|
||||
Code: errorCodeResponse[ErrNoSuchKey].Code,
|
||||
Message: errorCodeResponse[ErrNoSuchKey].Description,
|
||||
Key: object.ObjectName,
|
||||
})
|
||||
case ObjectNameInvalid:
|
||||
deleteErrors = append(deleteErrors, DeleteError{
|
||||
Code: errorCodeResponse[ErrNoSuchKey].Code,
|
||||
Message: errorCodeResponse[ErrNoSuchKey].Description,
|
||||
Key: object.ObjectName,
|
||||
})
|
||||
default:
|
||||
deleteErrors = append(deleteErrors, DeleteError{
|
||||
Code: errorCodeResponse[ErrInternalError].Code,
|
||||
Message: errorCodeResponse[ErrInternalError].Description,
|
||||
Key: object.ObjectName,
|
||||
})
|
||||
}
|
||||
deleteErrors = append(deleteErrors, DeleteError{
|
||||
Code: errorCodeResponse[toAPIErrorCode(err)].Code,
|
||||
Message: errorCodeResponse[toAPIErrorCode(err)].Description,
|
||||
Key: object.ObjectName,
|
||||
})
|
||||
}
|
||||
}
|
||||
// Generate response
|
||||
@ -466,7 +412,6 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
||||
// ----------
|
||||
// This implementation of the PUT operation creates a new bucket for authenticated request
|
||||
func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
vars := mux.Vars(r)
|
||||
bucket := vars["bucket"]
|
||||
|
||||
@ -495,14 +440,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
|
||||
err := api.ObjectAPI.MakeBucket(bucket)
|
||||
if err != nil {
|
||||
errorIf(err, "MakeBucket failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketExists:
|
||||
writeErrorResponse(w, r, ErrBucketAlreadyOwnedByYou, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
// Make sure to add Location information here only for bucket
|
||||
@ -573,20 +511,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
||||
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, -1, fileBody, nil)
|
||||
if err != nil {
|
||||
errorIf(err, "PutObject failed.", nil)
|
||||
switch err.(type) {
|
||||
case StorageFull:
|
||||
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BadDigest:
|
||||
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
|
||||
case IncompleteBody:
|
||||
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
if md5Sum != "" {
|
||||
@ -632,16 +557,7 @@ func (api objectAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Re
|
||||
|
||||
if _, err := api.ObjectAPI.GetBucketInfo(bucket); err != nil {
|
||||
errorIf(err, "GetBucketInfo failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case StorageInsufficientReadResources:
|
||||
writeErrorResponse(w, r, ErrInsufficientReadResources, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
writeSuccessResponse(w, nil)
|
||||
@ -666,14 +582,7 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.
|
||||
|
||||
if err := api.ObjectAPI.DeleteBucket(bucket); err != nil {
|
||||
errorIf(err, "DeleteBucket failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case BucketNotEmpty:
|
||||
writeErrorResponse(w, r, ErrBucketNotEmpty, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,9 @@ func toObjectErr(err error, params ...string) error {
|
||||
case errDiskFull:
|
||||
return StorageFull{}
|
||||
case errReadQuorum:
|
||||
return StorageInsufficientReadResources{}
|
||||
return InsufficientReadQuorum{}
|
||||
case errWriteQuorum:
|
||||
return StorageInsufficientWriteResources{}
|
||||
return InsufficientWriteQuorum{}
|
||||
case errIsNotRegular, errFileAccessDenied:
|
||||
if len(params) >= 2 {
|
||||
return ObjectExistsAsPrefix{
|
||||
@ -71,18 +71,18 @@ func (e StorageFull) Error() string {
|
||||
return "Storage reached its minimum free disk threshold."
|
||||
}
|
||||
|
||||
// StorageInsufficientReadResources storage cannot satisfy quorum for read operation.
|
||||
type StorageInsufficientReadResources struct{}
|
||||
// InsufficientReadQuorum storage cannot satisfy quorum for read operation.
|
||||
type InsufficientReadQuorum struct{}
|
||||
|
||||
func (e StorageInsufficientReadResources) Error() string {
|
||||
func (e InsufficientReadQuorum) Error() string {
|
||||
return "Storage resources are insufficient for the read operation."
|
||||
}
|
||||
|
||||
// StorageInsufficientWriteResources storage cannot satisfy quorum for write operation.
|
||||
type StorageInsufficientWriteResources struct{}
|
||||
// InsufficientWriteQuorum storage cannot satisfy quorum for write operation.
|
||||
type InsufficientWriteQuorum struct{}
|
||||
|
||||
func (e StorageInsufficientWriteResources) Error() string {
|
||||
return "Stroage resources are insufficient for the write operation."
|
||||
func (e InsufficientWriteQuorum) Error() string {
|
||||
return "Storage resources are insufficient for the write operation."
|
||||
}
|
||||
|
||||
// GenericError - generic object layer error.
|
||||
|
@ -65,7 +65,6 @@ func errAllowableObjectNotFound(bucket string, r *http.Request) APIErrorCode {
|
||||
return ErrAccessDenied
|
||||
}
|
||||
}
|
||||
|
||||
return ErrNoSuchKey
|
||||
}
|
||||
|
||||
@ -100,18 +99,11 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
|
||||
objInfo, err := api.ObjectAPI.GetObjectInfo(bucket, object)
|
||||
if err != nil {
|
||||
errorIf(err, "GetObjectInfo failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, errAllowableObjectNotFound(bucket, r), r.URL.Path)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
apiErr := toAPIErrorCode(err)
|
||||
if apiErr == ErrNoSuchKey {
|
||||
apiErr = errAllowableObjectNotFound(bucket, r)
|
||||
}
|
||||
writeErrorResponse(w, r, apiErr, r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
@ -136,15 +128,12 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req
|
||||
startOffset := hrange.start
|
||||
readCloser, err := api.ObjectAPI.GetObject(bucket, object, startOffset)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, errAllowableObjectNotFound(bucket, r), r.URL.Path)
|
||||
default:
|
||||
errorIf(err, "GetObject failed.", nil)
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
errorIf(err, "GetObject failed.", nil)
|
||||
apiErr := toAPIErrorCode(err)
|
||||
if apiErr == ErrNoSuchKey {
|
||||
apiErr = errAllowableObjectNotFound(bucket, r)
|
||||
}
|
||||
writeErrorResponse(w, r, apiErr, r.URL.Path)
|
||||
return
|
||||
}
|
||||
defer readCloser.Close() // Close after this handler returns.
|
||||
@ -294,18 +283,11 @@ func (api objectAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
objInfo, err := api.ObjectAPI.GetObjectInfo(bucket, object)
|
||||
if err != nil {
|
||||
errorIf(err, "GetObjectInfo failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, errAllowableObjectNotFound(bucket, r), r.URL.Path)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
apiErr := toAPIErrorCode(err)
|
||||
if apiErr == ErrNoSuchKey {
|
||||
apiErr = errAllowableObjectNotFound(bucket, r)
|
||||
}
|
||||
writeErrorResponse(w, r, apiErr, r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
@ -387,18 +369,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
objInfo, err := api.ObjectAPI.GetObjectInfo(sourceBucket, sourceObject)
|
||||
if err != nil {
|
||||
errorIf(err, "GetObjectInfo failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, objectSource)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, objectSource)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, objectSource)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, objectSource)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, objectSource)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), objectSource)
|
||||
return
|
||||
}
|
||||
// Verify before writing.
|
||||
@ -437,14 +408,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
readCloser, err := api.ObjectAPI.GetObject(sourceBucket, sourceObject, startOffset)
|
||||
if err != nil {
|
||||
errorIf(err, "Reading "+objectSource+" failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, objectSource)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, objectSource)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, objectSource)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), objectSource)
|
||||
return
|
||||
}
|
||||
// Size of object.
|
||||
@ -458,29 +422,14 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
|
||||
md5Sum, err := api.ObjectAPI.PutObject(bucket, object, size, readCloser, metadata)
|
||||
if err != nil {
|
||||
errorIf(err, "PutObject failed.", nil)
|
||||
switch err.(type) {
|
||||
case StorageFull:
|
||||
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BadDigest:
|
||||
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
|
||||
case IncompleteBody:
|
||||
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
|
||||
case ObjectExistsAsPrefix:
|
||||
writeErrorResponse(w, r, ErrObjectExistsAsPrefix, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
objInfo, err = api.ObjectAPI.GetObjectInfo(bucket, object)
|
||||
if err != nil {
|
||||
errorIf(err, "GetObjectInfo failed.", nil)
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
@ -675,27 +624,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
|
||||
}
|
||||
if err != nil {
|
||||
errorIf(err, "PutObject failed.", nil)
|
||||
// Verify if the underlying error is signature mismatch.
|
||||
if err == errSignatureMismatch {
|
||||
writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path)
|
||||
return
|
||||
}
|
||||
switch err.(type) {
|
||||
case StorageFull:
|
||||
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BadDigest:
|
||||
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
|
||||
case IncompleteBody:
|
||||
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
|
||||
case ObjectExistsAsPrefix:
|
||||
writeErrorResponse(w, r, ErrObjectExistsAsPrefix, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
if md5Sum != "" {
|
||||
@ -734,20 +663,7 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r
|
||||
uploadID, err := api.ObjectAPI.NewMultipartUpload(bucket, object)
|
||||
if err != nil {
|
||||
errorIf(err, "NewMultipartUpload failed.", nil)
|
||||
switch err.(type) {
|
||||
case StorageFull:
|
||||
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
@ -847,22 +763,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
|
||||
if err != nil {
|
||||
errorIf(err, "PutObjectPart failed.", nil)
|
||||
// Verify if the underlying error is signature mismatch.
|
||||
if err == errSignatureMismatch {
|
||||
writeErrorResponse(w, r, ErrSignatureDoesNotMatch, r.URL.Path)
|
||||
return
|
||||
}
|
||||
switch err.(type) {
|
||||
case StorageFull:
|
||||
writeErrorResponse(w, r, ErrStorageFull, r.URL.Path)
|
||||
case InvalidUploadID:
|
||||
writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path)
|
||||
case BadDigest:
|
||||
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
|
||||
case IncompleteBody:
|
||||
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
if partMD5 != "" {
|
||||
@ -898,20 +799,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter,
|
||||
uploadID, _, _, _ := getObjectResources(r.URL.Query())
|
||||
if err := api.ObjectAPI.AbortMultipartUpload(bucket, object, uploadID); err != nil {
|
||||
errorIf(err, "AbortMutlipartUpload failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
case InvalidUploadID:
|
||||
writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
writeSuccessNoContent(w)
|
||||
@ -957,22 +845,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht
|
||||
listPartsInfo, err := api.ObjectAPI.ListObjectParts(bucket, object, uploadID, partNumberMarker, maxParts)
|
||||
if err != nil {
|
||||
errorIf(err, "ListObjectParts failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
case InvalidUploadID:
|
||||
writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path)
|
||||
case InvalidPart:
|
||||
writeErrorResponse(w, r, ErrInvalidPart, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
response := generateListPartsResponse(listPartsInfo)
|
||||
@ -1038,24 +911,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
|
||||
md5Sum, err = api.ObjectAPI.CompleteMultipartUpload(bucket, object, uploadID, completeParts)
|
||||
if err != nil {
|
||||
errorIf(err, "CompleteMultipartUpload failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
case InvalidUploadID:
|
||||
writeErrorResponse(w, r, ErrNoSuchUpload, r.URL.Path)
|
||||
case InvalidPart:
|
||||
writeErrorResponse(w, r, ErrInvalidPart, r.URL.Path)
|
||||
case IncompleteBody:
|
||||
writeErrorResponse(w, r, ErrIncompleteBody, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
// Get object location.
|
||||
@ -1096,18 +952,7 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
|
||||
}
|
||||
if err := api.ObjectAPI.DeleteObject(bucket, object); err != nil {
|
||||
errorIf(err, "DeleteObject failed.", nil)
|
||||
switch err.(type) {
|
||||
case BucketNameInvalid:
|
||||
writeErrorResponse(w, r, ErrInvalidBucketName, r.URL.Path)
|
||||
case BucketNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchBucket, r.URL.Path)
|
||||
case ObjectNotFound:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
case ObjectNameInvalid:
|
||||
writeErrorResponse(w, r, ErrNoSuchKey, r.URL.Path)
|
||||
default:
|
||||
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||
}
|
||||
writeErrorResponse(w, r, toAPIErrorCode(err), r.URL.Path)
|
||||
return
|
||||
}
|
||||
writeSuccessNoContent(w)
|
||||
|
@ -411,10 +411,10 @@ func writeWebErrorResponse(w http.ResponseWriter, err error) {
|
||||
apiErrCode = ErrNoSuchKey
|
||||
case ObjectNameInvalid:
|
||||
apiErrCode = ErrNoSuchKey
|
||||
case StorageInsufficientWriteResources:
|
||||
apiErrCode = ErrInsufficientWriteResources
|
||||
case StorageInsufficientReadResources:
|
||||
apiErrCode = ErrInsufficientReadResources
|
||||
case InsufficientWriteQuorum:
|
||||
apiErrCode = ErrWriteQuorum
|
||||
case InsufficientReadQuorum:
|
||||
apiErrCode = ErrReadQuorum
|
||||
default:
|
||||
apiErrCode = ErrInternalError
|
||||
}
|
||||
|
@ -62,13 +62,12 @@ func (xl XL) listOnlineDisks(volume, path string) (onlineDisks []StorageAPI, mda
|
||||
for _, err := range errs {
|
||||
if err == errFileNotFound {
|
||||
notFoundCount++
|
||||
// If we have errors with file not found greater than allowed read
|
||||
// quorum we return err as errFileNotFound.
|
||||
if notFoundCount > len(xl.storageDisks)-xl.readQuorum {
|
||||
return nil, xlMetaV1{}, false, errFileNotFound
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we have errors with file not found equal to the number of disks.
|
||||
if notFoundCount == len(xl.storageDisks) {
|
||||
return nil, xlMetaV1{}, false, errFileNotFound
|
||||
}
|
||||
highestVersion := int64(0)
|
||||
onlineDisks = make([]StorageAPI, len(xl.storageDisks))
|
||||
// List all the file versions from partsMetadata list.
|
||||
|
@ -163,13 +163,17 @@ func (xl xlObjects) GetObjectInfo(bucket, object string) (ObjectInfo, error) {
|
||||
}
|
||||
fi, err := xl.storage.StatFile(bucket, object)
|
||||
if err != nil {
|
||||
info, err := getMultipartObjectInfo(xl.storage, bucket, object)
|
||||
if err != nil {
|
||||
return ObjectInfo{}, toObjectErr(err, bucket, object)
|
||||
if err == errFileNotFound {
|
||||
var info MultipartObjectInfo
|
||||
info, err = getMultipartObjectInfo(xl.storage, bucket, object)
|
||||
if err != nil {
|
||||
return ObjectInfo{}, toObjectErr(err, bucket, object)
|
||||
}
|
||||
fi.Size = info.Size
|
||||
fi.ModTime = info.ModTime
|
||||
fi.MD5Sum = info.MD5Sum
|
||||
}
|
||||
fi.Size = info.Size
|
||||
fi.ModTime = info.ModTime
|
||||
fi.MD5Sum = info.MD5Sum
|
||||
return ObjectInfo{}, toObjectErr(err, bucket, object)
|
||||
}
|
||||
contentType := "application/octet-stream"
|
||||
if objectExt := filepath.Ext(object); objectExt != "" {
|
||||
|
Loading…
Reference in New Issue
Block a user