Merge pull request #847 from harshavardhana/enhance-signature-handler

Enhance signature handler - throw back valid error messages
This commit is contained in:
Harshavardhana 2015-09-18 15:17:08 -07:00
commit b59d7882ef
9 changed files with 182 additions and 84 deletions

View File

@ -29,35 +29,35 @@ func (api Minio) isValidOp(w http.ResponseWriter, req *http.Request, acceptsCont
bucket := vars["bucket"] bucket := vars["bucket"]
bucketMetadata, err := api.Donut.GetBucketMetadata(bucket, nil) bucketMetadata, err := api.Donut.GetBucketMetadata(bucket, nil)
if err == nil { if err != nil {
if _, err := StripAccessKeyID(req.Header.Get("Authorization")); err != nil { switch err.ToGoError().(type) {
if bucketMetadata.ACL.IsPrivate() { case donut.BucketNotFound:
return true writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path)
//uncomment this when we have webcli return false
//writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) case donut.BucketNameInvalid:
//return false writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path)
} return false
if bucketMetadata.ACL.IsPublicRead() && req.Method == "PUT" { default:
return true // log.Error.Println(err.Trace())
//uncomment this when we have webcli writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
//writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) return false
//return false
}
} }
return true
} }
switch err.ToGoError().(type) { if _, err = stripAccessKeyID(req.Header.Get("Authorization")); err != nil {
case donut.BucketNotFound: if bucketMetadata.ACL.IsPrivate() {
writeErrorResponse(w, req, NoSuchBucket, acceptsContentType, req.URL.Path) return true
return false //uncomment this when we have webcli
case donut.BucketNameInvalid: //writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path)
writeErrorResponse(w, req, InvalidBucketName, acceptsContentType, req.URL.Path) //return false
return false }
default: if bucketMetadata.ACL.IsPublicRead() && req.Method == "PUT" {
// log.Error.Println(err.Trace()) return true
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) //uncomment this when we have webcli
return false //writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path)
//return false
}
} }
return true
} }
// ListMultipartUploadsHandler - GET Bucket (List Multipart uploads) // ListMultipartUploadsHandler - GET Bucket (List Multipart uploads)
@ -98,7 +98,7 @@ func (api Minio) ListMultipartUploadsHandler(w http.ResponseWriter, req *http.Re
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -169,7 +169,7 @@ func (api Minio) ListObjectsHandler(w http.ResponseWriter, req *http.Request) {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -230,7 +230,7 @@ func (api Minio) ListBucketsHandler(w http.ResponseWriter, req *http.Request) {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -296,7 +296,7 @@ func (api Minio) PutBucketHandler(w http.ResponseWriter, req *http.Request) {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -364,7 +364,7 @@ func (api Minio) PutBucketACLHandler(w http.ResponseWriter, req *http.Request) {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -414,7 +414,7 @@ func (api Minio) HeadBucketHandler(w http.ResponseWriter, req *http.Request) {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return

View File

@ -69,38 +69,39 @@ const (
MethodNotAllowed MethodNotAllowed
InvalidPart InvalidPart
InvalidPartOrder InvalidPartOrder
AuthorizationHeaderMalformed
) )
// Error codes, non exhaustive list - standard HTTP errors // Error codes, non exhaustive list - standard HTTP errors
const ( const (
NotAcceptable = iota + 29 NotAcceptable = iota + 30
) )
// Error code to Error structure map // Error code to Error structure map
var errorCodeResponse = map[int]Error{ var errorCodeResponse = map[int]Error{
InvalidMaxUploads: { InvalidMaxUploads: {
Code: "InvalidArgument", Code: "InvalidArgument",
Description: "Argument maxUploads must be an integer between 0 and 2147483647", Description: "Argument maxUploads must be an integer between 0 and 2147483647.",
HTTPStatusCode: http.StatusBadRequest, HTTPStatusCode: http.StatusBadRequest,
}, },
InvalidMaxKeys: { InvalidMaxKeys: {
Code: "InvalidArgument", Code: "InvalidArgument",
Description: "Argument maxKeys must be an integer between 0 and 2147483647", Description: "Argument maxKeys must be an integer between 0 and 2147483647.",
HTTPStatusCode: http.StatusBadRequest, HTTPStatusCode: http.StatusBadRequest,
}, },
InvalidMaxParts: { InvalidMaxParts: {
Code: "InvalidArgument", Code: "InvalidArgument",
Description: "Argument maxParts must be an integer between 1 and 10000", Description: "Argument maxParts must be an integer between 1 and 10000.",
HTTPStatusCode: http.StatusBadRequest, HTTPStatusCode: http.StatusBadRequest,
}, },
InvalidPartNumberMarker: { InvalidPartNumberMarker: {
Code: "InvalidArgument", Code: "InvalidArgument",
Description: "Argument partNumberMarker must be an integer", Description: "Argument partNumberMarker must be an integer.",
HTTPStatusCode: http.StatusBadRequest, HTTPStatusCode: http.StatusBadRequest,
}, },
AccessDenied: { AccessDenied: {
Code: "AccessDenied", Code: "AccessDenied",
Description: "Access Denied", Description: "Access Denied.",
HTTPStatusCode: http.StatusForbidden, HTTPStatusCode: http.StatusForbidden,
}, },
BadDigest: { BadDigest: {
@ -125,7 +126,7 @@ var errorCodeResponse = map[int]Error{
}, },
IncompleteBody: { IncompleteBody: {
Code: "IncompleteBody", Code: "IncompleteBody",
Description: "You did not provide the number of bytes specified by the Content-Length HTTP header", Description: "You did not provide the number of bytes specified by the Content-Length HTTP header.",
HTTPStatusCode: http.StatusBadRequest, HTTPStatusCode: http.StatusBadRequest,
}, },
InternalError: { InternalError: {
@ -215,7 +216,7 @@ var errorCodeResponse = map[int]Error{
}, },
InvalidPart: { InvalidPart: {
Code: "InvalidPart", Code: "InvalidPart",
Description: "One or more of the specified parts could not be found", Description: "One or more of the specified parts could not be found.",
HTTPStatusCode: http.StatusBadRequest, HTTPStatusCode: http.StatusBadRequest,
}, },
InvalidPartOrder: { InvalidPartOrder: {
@ -223,6 +224,11 @@ var errorCodeResponse = map[int]Error{
Description: "The list of parts was not in ascending order. The parts list must be specified in order by part number.", Description: "The list of parts was not in ascending order. The parts list must be specified in order by part number.",
HTTPStatusCode: http.StatusBadRequest, HTTPStatusCode: http.StatusBadRequest,
}, },
AuthorizationHeaderMalformed: {
Code: "AuthorizationHeaderMalformed",
Description: "The authorization header is malformed; the region is wrong; expecting 'milkyway'.",
HTTPStatusCode: http.StatusBadRequest,
},
} }
// errorCodeError provides errorCode to Error. It returns empty if the code provided is unknown // errorCodeError provides errorCode to Error. It returns empty if the code provided is unknown

View File

@ -122,9 +122,9 @@ func (h timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.handler.ServeHTTP(w, r) h.handler.ServeHTTP(w, r)
} }
// ValidateAuthHeaderHandler - // ValidateAuthHeaderHandler - validate auth header handler is wrapper handler used
// validate auth header handler is wrapper handler used for request validation with authorization header. // for request validation with authorization header. Current authorization layer
// Current authorization layer supports S3's standard HMAC based signature request. // supports S3's standard HMAC based signature request.
func ValidateAuthHeaderHandler(h http.Handler) http.Handler { func ValidateAuthHeaderHandler(h http.Handler) http.Handler {
return validateAuthHandler{h} return validateAuthHandler{h}
} }
@ -132,8 +132,14 @@ func ValidateAuthHeaderHandler(h http.Handler) http.Handler {
// validate auth header handler ServeHTTP() wrapper // validate auth header handler ServeHTTP() wrapper
func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
acceptsContentType := getContentType(r) acceptsContentType := getContentType(r)
accessKeyID, err := StripAccessKeyID(r.Header.Get("Authorization")) accessKeyID, err := stripAccessKeyID(r.Header.Get("Authorization"))
switch err.(type) { switch err.ToGoError() {
case errInvalidRegion:
writeErrorResponse(w, r, AuthorizationHeaderMalformed, acceptsContentType, r.URL.Path)
return
case errAccessKeyIDInvalid:
writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path)
return
case nil: case nil:
// load auth config // load auth config
authConfig, err := auth.LoadConfig() authConfig, err := auth.LoadConfig()
@ -150,6 +156,7 @@ func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path) writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path)
return return
// All other errors for now, serve them
default: default:
// control reaches here, we should just send the request up the stack - internally // control reaches here, we should just send the request up the stack - internally
// individual calls will validate themselves against un-authenticated requests // individual calls will validate themselves against un-authenticated requests

View File

@ -57,7 +57,7 @@ func (api Minio) GetObjectHandler(w http.ResponseWriter, req *http.Request) {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -124,7 +124,7 @@ func (api Minio) HeadObjectHandler(w http.ResponseWriter, req *http.Request) {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -218,7 +218,7 @@ func (api Minio) PutObjectHandler(w http.ResponseWriter, req *http.Request) {
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -288,7 +288,7 @@ func (api Minio) NewMultipartUploadHandler(w http.ResponseWriter, req *http.Requ
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -382,7 +382,7 @@ func (api Minio) PutObjectPartHandler(w http.ResponseWriter, req *http.Request)
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -442,7 +442,7 @@ func (api Minio) AbortMultipartUploadHandler(w http.ResponseWriter, req *http.Re
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -503,7 +503,7 @@ func (api Minio) ListObjectPartsHandler(w http.ResponseWriter, req *http.Request
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return
@ -557,7 +557,7 @@ func (api Minio) CompleteMultipartUploadHandler(w http.ResponseWriter, req *http
if _, ok := req.Header["Authorization"]; ok { if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification // Init signature V4 verification
var err *probe.Error var err *probe.Error
signature, err = InitSignatureV4(req) signature, err = initSignatureV4(req)
if err != nil { if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return return

View File

@ -30,50 +30,75 @@ const (
authHeaderPrefix = "AWS4-HMAC-SHA256" authHeaderPrefix = "AWS4-HMAC-SHA256"
) )
// StripAccessKeyID - strip only access key id from auth header // getCredentialsFromAuth parse credentials tag from authorization value
func StripAccessKeyID(ah string) (string, error) { func getCredentialsFromAuth(authValue string) ([]string, *probe.Error) {
if ah == "" { if authValue == "" {
return "", errors.New("Missing auth header") return nil, probe.NewError(errMissingAuthHeaderValue)
} }
authFields := strings.Split(strings.TrimSpace(ah), ",") authFields := strings.Split(strings.TrimSpace(authValue), ",")
if len(authFields) != 3 { if len(authFields) != 3 {
return "", errors.New("Missing fields in Auth header") return nil, probe.NewError(errInvalidAuthHeaderValue)
} }
authPrefixFields := strings.Fields(authFields[0]) authPrefixFields := strings.Fields(authFields[0])
if len(authPrefixFields) != 2 { if len(authPrefixFields) != 2 {
return "", errors.New("Missing fields in Auth header") return nil, probe.NewError(errMissingFieldsAuthHeader)
} }
if authPrefixFields[0] != authHeaderPrefix { if authPrefixFields[0] != authHeaderPrefix {
return "", errors.New("Missing fields is Auth header") return nil, probe.NewError(errInvalidAuthHeaderPrefix)
} }
credentials := strings.Split(strings.TrimSpace(authPrefixFields[1]), "=") credentials := strings.Split(strings.TrimSpace(authPrefixFields[1]), "=")
if len(credentials) != 2 { if len(credentials) != 2 {
return "", errors.New("Missing fields in Auth header") return nil, probe.NewError(errMissingFieldsCredentialTag)
} }
if len(strings.Split(strings.TrimSpace(authFields[1]), "=")) != 2 { if len(strings.Split(strings.TrimSpace(authFields[1]), "=")) != 2 {
return "", errors.New("Missing fields in Auth header") return nil, probe.NewError(errMissingFieldsSignedHeadersTag)
} }
if len(strings.Split(strings.TrimSpace(authFields[2]), "=")) != 2 { if len(strings.Split(strings.TrimSpace(authFields[2]), "=")) != 2 {
return "", errors.New("Missing fields in Auth header") return nil, probe.NewError(errMissingFieldsSignatureTag)
} }
accessKeyID := strings.Split(strings.TrimSpace(credentials[1]), "/")[0] credentialElements := strings.Split(strings.TrimSpace(credentials[1]), "/")
if len(credentialElements) != 5 {
return nil, probe.NewError(errCredentialTagMalformed)
}
return credentialElements, nil
}
// verify if authHeader value has valid region
func isValidRegion(authHeaderValue string) *probe.Error {
credentialElements, err := getCredentialsFromAuth(authHeaderValue)
if err != nil {
return err.Trace()
}
region := credentialElements[2]
if region != "milkyway" {
return probe.NewError(errInvalidRegion)
}
return nil
}
// stripAccessKeyID - strip only access key id from auth header
func stripAccessKeyID(authHeaderValue string) (string, *probe.Error) {
if err := isValidRegion(authHeaderValue); err != nil {
return "", err.Trace()
}
credentialElements, err := getCredentialsFromAuth(authHeaderValue)
if err != nil {
return "", err.Trace()
}
accessKeyID := credentialElements[0]
if !auth.IsValidAccessKey(accessKeyID) { if !auth.IsValidAccessKey(accessKeyID) {
return "", errors.New("Invalid access key") return "", probe.NewError(errAccessKeyIDInvalid)
} }
return accessKeyID, nil return accessKeyID, nil
} }
// InitSignatureV4 initializing signature verification // initSignatureV4 initializing signature verification
func InitSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) { func initSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) {
// strip auth from authorization header // strip auth from authorization header
ah := req.Header.Get("Authorization") authHeaderValue := req.Header.Get("Authorization")
var accessKeyID string accessKeyID, err := stripAccessKeyID(authHeaderValue)
{ if err != nil {
var err error return nil, err.Trace()
accessKeyID, err = StripAccessKeyID(ah)
if err != nil {
return nil, probe.NewError(err)
}
} }
authConfig, err := auth.LoadConfig() authConfig, err := auth.LoadConfig()
if err != nil { if err != nil {
@ -84,11 +109,11 @@ func InitSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) {
signature := &donut.Signature{ signature := &donut.Signature{
AccessKeyID: user.AccessKeyID, AccessKeyID: user.AccessKeyID,
SecretAccessKey: user.SecretAccessKey, SecretAccessKey: user.SecretAccessKey,
AuthHeader: ah, AuthHeader: authHeaderValue,
Request: req, Request: req,
} }
return signature, nil return signature, nil
} }
} }
return nil, probe.NewError(errors.New("AccessID not found")) return nil, probe.NewError(errors.New("AccessKeyID not found"))
} }

View File

@ -0,0 +1,60 @@
/*
* Minio Cloud Storage, (C) 2015 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package api
import "errors"
// errMissingAuthHeader means that Authorization header
// has missing value or it is empty
var errMissingAuthHeaderValue = errors.New("Missing auth header value")
// errInvalidAuthHeaderValue means that Authorization
// header is available but is malformed and not in
// accordance with signature v4
var errInvalidAuthHeaderValue = errors.New("Invalid auth header value")
// errInvalidAuthHeaderPrefix means that Authorization header
// has a wrong prefix only supported value should be "AWS4-HMAC-SHA256"
var errInvalidAuthHeaderPrefix = errors.New("Invalid auth header prefix")
// errMissingFieldsAuthHeader means that Authorization
// header is available but has some missing fields
var errMissingFieldsAuthHeader = errors.New("Missing fields in auth header")
// errMissingFieldsCredentialTag means that Authorization
// header credentials tag has some missing fields
var errMissingFieldsCredentialTag = errors.New("Missing fields in crendential tag")
// errMissingFieldsSignedHeadersTag means that Authorization
// header signed headers tag has some missing fields
var errMissingFieldsSignedHeadersTag = errors.New("Missing fields in signed headers tag")
// errMissingFieldsSignatureTag means that Authorization
// header signature tag has missing fields
var errMissingFieldsSignatureTag = errors.New("Missing fields in signature tag")
// errCredentialTagMalformed means that Authorization header
// credential tag is malformed
var errCredentialTagMalformed = errors.New("Invalid credential tag malformed")
// errInvalidRegion means that the region element from credential tag
// in Authorization header is invalid
var errInvalidRegion = errors.New("Invalid region")
// errAccessKeyIDInvalid means that the accessKeyID element from
// credential tag in Authorization header is invalid
var errAccessKeyIDInvalid = errors.New("AccessKeyID invalid")

View File

@ -560,7 +560,7 @@ func (s *MyAPIDonutCacheSuite) TestListObjectsHandlerErrors(c *C) {
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
verifyError(c, response, "InvalidArgument", "Argument maxKeys must be an integer between 0 and 2147483647", http.StatusBadRequest) verifyError(c, response, "InvalidArgument", "Argument maxKeys must be an integer between 0 and 2147483647.", http.StatusBadRequest)
} }
func (s *MyAPIDonutCacheSuite) TestPutBucketErrors(c *C) { func (s *MyAPIDonutCacheSuite) TestPutBucketErrors(c *C) {
@ -805,7 +805,7 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartList(c *C) {
response4, err := client.Do(request) response4, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
verifyError(c, response4, "InvalidArgument", "Argument maxParts must be an integer between 1 and 10000", http.StatusBadRequest) verifyError(c, response4, "InvalidArgument", "Argument maxParts must be an integer between 1 and 10000.", http.StatusBadRequest)
} }
func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) { func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {

View File

@ -580,7 +580,7 @@ func (s *MyAPIDonutSuite) TestListObjectsHandlerErrors(c *C) {
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
verifyError(c, response, "InvalidArgument", "Argument maxKeys must be an integer between 0 and 2147483647", http.StatusBadRequest) verifyError(c, response, "InvalidArgument", "Argument maxKeys must be an integer between 0 and 2147483647.", http.StatusBadRequest)
} }
func (s *MyAPIDonutSuite) TestPutBucketErrors(c *C) { func (s *MyAPIDonutSuite) TestPutBucketErrors(c *C) {
@ -825,7 +825,7 @@ func (s *MyAPIDonutSuite) TestObjectMultipartList(c *C) {
response4, err := client.Do(request) response4, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
verifyError(c, response4, "InvalidArgument", "Argument maxParts must be an integer between 1 and 10000", http.StatusBadRequest) verifyError(c, response4, "InvalidArgument", "Argument maxParts must be an integer between 1 and 10000.", http.StatusBadRequest)
} }
func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) { func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {

View File

@ -572,7 +572,7 @@ func (s *MyAPISignatureV4Suite) TestListObjectsHandlerErrors(c *C) {
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
verifyError(c, response, "InvalidArgument", "Argument maxKeys must be an integer between 0 and 2147483647", http.StatusBadRequest) verifyError(c, response, "InvalidArgument", "Argument maxKeys must be an integer between 0 and 2147483647.", http.StatusBadRequest)
} }
func (s *MyAPISignatureV4Suite) TestPutBucketErrors(c *C) { func (s *MyAPISignatureV4Suite) TestPutBucketErrors(c *C) {
@ -824,7 +824,7 @@ func (s *MyAPISignatureV4Suite) TestObjectMultipartList(c *C) {
response4, err := client.Do(request) response4, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
verifyError(c, response4, "InvalidArgument", "Argument maxParts must be an integer between 1 and 10000", http.StatusBadRequest) verifyError(c, response4, "InvalidArgument", "Argument maxParts must be an integer between 1 and 10000.", http.StatusBadRequest)
} }
func (s *MyAPISignatureV4Suite) TestObjectMultipart(c *C) { func (s *MyAPISignatureV4Suite) TestObjectMultipart(c *C) {