Remove SignatureV2 support, bring in SignatureV4 header only validation for now

This commit is contained in:
Harshavardhana 2015-04-30 19:29:03 -04:00
parent 01c1bd6fc5
commit f45635524f
6 changed files with 165 additions and 356 deletions

View file

@ -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 {

View file

@ -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

View file

@ -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)

View file

@ -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
}

View file

@ -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 ] +
// <HTTP-Request-URI, from the protocol name up to the query string> +
// [ 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]))
}
}
}
}
}

View file

@ -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)