diff --git a/pkg/api/api_bucket_handlers.go b/pkg/api/api_bucket_handlers.go index 9e25a9ba8..a1c5aceb0 100644 --- a/pkg/api/api_bucket_handlers.go +++ b/pkg/api/api_bucket_handlers.go @@ -43,18 +43,19 @@ func (server *minioAPI) isValidOp(w http.ResponseWriter, req *http.Request, acce return false } case nil: - - if stripAccessKey(req) == "" && bucketMetadata.ACL.IsPrivate() { - return true - // Uncomment this before release - // writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) - // return false - } - if bucketMetadata.ACL.IsPublicRead() && req.Method == "PUT" { - return true - // Uncomment this before release - // writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) - // return false + if _, err := stripAuth(req); err != nil { + if bucketMetadata.ACL.IsPrivate() { + return true + //uncomment this when we have webcli + //writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) + //return false + } + if bucketMetadata.ACL.IsPublicRead() && req.Method == "PUT" { + return true + //uncomment this when we have webcli + //writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) + //return false + } } } return true @@ -126,7 +127,12 @@ func (server *minioAPI) listBucketsHandler(w http.ResponseWriter, req *http.Requ writeErrorResponse(w, req, NotAcceptable, acceptsContentType, req.URL.Path) return } - + // uncomment this when we have webcli + // without access key credentials one cannot list buckets + // if _, err := stripAuth(req); err != nil { + // writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) + // return + // } buckets, err := server.driver.ListBuckets() switch err := iodine.ToError(err).(type) { case nil: @@ -154,17 +160,21 @@ func (server *minioAPI) listBucketsHandler(w http.ResponseWriter, req *http.Requ // ---------- // This implementation of the PUT operation creates a new bucket for authenticated request func (server *minioAPI) putBucketHandler(w http.ResponseWriter, req *http.Request) { - if isRequestBucketACL(req.URL.Query()) { - server.putBucketACLHandler(w, req) - return - } - acceptsContentType := getContentType(req) if acceptsContentType == unknownContentType { writeErrorResponse(w, req, NotAcceptable, acceptsContentType, req.URL.Path) return } - + // uncomment this when we have webcli + // without access key credentials one cannot create a bucket + // if _, err := stripAuth(req); err != nil { + // writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) + // return + // } + if isRequestBucketACL(req.URL.Query()) { + server.putBucketACLHandler(w, req) + return + } // read from 'x-amz-acl' aclType := getACLType(req) if aclType == unsupportedACLType { diff --git a/pkg/api/api_generic_handlers.go b/pkg/api/api_generic_handlers.go index a8efcb7f2..103a317c0 100644 --- a/pkg/api/api_generic_handlers.go +++ b/pkg/api/api_generic_handlers.go @@ -29,7 +29,7 @@ type timeHandler struct { handler http.Handler } -type validateHandler struct { +type validateAuthHandler struct { conf config.Config handler http.Handler } @@ -38,19 +38,46 @@ type resourceHandler struct { handler http.Handler } -// strip AccessKey from authorization header -func stripAccessKey(r *http.Request) string { - fields := strings.Fields(r.Header.Get("Authorization")) - if len(fields) < 2 { - return "" - } - splits := strings.Split(fields[1], ":") - if len(splits) < 2 { - return "" - } - return splits[0] +type auth struct { + prefix string + credential string + signedheaders string + signature string + accessKey string } +// strip auth from authorization header +func stripAuth(r *http.Request) (*auth, error) { + authHeader := r.Header.Get("Authorization") + if authHeader == "" { + return nil, errors.New("Missing auth header") + } + a := new(auth) + authFields := strings.Fields(authHeader) + if len(authFields) < 4 { + return nil, errors.New("Missing fields in Auth header") + } + a.prefix = authFields[0] + credentials := strings.Split(authFields[1], ",")[0] + if len(credentials) < 2 { + return nil, errors.New("Missing fields in Auth header") + } + signedheaders := strings.Split(authFields[2], ",")[0] + if len(signedheaders) < 2 { + return nil, errors.New("Missing fields in Auth header") + } + signature := authFields[3] + a.credential = strings.Split(credentials, "=")[1] + a.signedheaders = strings.Split(signedheaders, "=")[1] + a.signature = strings.Split(signature, "=")[1] + a.accessKey = strings.Split(a.credential, "/")[0] + return a, nil +} + +const ( + timeFormat = "20060102T150405Z" +) + func getDate(req *http.Request) (time.Time, error) { amzDate := req.Header.Get("X-Amz-Date") switch { @@ -61,6 +88,9 @@ func getDate(req *http.Request) (time.Time, error) { if _, err := time.Parse(time.RFC1123Z, amzDate); err == nil { return time.Parse(time.RFC1123Z, amzDate) } + if _, err := time.Parse(timeFormat, amzDate); err == nil { + return time.Parse(timeFormat, amzDate) + } } date := req.Header.Get("Date") switch { @@ -71,6 +101,9 @@ func getDate(req *http.Request) (time.Time, error) { if _, err := time.Parse(time.RFC1123Z, date); err == nil { return time.Parse(time.RFC1123Z, date) } + if _, err := time.Parse(timeFormat, amzDate); err == nil { + return time.Parse(timeFormat, amzDate) + } } return time.Time{}, errors.New("invalid request") } @@ -86,7 +119,6 @@ func (h timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } // Verify if date headers are set, if not reject the request - if r.Header.Get("Authorization") != "" { if r.Header.Get("X-Amz-Date") == "" && r.Header.Get("Date") == "" { // there is no way to knowing if this is a valid request, could be a attack reject such clients @@ -109,60 +141,42 @@ func (h timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.handler.ServeHTTP(w, r) } -// Validate handler is wrapper handler used for API request validation with authorization header. +// validate auth header handler is wrapper handler used for API request validation with authorization header. // Current authorization layer supports S3's standard HMAC based signature request. -func validateRequestHandler(conf config.Config, h http.Handler) http.Handler { - return validateHandler{ +func validateAuthHeaderHandler(conf config.Config, h http.Handler) http.Handler { + return validateAuthHandler{ conf: conf, handler: h, } } -// Validate handler ServeHTTP() wrapper -func (h validateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { +// validate auth header handler ServeHTTP() wrapper +func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { acceptsContentType := getContentType(r) if acceptsContentType == unknownContentType { writeErrorResponse(w, r, NotAcceptable, acceptsContentType, r.URL.Path) return } - // success - h.handler.ServeHTTP(w, r) - - // Enable below only when webcli is ready - - /* - switch true { - case accessKey != "": - if err := h.conf.ReadConfig(); err != nil { - writeErrorResponse(w, r, InternalError, acceptsContentType, r.URL.Path) - return - } - user, ok := h.conf.Users[accessKey] - if !ok { - writeErrorResponse(w, r, AccessDenied, acceptsContentType, r.URL.Path) - return - } - ok, _ = ValidateRequest(user, r) - if !ok { - writeErrorResponse(w, r, AccessDenied, acceptsContentType, r.URL.Path) - return - } - // Success - h.handler.ServeHTTP(w, r) - default: - // Control reaches when no access key is found, ideally we would - // like to throw back `403`. But for now with our tests lacking - // this functionality it is better for us to be serving anonymous - // requests as well. - // We should remove this after adding tests to support signature request - h.handler.ServeHTTP(w, r) - // ## Uncommented below links of code after disabling anonymous requests - // error := errorCodeError(AccessDenied) - // errorResponse := getErrorResponse(error, "") - // w.WriteHeader(error.HTTPStatusCode) - // w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) + _, err := stripAuth(r) + switch err.(type) { + case nil: + if err := h.conf.ReadConfig(); err != nil { + writeErrorResponse(w, r, InternalError, acceptsContentType, r.URL.Path) + return } - */ + // uncomment this when we have webcli + // _, ok := h.conf.Users[auth.accessKey] + //if !ok { + // writeErrorResponse(w, r, AccessDenied, acceptsContentType, r.URL.Path) + // return + //} + // Success + h.handler.ServeHTTP(w, r) + default: + // control reaches here, we should just send the request up the stack - internally + // individual calls will validate themselves against un-authenticated requests + h.handler.ServeHTTP(w, r) + } } // Ignore resources handler is wrapper handler used for API request resource validation diff --git a/pkg/api/api_object_handlers.go b/pkg/api/api_object_handlers.go index 696752117..f95c9d2de 100644 --- a/pkg/api/api_object_handlers.go +++ b/pkg/api/api_object_handlers.go @@ -44,6 +44,7 @@ func (server *minioAPI) getObjectHandler(w http.ResponseWriter, req *http.Reques return } + // verify if this operation is allowed if !server.isValidOp(w, req, acceptsContentType) { return } @@ -105,6 +106,7 @@ func (server *minioAPI) headObjectHandler(w http.ResponseWriter, req *http.Reque return } + // verify if this operation is allowed if !server.isValidOp(w, req, acceptsContentType) { return } @@ -147,7 +149,7 @@ func (server *minioAPI) putObjectHandler(w http.ResponseWriter, req *http.Reques return } - // handle ACL's here at bucket level + // verify if this operation is allowed if !server.isValidOp(w, req, acceptsContentType) { return } @@ -276,17 +278,20 @@ func (server *minioAPI) putObjectPartHandler(w http.ResponseWriter, req *http.Re writeErrorResponse(w, req, InvalidDigest, acceptsContentType, req.URL.Path) return } + /// if Content-Length missing, throw away size := req.Header.Get("Content-Length") if size == "" { writeErrorResponse(w, req, MissingContentLength, acceptsContentType, req.URL.Path) return } + /// maximum Upload size for multipart objects in a single operation if isMaxObjectSize(size) { writeErrorResponse(w, req, EntityTooLarge, acceptsContentType, req.URL.Path) return } + // last part can be less than < 5MB so we need to figure out a way to handle it first // and then enable below code (y4m4) // @@ -295,6 +300,7 @@ func (server *minioAPI) putObjectPartHandler(w http.ResponseWriter, req *http.Re // writeErrorResponse(w, req, EntityTooSmall, acceptsContentType, req.URL.Path) // return // } + sizeInt64, err := strconv.ParseInt(size, 10, 64) if err != nil { writeErrorResponse(w, req, InvalidRequest, acceptsContentType, req.URL.Path) diff --git a/pkg/api/api_router.go b/pkg/api/api_router.go index dceabee3d..9c745ebb5 100644 --- a/pkg/api/api_router.go +++ b/pkg/api/api_router.go @@ -63,12 +63,12 @@ func HTTPHandler(driver drivers.Driver) http.Handler { } h := timeValidityHandler(mux) h = ignoreResourcesHandler(h) - h = validateRequestHandler(conf, h) + h = validateAuthHeaderHandler(conf, h) // h = quota.BandwidthCap(h, 25*1024*1024, time.Duration(30*time.Minute)) // h = quota.BandwidthCap(h, 100*1024*1024, time.Duration(24*time.Hour)) // h = quota.RequestLimit(h, 100, time.Duration(30*time.Minute)) // h = quota.RequestLimit(h, 1000, time.Duration(24*time.Hour)) - h = quota.ConnectionLimit(h, 5) + h = quota.ConnectionLimit(h, 2) h = logging.LogHandler(h) return h } diff --git a/pkg/api/api_signature.go b/pkg/api/api_signature.go deleted file mode 100644 index 380c9b95f..000000000 --- a/pkg/api/api_signature.go +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Minimalist Object Storage, (C) 2014,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 ( - "bytes" - "crypto/hmac" - "crypto/sha1" - "encoding/base64" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "sort" - "strings" - "time" - - "github.com/minio-io/minio/pkg/api/config" -) - -// SignRequest - a given http request using HMAC style signatures -func SignRequest(user config.User, req *http.Request) { - if date := req.Header.Get("Date"); date == "" { - req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) - } - hm := hmac.New(sha1.New, []byte(user.SecretKey)) - ss := getStringToSign(req) - io.WriteString(hm, ss) - - authHeader := new(bytes.Buffer) - fmt.Fprintf(authHeader, "AWS %s:", user.AccessKey) - encoder := base64.NewEncoder(base64.StdEncoding, authHeader) - encoder.Write(hm.Sum(nil)) - encoder.Close() - req.Header.Set("Authorization", authHeader.String()) -} - -// ValidateRequest - an API request by validating its signature using HMAC signatures -func ValidateRequest(user config.User, req *http.Request) (bool, error) { - // Verify if date headers are set, if not reject the request - if req.Header.Get("x-amz-date") == "" { - if req.Header.Get("Date") == "" { - return false, errors.New("Date should be set") - } - } - hm := hmac.New(sha1.New, []byte(user.SecretKey)) - ss := getStringToSign(req) - io.WriteString(hm, ss) - - authHeader := new(bytes.Buffer) - fmt.Fprintf(authHeader, "AWS %s:", user.AccessKey) - encoder := base64.NewEncoder(base64.StdEncoding, authHeader) - encoder.Write(hm.Sum(nil)) - encoder.Close() - - // DEBUG - // fmt.Println("Request header sent: ", req.Header.Get("Authorization")) - // fmt.Println("Header calculated: ", authHeader.String()) - // fmt.Printf("%q : %x", ss, ss) - if req.Header.Get("Authorization") != authHeader.String() { - return false, errors.New("Authorization header mismatch") - } - return true, nil -} - -// From the Amazon docs: -// -// StringToSign = HTTP-Verb + "\n" + -// Content-MD5 + "\n" + -// Content-Type + "\n" + -// Date + "\n" + -// CanonicalizedAmzHeaders + -// CanonicalizedResource; -func getStringToSign(req *http.Request) string { - buf := new(bytes.Buffer) - buf.WriteString(req.Method) - buf.WriteByte('\n') - buf.WriteString(req.Header.Get("Content-MD5")) - buf.WriteByte('\n') - buf.WriteString(req.Header.Get("Content-Type")) - buf.WriteByte('\n') - if req.Header.Get("x-amz-date") == "" { - buf.WriteString(req.Header.Get("Date")) - } - buf.WriteByte('\n') - writeCanonicalizedAmzHeaders(buf, req) - writeCanonicalizedResource(buf, req) - - return buf.String() -} - -// Lower all upper case letters -func hasPrefixCaseInsensitive(s, pfx string) bool { - if len(pfx) > len(s) { - return false - } - shead := s[:len(pfx)] - if shead == pfx { - return true - } - shead = strings.ToLower(shead) - return shead == pfx || shead == strings.ToLower(pfx) -} - -// Canonicalize amazon special headers, headers starting with 'x-amz-' -func writeCanonicalizedAmzHeaders(buf *bytes.Buffer, req *http.Request) { - var amzHeaders []string - vals := make(map[string][]string) - for k, vv := range req.Header { - if hasPrefixCaseInsensitive(k, "x-amz-") { - lk := strings.ToLower(k) - amzHeaders = append(amzHeaders, lk) - vals[lk] = vv - } - } - sort.Strings(amzHeaders) - for _, k := range amzHeaders { - buf.WriteString(k) - buf.WriteByte(':') - for idx, v := range vals[k] { - if idx > 0 { - buf.WriteByte(',') - } - if strings.Contains(v, "\n") { - // TODO: "Unfold" long headers that - // span multiple lines (as allowed by - // RFC 2616, section 4.2) by replacing - // the folding white-space (including - // new-line) by a single space. - buf.WriteString(v) - } else { - buf.WriteString(v) - } - } - buf.WriteByte('\n') - } -} - -// Resource list must be sorted: -var subResList = []string{ - "acl", - "location", - "logging", - "notification", - "partNumber", - "policy", - "uploadId", - "uploads", - "response-content-type", - "response-content-language", - "response-content-disposition", - "response-content-encoding", - "website", -} - -func url2BucketAndObject(url string) (string, string) { - var bucketName, objectName string - splits := strings.SplitN(url, "/", 3) - switch len(splits) { - case 0, 1: - bucketName = "" - objectName = "" - case 2: - bucketName = splits[1] - objectName = "" - case 3: - bucketName = splits[1] - objectName = splits[2] - } - return bucketName, objectName -} - -// From the Amazon docs: -// -// CanonicalizedResource = [ "/" + Bucket ] + -// + -// [ sub-resource, if present. For example "?acl", "?location", "?logging", or "?torrent"]; -func writeCanonicalizedResource(buf *bytes.Buffer, req *http.Request) { - bucket, _ := url2BucketAndObject(req.URL.Path) - if bucket != "" { - buf.WriteByte('/') - buf.WriteString(bucket) - } - buf.WriteString(req.URL.Path) - sort.Strings(subResList) - if req.URL.RawQuery != "" { - n := 0 - vals, _ := url.ParseQuery(req.URL.RawQuery) - for _, subres := range subResList { - if vv, ok := vals[subres]; ok && len(vv) > 0 { - n++ - if n == 1 { - buf.WriteByte('?') - } else { - buf.WriteByte('&') - } - buf.WriteString(subres) - if len(vv[0]) > 0 { - buf.WriteByte('=') - buf.WriteString(url.QueryEscape(vv[0])) - } - } - } - } -} diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index 1d192f53f..3c03910f8 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -18,9 +18,6 @@ package api import ( "bytes" - "crypto/hmac" - "crypto/sha1" - "fmt" "io" "io/ioutil" "log" @@ -31,7 +28,6 @@ import ( "testing" "time" - "encoding/base64" "encoding/xml" "net/http" "net/http/httptest" @@ -113,19 +109,10 @@ func (s *MySuite) TearDownTest(c *C) { s.Root = "" } -func setAuthHeader(req *http.Request) { - if date := req.Header.Get("Date"); date == "" { - req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) - } - hm := hmac.New(sha1.New, []byte("H+AVh8q5G7hEH2r3WxFP135+Q19Aw8yXWel8IGh/HrEjZyTNx/n4Xw==")) - ss := getStringToSign(req) - io.WriteString(hm, ss) - authHeader := new(bytes.Buffer) - fmt.Fprintf(authHeader, "AWS %s:", "AC5NH40NQLTL4D2W92PM") - encoder := base64.NewEncoder(base64.StdEncoding, authHeader) - encoder.Write(hm.Sum(nil)) - encoder.Close() - req.Header.Set("Authorization", authHeader.String()) +func setDummyAuthHeader(req *http.Request) { + authDummy := "AWS4-HMAC-SHA256 Credential=AC5NH40NQLTL4DUMMY/20130524/us-east-1/s3/aws4_request, SignedHeaders=date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class, Signature=98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd" + req.Header.Set("Authorization", authDummy) + req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) } func (s *MySuite) TestNonExistantBucket(c *C) { @@ -143,7 +130,7 @@ func (s *MySuite) TestNonExistantBucket(c *C) { s.MockDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, drivers.BucketNotFound{Bucket: "bucket"}).Once() request, err := http.NewRequest("HEAD", testServer.URL+"/bucket", nil) c.Assert(err, IsNil) - setAuthHeader(request) + //setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -184,7 +171,7 @@ func (s *MySuite) TestEmptyObject(c *C) { request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil) c.Assert(err, IsNil) - setAuthHeader(request) + //setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -225,7 +212,7 @@ func (s *MySuite) TestBucket(c *C) { request, err := http.NewRequest("HEAD", testServer.URL+"/bucket", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -267,7 +254,7 @@ func (s *MySuite) TestObject(c *C) { request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -338,7 +325,7 @@ func (s *MySuite) TestMultipleObjects(c *C) { typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNotFound{}).Once() request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -354,7 +341,7 @@ func (s *MySuite) TestMultipleObjects(c *C) { typedDriver.On("GetObject", mock.Anything, "bucket", "object1").Return(int64(0), nil).Once() request, err = http.NewRequest("GET", testServer.URL+"/bucket/object1", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client = http.Client{} response, err = client.Do(request) @@ -384,7 +371,7 @@ func (s *MySuite) TestMultipleObjects(c *C) { typedDriver.On("GetObject", mock.Anything, "bucket", "object2").Return(int64(0), nil).Once() request, err = http.NewRequest("GET", testServer.URL+"/bucket/object2", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client = http.Client{} response, err = client.Do(request) @@ -414,7 +401,7 @@ func (s *MySuite) TestMultipleObjects(c *C) { typedDriver.On("GetObject", mock.Anything, "bucket", "object3").Return(int64(0), nil).Once() request, err = http.NewRequest("GET", testServer.URL+"/bucket/object3", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client = http.Client{} response, err = client.Do(request) @@ -452,7 +439,7 @@ func (s *MySuite) TestNotImplemented(c *C) { request, err := http.NewRequest("GET", testServer.URL+"/bucket/object?policy", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -488,7 +475,7 @@ func (s *MySuite) TestHeader(c *C) { typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNotFound{}).Once() request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -516,7 +503,7 @@ func (s *MySuite) TestHeader(c *C) { typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once() request, err = http.NewRequest("GET", testServer.URL+"/bucket/object", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client = http.Client{} response, err = client.Do(request) @@ -553,7 +540,7 @@ func (s *MySuite) TestPutBucket(c *C) { request, err := http.NewRequest("PUT", testServer.URL+"/bucket", bytes.NewBufferString("")) c.Assert(err, IsNil) request.Header.Add("x-amz-acl", "private") - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -603,7 +590,7 @@ func (s *MySuite) TestPutObject(c *C) { request, err := http.NewRequest("PUT", testServer.URL+"/bucket", nil) c.Assert(err, IsNil) request.Header.Add("x-amz-acl", "private") - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -622,7 +609,7 @@ func (s *MySuite) TestPutObject(c *C) { typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything, mock.Anything).Return(twoMetadata.Md5, nil).Once() request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world")) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -673,7 +660,7 @@ func (s *MySuite) TestListBuckets(c *C) { typedDriver.On("ListBuckets").Return([]drivers.BucketMetadata{}, nil).Once() request, err := http.NewRequest("GET", testServer.URL+"/", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -694,7 +681,7 @@ func (s *MySuite) TestListBuckets(c *C) { typedDriver.On("ListBuckets").Return(bucketMetadata, nil).Once() request, err = http.NewRequest("GET", testServer.URL+"/", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client = http.Client{} response, err = client.Do(request) @@ -718,7 +705,7 @@ func (s *MySuite) TestListBuckets(c *C) { typedDriver.On("ListBuckets").Return(bucketMetadata, nil).Once() request, err = http.NewRequest("GET", testServer.URL+"/", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client = http.Client{} response, err = client.Do(request) @@ -816,7 +803,7 @@ func (s *MySuite) TestXMLNameNotInBucketListJson(c *C) { request, err := http.NewRequest("GET", testServer.URL+"/", nil) c.Assert(err, IsNil) request.Header.Add("Accept", "application/json") - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -860,7 +847,7 @@ func (s *MySuite) TestXMLNameNotInObjectListJson(c *C) { request, err := http.NewRequest("GET", testServer.URL+"/foo", nil) c.Assert(err, IsNil) request.Header.Add("Accept", "application/json") - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -910,7 +897,7 @@ func (s *MySuite) TestContentTypePersists(c *C) { request, err := http.NewRequest("PUT", testServer.URL+"/bucket/one", bytes.NewBufferString("hello world")) delete(request.Header, "Content-Type") c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -921,7 +908,7 @@ func (s *MySuite) TestContentTypePersists(c *C) { typedDriver.On("GetObjectMetadata", "bucket", "one", "").Return(oneMetadata, nil).Once() request, err = http.NewRequest("HEAD", testServer.URL+"/bucket/one", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -934,7 +921,7 @@ func (s *MySuite) TestContentTypePersists(c *C) { typedDriver.On("GetObject", mock.Anything, "bucket", "one").Return(int64(0), nil).Once() request, err = http.NewRequest("GET", testServer.URL+"/bucket/one", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) client = http.Client{} response, err = client.Do(request) @@ -958,7 +945,7 @@ func (s *MySuite) TestContentTypePersists(c *C) { delete(request.Header, "Content-Type") request.Header.Add("Content-Type", "application/json") c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -968,7 +955,7 @@ func (s *MySuite) TestContentTypePersists(c *C) { typedDriver.On("GetObjectMetadata", "bucket", "two", "").Return(twoMetadata, nil).Once() request, err = http.NewRequest("HEAD", testServer.URL+"/bucket/two", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -980,7 +967,7 @@ func (s *MySuite) TestContentTypePersists(c *C) { typedDriver.On("GetObject", mock.Anything, "bucket", "two").Return(int64(0), nil).Once() request, err = http.NewRequest("GET", testServer.URL+"/bucket/two", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1029,7 +1016,7 @@ func (s *MySuite) TestPartialContent(c *C) { c.Assert(err, IsNil) request.Header.Add("Accept", "application/json") request.Header.Add("Range", "bytes=6-7") - setAuthHeader(request) + setDummyAuthHeader(request) client := http.Client{} response, err := client.Do(request) @@ -1063,7 +1050,7 @@ func (s *MySuite) TestListObjectsHandlerErrors(c *C) { typedDriver.On("GetBucketMetadata", "foo").Return(drivers.BucketMetadata{}, drivers.BucketNameInvalid{}).Once() request, err := http.NewRequest("GET", testServer.URL+"/foo", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err := client.Do(request) c.Assert(err, IsNil) @@ -1072,7 +1059,7 @@ func (s *MySuite) TestListObjectsHandlerErrors(c *C) { typedDriver.On("GetBucketMetadata", "foo").Return(drivers.BucketMetadata{}, drivers.BucketNotFound{}).Once() request, err = http.NewRequest("GET", testServer.URL+"/foo", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) verifyError(c, response, "NoSuchBucket", "The specified bucket does not exist.", http.StatusNotFound) @@ -1081,7 +1068,7 @@ func (s *MySuite) TestListObjectsHandlerErrors(c *C) { typedDriver.On("ListObjects", "foo", mock.Anything).Return(make([]drivers.ObjectMetadata, 0), drivers.BucketResourcesMetadata{}, drivers.ObjectNameInvalid{}).Once() request, err = http.NewRequest("GET", testServer.URL+"/foo", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1091,7 +1078,7 @@ func (s *MySuite) TestListObjectsHandlerErrors(c *C) { typedDriver.On("ListObjects", "foo", mock.Anything).Return(make([]drivers.ObjectMetadata, 0), drivers.BucketResourcesMetadata{}, drivers.ObjectNotFound{}).Once() request, err = http.NewRequest("GET", testServer.URL+"/foo", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1101,7 +1088,7 @@ func (s *MySuite) TestListObjectsHandlerErrors(c *C) { typedDriver.On("ListObjects", "foo", mock.Anything).Return(make([]drivers.ObjectMetadata, 0), drivers.BucketResourcesMetadata{}, drivers.BackendCorrupted{}).Once() request, err = http.NewRequest("GET", testServer.URL+"/foo", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1138,7 +1125,7 @@ func (s *MySuite) TestListBucketsErrors(c *C) { drivers.BucketResourcesMetadata{}, drivers.BackendCorrupted{}).Once() request, err := http.NewRequest("GET", testServer.URL+"/foo", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err := client.Do(request) c.Assert(err, IsNil) @@ -1168,7 +1155,7 @@ func (s *MySuite) TestPutBucketErrors(c *C) { request, err := http.NewRequest("PUT", testServer.URL+"/foo", bytes.NewBufferString("")) c.Assert(err, IsNil) request.Header.Add("x-amz-acl", "private") - setAuthHeader(request) + setDummyAuthHeader(request) response, err := client.Do(request) c.Assert(err, IsNil) @@ -1178,7 +1165,7 @@ func (s *MySuite) TestPutBucketErrors(c *C) { request, err = http.NewRequest("PUT", testServer.URL+"/foo", bytes.NewBufferString("")) c.Assert(err, IsNil) request.Header.Add("x-amz-acl", "private") - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1188,7 +1175,7 @@ func (s *MySuite) TestPutBucketErrors(c *C) { request, err = http.NewRequest("PUT", testServer.URL+"/foo", bytes.NewBufferString("")) c.Assert(err, IsNil) request.Header.Add("x-amz-acl", "private") - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1198,7 +1185,7 @@ func (s *MySuite) TestPutBucketErrors(c *C) { request, err = http.NewRequest("PUT", testServer.URL+"/foo", bytes.NewBufferString("")) c.Assert(err, IsNil) request.Header.Add("x-amz-acl", "unknown") - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1233,7 +1220,7 @@ func (s *MySuite) TestGetObjectErrors(c *C) { typedDriver.On("GetObjectMetadata", "foo", "bar", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNotFound{}).Once() request, err := http.NewRequest("GET", testServer.URL+"/foo/bar", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err := client.Do(request) c.Assert(err, IsNil) @@ -1242,7 +1229,7 @@ func (s *MySuite) TestGetObjectErrors(c *C) { typedDriver.On("GetBucketMetadata", "foo").Return(drivers.BucketMetadata{}, drivers.BucketNotFound{}).Once() request, err = http.NewRequest("GET", testServer.URL+"/foo/bar", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1252,7 +1239,7 @@ func (s *MySuite) TestGetObjectErrors(c *C) { typedDriver.On("GetObjectMetadata", "foo", "bar", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNameInvalid{}).Once() request, err = http.NewRequest("GET", testServer.URL+"/foo/bar", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1261,7 +1248,7 @@ func (s *MySuite) TestGetObjectErrors(c *C) { typedDriver.On("GetBucketMetadata", "foo").Return(drivers.BucketMetadata{}, drivers.BucketNameInvalid{}).Once() request, err = http.NewRequest("GET", testServer.URL+"/foo/bar", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1271,7 +1258,7 @@ func (s *MySuite) TestGetObjectErrors(c *C) { typedDriver.On("GetObjectMetadata", "foo", "bar", "").Return(drivers.ObjectMetadata{}, drivers.BackendCorrupted{}).Once() request, err = http.NewRequest("GET", testServer.URL+"/foo/bar", nil) c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err = client.Do(request) c.Assert(err, IsNil) @@ -1312,7 +1299,7 @@ func (s *MySuite) TestGetObjectRangeErrors(c *C) { request, err := http.NewRequest("GET", testServer.URL+"/foo/bar", nil) request.Header.Add("Range", "bytes=7-6") c.Assert(err, IsNil) - setAuthHeader(request) + setDummyAuthHeader(request) response, err := client.Do(request) c.Assert(err, IsNil) @@ -1347,6 +1334,8 @@ func (s *MySuite) TestPutMultipart(c *C) { typedDriver.On("CreateBucket", "foo", "private").Return(nil).Once() request, err := http.NewRequest("PUT", testServer.URL+"/foo", bytes.NewBufferString("")) c.Assert(err, IsNil) + setDummyAuthHeader(request) + response, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, 200) @@ -1356,6 +1345,8 @@ func (s *MySuite) TestPutMultipart(c *C) { typedDriver.On("NewMultipartUpload", "foo", "object", "").Return("uploadid", nil).Once() request, err = http.NewRequest("POST", testServer.URL+"/foo/object?uploads", bytes.NewBufferString("")) c.Assert(err, IsNil) + setDummyAuthHeader(request) + response, err = client.Do(request) c.Assert(response.StatusCode, Equals, http.StatusOK) @@ -1372,6 +1363,8 @@ func (s *MySuite) TestPutMultipart(c *C) { typedDriver.On("CreateObjectPart", "foo", "object", "uploadid", 1, "", "", 11, mock.Anything).Return("5eb63bbbe01eeed093cb22bb8f5acdc3", nil).Once() request, err = http.NewRequest("PUT", testServer.URL+"/foo/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) c.Assert(err, IsNil) + setDummyAuthHeader(request) + response1, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response1.StatusCode, Equals, http.StatusOK) @@ -1381,6 +1374,8 @@ func (s *MySuite) TestPutMultipart(c *C) { typedDriver.On("CreateObjectPart", "foo", "object", "uploadid", 2, "", "", 11, mock.Anything).Return("5eb63bbbe01eeed093cb22bb8f5acdc3", nil).Once() request, err = http.NewRequest("PUT", testServer.URL+"/foo/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) c.Assert(err, IsNil) + setDummyAuthHeader(request) + response2, err := client.Do(request) c.Assert(err, IsNil) c.Assert(response2.StatusCode, Equals, http.StatusOK) @@ -1407,6 +1402,8 @@ func (s *MySuite) TestPutMultipart(c *C) { typedDriver.On("CompleteMultipartUpload", "foo", "object", "uploadid", mock.Anything).Return("etag", nil).Once() request, err = http.NewRequest("POST", testServer.URL+"/foo/object?uploadId="+uploadID, &completeBuffer) c.Assert(err, IsNil) + setDummyAuthHeader(request) + response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) @@ -1418,6 +1415,8 @@ func (s *MySuite) TestPutMultipart(c *C) { typedDriver.SetGetObjectWriter("foo", "object", []byte("hello worldhello world")) request, err = http.NewRequest("GET", testServer.URL+"/foo/object", nil) c.Assert(err, IsNil) + setDummyAuthHeader(request) + response, err = client.Do(request) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK)