123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- package s3err
- import (
- "encoding/xml"
- "fmt"
- "net/http"
- )
- // APIError structure
- type APIError struct {
- Code string
- Description string
- HTTPStatusCode int
- }
- // RESTErrorResponse - error response format
- type RESTErrorResponse struct {
- XMLName xml.Name `xml:"Error" json:"-"`
- Code string `xml:"Code" json:"Code"`
- Message string `xml:"Message" json:"Message"`
- Resource string `xml:"Resource" json:"Resource"`
- RequestID string `xml:"RequestId" json:"RequestId"`
- Key string `xml:"Key,omitempty" json:"Key,omitempty"`
- BucketName string `xml:"BucketName,omitempty" json:"BucketName,omitempty"`
- // Underlying HTTP status code for the returned error
- StatusCode int `xml:"-" json:"-"`
- }
- // Error - Returns S3 error string.
- func (e RESTErrorResponse) Error() string {
- if e.Message == "" {
- msg, ok := s3ErrorResponseMap[e.Code]
- if !ok {
- msg = fmt.Sprintf("Error response code %s.", e.Code)
- }
- return msg
- }
- return e.Message
- }
- // ErrorCode type of error status.
- type ErrorCode int
- // Error codes, see full list at http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
- const (
- ErrNone ErrorCode = iota
- ErrAccessDenied
- ErrMethodNotAllowed
- ErrBucketNotEmpty
- ErrBucketAlreadyExists
- ErrBucketAlreadyOwnedByYou
- ErrNoSuchBucket
- ErrNoSuchBucketPolicy
- ErrNoSuchCORSConfiguration
- ErrNoSuchLifecycleConfiguration
- ErrNoSuchKey
- ErrNoSuchUpload
- ErrInvalidBucketName
- ErrInvalidDigest
- ErrInvalidMaxKeys
- ErrInvalidMaxUploads
- ErrInvalidMaxParts
- ErrInvalidMaxDeleteObjects
- ErrInvalidPartNumberMarker
- ErrInvalidPart
- ErrInvalidRange
- ErrInternalError
- ErrInvalidCopyDest
- ErrInvalidCopySource
- ErrInvalidTag
- ErrAuthHeaderEmpty
- ErrSignatureVersionNotSupported
- ErrMalformedPOSTRequest
- ErrPOSTFileRequired
- ErrPostPolicyConditionInvalidFormat
- ErrEntityTooSmall
- ErrEntityTooLarge
- ErrMissingFields
- ErrMissingCredTag
- ErrCredMalformed
- ErrMalformedXML
- ErrMalformedDate
- ErrMalformedPresignedDate
- ErrMalformedCredentialDate
- ErrMissingSignHeadersTag
- ErrMissingSignTag
- ErrUnsignedHeaders
- ErrInvalidQueryParams
- ErrInvalidQuerySignatureAlgo
- ErrExpiredPresignRequest
- ErrMalformedExpires
- ErrNegativeExpires
- ErrMaximumExpires
- ErrSignatureDoesNotMatch
- ErrContentSHA256Mismatch
- ErrInvalidAccessKeyID
- ErrRequestNotReadyYet
- ErrMissingDateHeader
- ErrInvalidRequest
- ErrAuthNotSetup
- ErrNotImplemented
- ErrPreconditionFailed
- ErrExistingObjectIsDirectory
- ErrExistingObjectIsFile
- ErrTooManyRequest
- ErrRequestBytesExceed
- OwnershipControlsNotFoundError
- ErrNoSuchTagSet
- )
- // error code to APIError structure, these fields carry respective
- // descriptions for all the error responses.
- var errorCodeResponse = map[ErrorCode]APIError{
- ErrAccessDenied: {
- Code: "AccessDenied",
- Description: "Access Denied.",
- HTTPStatusCode: http.StatusForbidden,
- },
- ErrMethodNotAllowed: {
- Code: "MethodNotAllowed",
- Description: "The specified method is not allowed against this resource.",
- HTTPStatusCode: http.StatusMethodNotAllowed,
- },
- ErrBucketNotEmpty: {
- Code: "BucketNotEmpty",
- Description: "The bucket you tried to delete is not empty",
- HTTPStatusCode: http.StatusConflict,
- },
- ErrBucketAlreadyExists: {
- Code: "BucketAlreadyExists",
- Description: "The requested bucket name is not available. The bucket name can not be an existing collection, and the bucket namespace is shared by all users of the system. Please select a different name and try again.",
- HTTPStatusCode: http.StatusConflict,
- },
- ErrBucketAlreadyOwnedByYou: {
- Code: "BucketAlreadyOwnedByYou",
- Description: "Your previous request to create the named bucket succeeded and you already own it.",
- HTTPStatusCode: http.StatusConflict,
- },
- ErrInvalidBucketName: {
- Code: "InvalidBucketName",
- Description: "The specified bucket is not valid.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidDigest: {
- Code: "InvalidDigest",
- Description: "The Content-Md5 you specified is not valid.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidMaxUploads: {
- Code: "InvalidArgument",
- Description: "Argument max-uploads must be an integer between 0 and 2147483647",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidMaxKeys: {
- Code: "InvalidArgument",
- Description: "Argument maxKeys must be an integer between 0 and 2147483647",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidMaxParts: {
- Code: "InvalidArgument",
- Description: "Argument max-parts must be an integer between 0 and 2147483647",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidMaxDeleteObjects: {
- Code: "InvalidArgument",
- Description: "Argument objects can contain a list of up to 1000 keys",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidPartNumberMarker: {
- Code: "InvalidArgument",
- Description: "Argument partNumberMarker must be an integer.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrNoSuchBucket: {
- Code: "NoSuchBucket",
- Description: "The specified bucket does not exist",
- HTTPStatusCode: http.StatusNotFound,
- },
- ErrNoSuchBucketPolicy: {
- Code: "NoSuchBucketPolicy",
- Description: "The bucket policy does not exist",
- HTTPStatusCode: http.StatusNotFound,
- },
- ErrNoSuchTagSet: {
- Code: "NoSuchTagSet",
- Description: "The TagSet does not exist",
- HTTPStatusCode: http.StatusNotFound,
- },
- ErrNoSuchCORSConfiguration: {
- Code: "NoSuchCORSConfiguration",
- Description: "The CORS configuration does not exist",
- HTTPStatusCode: http.StatusNotFound,
- },
- ErrNoSuchLifecycleConfiguration: {
- Code: "NoSuchLifecycleConfiguration",
- Description: "The lifecycle configuration does not exist",
- HTTPStatusCode: http.StatusNotFound,
- },
- ErrNoSuchKey: {
- Code: "NoSuchKey",
- Description: "The specified key does not exist.",
- HTTPStatusCode: http.StatusNotFound,
- },
- ErrNoSuchUpload: {
- Code: "NoSuchUpload",
- Description: "The specified multipart upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.",
- HTTPStatusCode: http.StatusNotFound,
- },
- ErrInternalError: {
- Code: "InternalError",
- Description: "We encountered an internal error, please try again.",
- HTTPStatusCode: http.StatusInternalServerError,
- },
- ErrInvalidPart: {
- Code: "InvalidPart",
- Description: "One or more of the specified parts could not be found. The part may not have been uploaded, or the specified entity tag may not match the part's entity tag.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidCopyDest: {
- Code: "InvalidRequest",
- Description: "This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidCopySource: {
- Code: "InvalidArgument",
- Description: "Copy Source must mention the source bucket and key: sourcebucket/sourcekey.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidTag: {
- Code: "InvalidTag",
- Description: "The Tag value you have provided is invalid",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMalformedXML: {
- Code: "MalformedXML",
- Description: "The XML you provided was not well-formed or did not validate against our published schema.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrAuthHeaderEmpty: {
- Code: "InvalidArgument",
- Description: "Authorization header is invalid -- one and only one ' ' (space) required.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrSignatureVersionNotSupported: {
- Code: "InvalidRequest",
- Description: "The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMalformedPOSTRequest: {
- Code: "MalformedPOSTRequest",
- Description: "The body of your POST request is not well-formed multipart/form-data.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrPOSTFileRequired: {
- Code: "InvalidArgument",
- Description: "POST requires exactly one file upload per request.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrPostPolicyConditionInvalidFormat: {
- Code: "PostPolicyInvalidKeyName",
- Description: "Invalid according to Policy: Policy Condition failed",
- HTTPStatusCode: http.StatusForbidden,
- },
- ErrEntityTooSmall: {
- Code: "EntityTooSmall",
- Description: "Your proposed upload is smaller than the minimum allowed object size.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrEntityTooLarge: {
- Code: "EntityTooLarge",
- Description: "Your proposed upload exceeds the maximum allowed object size.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMissingFields: {
- Code: "MissingFields",
- Description: "Missing fields in request.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMissingCredTag: {
- Code: "InvalidRequest",
- Description: "Missing Credential field for this request.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrCredMalformed: {
- Code: "AuthorizationQueryParametersError",
- Description: "Error parsing the X-Amz-Credential parameter; the Credential is mal-formed; expecting \"<YOUR-AKID>/YYYYMMDD/REGION/SERVICE/aws4_request\".",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMalformedDate: {
- Code: "MalformedDate",
- Description: "Invalid date format header, expected to be in ISO8601, RFC1123 or RFC1123Z time format.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMalformedPresignedDate: {
- Code: "AuthorizationQueryParametersError",
- Description: "X-Amz-Date must be in the ISO8601 Long Format \"yyyyMMdd'T'HHmmss'Z'\"",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMissingSignHeadersTag: {
- Code: "InvalidArgument",
- Description: "Signature header missing SignedHeaders field.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMissingSignTag: {
- Code: "AccessDenied",
- Description: "Signature header missing Signature field.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrUnsignedHeaders: {
- Code: "AccessDenied",
- Description: "There were headers present in the request which were not signed",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidQueryParams: {
- Code: "AuthorizationQueryParametersError",
- Description: "Query-string authentication version 4 requires the X-Amz-Algorithm, X-Amz-Credential, X-Amz-Signature, X-Amz-Date, X-Amz-SignedHeaders, and X-Amz-Expires parameters.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidQuerySignatureAlgo: {
- Code: "AuthorizationQueryParametersError",
- Description: "X-Amz-Algorithm only supports \"AWS4-HMAC-SHA256\".",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrExpiredPresignRequest: {
- Code: "AccessDenied",
- Description: "Request has expired",
- HTTPStatusCode: http.StatusForbidden,
- },
- ErrMalformedExpires: {
- Code: "AuthorizationQueryParametersError",
- Description: "X-Amz-Expires should be a number",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrNegativeExpires: {
- Code: "AuthorizationQueryParametersError",
- Description: "X-Amz-Expires must be non-negative",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMaximumExpires: {
- Code: "AuthorizationQueryParametersError",
- Description: "X-Amz-Expires must be less than a week (in seconds); that is, the given X-Amz-Expires must be less than 604800 seconds",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidAccessKeyID: {
- Code: "InvalidAccessKeyId",
- Description: "The access key ID you provided does not exist in our records.",
- HTTPStatusCode: http.StatusForbidden,
- },
- ErrRequestNotReadyYet: {
- Code: "AccessDenied",
- Description: "Request is not valid yet",
- HTTPStatusCode: http.StatusForbidden,
- },
- ErrSignatureDoesNotMatch: {
- Code: "SignatureDoesNotMatch",
- Description: "The request signature we calculated does not match the signature you provided. Check your key and signing method.",
- HTTPStatusCode: http.StatusForbidden,
- },
- ErrContentSHA256Mismatch: {
- Code: "XAmzContentSHA256Mismatch",
- Description: "The provided 'x-amz-content-sha256' header does not match what was computed.",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrMissingDateHeader: {
- Code: "AccessDenied",
- Description: "AWS authentication requires a valid Date or x-amz-date header",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidRequest: {
- Code: "InvalidRequest",
- Description: "Invalid Request",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrInvalidRange: {
- Code: "InvalidRange",
- Description: "The requested range is not satisfiable",
- HTTPStatusCode: http.StatusRequestedRangeNotSatisfiable,
- },
- ErrAuthNotSetup: {
- Code: "InvalidRequest",
- Description: "Signed request requires setting up SeaweedFS S3 authentication",
- HTTPStatusCode: http.StatusBadRequest,
- },
- ErrNotImplemented: {
- Code: "NotImplemented",
- Description: "A header you provided implies functionality that is not implemented",
- HTTPStatusCode: http.StatusNotImplemented,
- },
- ErrPreconditionFailed: {
- Code: "PreconditionFailed",
- Description: "At least one of the pre-conditions you specified did not hold",
- HTTPStatusCode: http.StatusPreconditionFailed,
- },
- ErrExistingObjectIsDirectory: {
- Code: "ExistingObjectIsDirectory",
- Description: "Existing Object is a directory.",
- HTTPStatusCode: http.StatusConflict,
- },
- ErrExistingObjectIsFile: {
- Code: "ExistingObjectIsFile",
- Description: "Existing Object is a file.",
- HTTPStatusCode: http.StatusConflict,
- },
- ErrTooManyRequest: {
- Code: "ErrTooManyRequest",
- Description: "Too many simultaneous request count",
- HTTPStatusCode: http.StatusTooManyRequests,
- },
- ErrRequestBytesExceed: {
- Code: "ErrRequestBytesExceed",
- Description: "Simultaneous request bytes exceed limitations",
- HTTPStatusCode: http.StatusTooManyRequests,
- },
- OwnershipControlsNotFoundError: {
- Code: "OwnershipControlsNotFoundError",
- Description: "The bucket ownership controls were not found",
- HTTPStatusCode: http.StatusNotFound,
- },
- }
- // GetAPIError provides API Error for input API error code.
- func GetAPIError(code ErrorCode) APIError {
- return errorCodeResponse[code]
- }
|