Merge pull request #727 from harshavardhana/pr_out_all_other_api_s_now_support_signature_v4

All other API's now support signature v4
This commit is contained in:
Harshavardhana 2015-07-10 02:47:32 +00:00
commit eac92d4647
16 changed files with 652 additions and 491 deletions

View File

@ -87,6 +87,24 @@ type PartMetadata struct {
Size int64 Size int64
} }
// CompletePart - completed part container
type CompletePart struct {
PartNumber int
ETag string
}
// completedParts is a sortable interface for Part slice
type completedParts []CompletePart
func (a completedParts) Len() int { return len(a) }
func (a completedParts) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a completedParts) Less(i, j int) bool { return a[i].PartNumber < a[j].PartNumber }
// CompleteMultipartUpload container for completing multipart upload
type CompleteMultipartUpload struct {
Part []CompletePart
}
// ObjectResourcesMetadata - various types of object resources // ObjectResourcesMetadata - various types of object resources
type ObjectResourcesMetadata struct { type ObjectResourcesMetadata struct {
Bucket string Bucket string

View File

@ -74,7 +74,7 @@ func (s *MyDonutSuite) SetUpSuite(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
// testing empty donut // testing empty donut
buckets, err := dd.ListBuckets() buckets, err := dd.ListBuckets(nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(buckets), Equals, 0) c.Assert(len(buckets), Equals, 0)
} }
@ -86,20 +86,20 @@ func (s *MyDonutSuite) TearDownSuite(c *C) {
// test make bucket without name // test make bucket without name
func (s *MyDonutSuite) TestBucketWithoutNameFails(c *C) { func (s *MyDonutSuite) TestBucketWithoutNameFails(c *C) {
// fail to create new bucket without a name // fail to create new bucket without a name
err := dd.MakeBucket("", "private") err := dd.MakeBucket("", "private", nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
err = dd.MakeBucket(" ", "private") err = dd.MakeBucket(" ", "private", nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
} }
// test empty bucket // test empty bucket
func (s *MyDonutSuite) TestEmptyBucket(c *C) { func (s *MyDonutSuite) TestEmptyBucket(c *C) {
c.Assert(dd.MakeBucket("foo1", "private"), IsNil) c.Assert(dd.MakeBucket("foo1", "private", nil), IsNil)
// check if bucket is empty // check if bucket is empty
var resources BucketResourcesMetadata var resources BucketResourcesMetadata
resources.Maxkeys = 1 resources.Maxkeys = 1
objectsMetadata, resources, err := dd.ListObjects("foo1", resources) objectsMetadata, resources, err := dd.ListObjects("foo1", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(objectsMetadata), Equals, 0) c.Assert(len(objectsMetadata), Equals, 0)
c.Assert(resources.CommonPrefixes, DeepEquals, []string{}) c.Assert(resources.CommonPrefixes, DeepEquals, []string{})
@ -109,11 +109,11 @@ func (s *MyDonutSuite) TestEmptyBucket(c *C) {
// test bucket list // test bucket list
func (s *MyDonutSuite) TestMakeBucketAndList(c *C) { func (s *MyDonutSuite) TestMakeBucketAndList(c *C) {
// create bucket // create bucket
err := dd.MakeBucket("foo2", "private") err := dd.MakeBucket("foo2", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
// check bucket exists // check bucket exists
buckets, err := dd.ListBuckets() buckets, err := dd.ListBuckets(nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(buckets), Equals, 5) c.Assert(len(buckets), Equals, 5)
c.Assert(buckets[0].ACL, Equals, BucketACL("private")) c.Assert(buckets[0].ACL, Equals, BucketACL("private"))
@ -121,33 +121,33 @@ func (s *MyDonutSuite) TestMakeBucketAndList(c *C) {
// test re-create bucket // test re-create bucket
func (s *MyDonutSuite) TestMakeBucketWithSameNameFails(c *C) { func (s *MyDonutSuite) TestMakeBucketWithSameNameFails(c *C) {
err := dd.MakeBucket("foo3", "private") err := dd.MakeBucket("foo3", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
err = dd.MakeBucket("foo3", "private") err = dd.MakeBucket("foo3", "private", nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
} }
// test make multiple buckets // test make multiple buckets
func (s *MyDonutSuite) TestCreateMultipleBucketsAndList(c *C) { func (s *MyDonutSuite) TestCreateMultipleBucketsAndList(c *C) {
// add a second bucket // add a second bucket
err := dd.MakeBucket("foo4", "private") err := dd.MakeBucket("foo4", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
err = dd.MakeBucket("bar1", "private") err = dd.MakeBucket("bar1", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
buckets, err := dd.ListBuckets() buckets, err := dd.ListBuckets(nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(buckets), Equals, 2) c.Assert(len(buckets), Equals, 2)
c.Assert(buckets[0].Name, Equals, "bar1") c.Assert(buckets[0].Name, Equals, "bar1")
c.Assert(buckets[1].Name, Equals, "foo4") c.Assert(buckets[1].Name, Equals, "foo4")
err = dd.MakeBucket("foobar1", "private") err = dd.MakeBucket("foobar1", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
buckets, err = dd.ListBuckets() buckets, err = dd.ListBuckets(nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(buckets), Equals, 3) c.Assert(len(buckets), Equals, 3)
@ -156,7 +156,7 @@ func (s *MyDonutSuite) TestCreateMultipleBucketsAndList(c *C) {
// test object create without bucket // test object create without bucket
func (s *MyDonutSuite) TestNewObjectFailsWithoutBucket(c *C) { func (s *MyDonutSuite) TestNewObjectFailsWithoutBucket(c *C) {
_, err := dd.CreateObject("unknown", "obj", "", 0, nil, nil) _, err := dd.CreateObject("unknown", "obj", "", 0, nil, nil, nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
} }
@ -168,10 +168,10 @@ func (s *MyDonutSuite) TestNewObjectMetadata(c *C) {
expectedMd5Sum := base64.StdEncoding.EncodeToString(hasher.Sum(nil)) expectedMd5Sum := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
reader := ioutil.NopCloser(bytes.NewReader([]byte(data))) reader := ioutil.NopCloser(bytes.NewReader([]byte(data)))
err := dd.MakeBucket("foo6", "private") err := dd.MakeBucket("foo6", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
objectMetadata, err := dd.CreateObject("foo6", "obj", expectedMd5Sum, int64(len(data)), reader, map[string]string{"contentType": "application/json"}) objectMetadata, err := dd.CreateObject("foo6", "obj", expectedMd5Sum, int64(len(data)), reader, map[string]string{"contentType": "application/json"}, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(objectMetadata.MD5Sum, Equals, hex.EncodeToString(hasher.Sum(nil))) c.Assert(objectMetadata.MD5Sum, Equals, hex.EncodeToString(hasher.Sum(nil)))
c.Assert(objectMetadata.Metadata["contentType"], Equals, "application/json") c.Assert(objectMetadata.Metadata["contentType"], Equals, "application/json")
@ -179,13 +179,13 @@ func (s *MyDonutSuite) TestNewObjectMetadata(c *C) {
// test create object fails without name // test create object fails without name
func (s *MyDonutSuite) TestNewObjectFailsWithEmptyName(c *C) { func (s *MyDonutSuite) TestNewObjectFailsWithEmptyName(c *C) {
_, err := dd.CreateObject("foo", "", "", 0, nil, nil) _, err := dd.CreateObject("foo", "", "", 0, nil, nil, nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
} }
// test create object // test create object
func (s *MyDonutSuite) TestNewObjectCanBeWritten(c *C) { func (s *MyDonutSuite) TestNewObjectCanBeWritten(c *C) {
err := dd.MakeBucket("foo", "private") err := dd.MakeBucket("foo", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
data := "Hello World" data := "Hello World"
@ -195,7 +195,7 @@ func (s *MyDonutSuite) TestNewObjectCanBeWritten(c *C) {
expectedMd5Sum := base64.StdEncoding.EncodeToString(hasher.Sum(nil)) expectedMd5Sum := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
reader := ioutil.NopCloser(bytes.NewReader([]byte(data))) reader := ioutil.NopCloser(bytes.NewReader([]byte(data)))
actualMetadata, err := dd.CreateObject("foo", "obj", expectedMd5Sum, int64(len(data)), reader, map[string]string{"contentType": "application/octet-stream"}) actualMetadata, err := dd.CreateObject("foo", "obj", expectedMd5Sum, int64(len(data)), reader, map[string]string{"contentType": "application/octet-stream"}, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(actualMetadata.MD5Sum, Equals, hex.EncodeToString(hasher.Sum(nil))) c.Assert(actualMetadata.MD5Sum, Equals, hex.EncodeToString(hasher.Sum(nil)))
@ -205,7 +205,7 @@ func (s *MyDonutSuite) TestNewObjectCanBeWritten(c *C) {
c.Assert(size, Equals, int64(len(data))) c.Assert(size, Equals, int64(len(data)))
c.Assert(buffer.Bytes(), DeepEquals, []byte(data)) c.Assert(buffer.Bytes(), DeepEquals, []byte(data))
actualMetadata, err = dd.GetObjectMetadata("foo", "obj") actualMetadata, err = dd.GetObjectMetadata("foo", "obj", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(hex.EncodeToString(hasher.Sum(nil)), Equals, actualMetadata.MD5Sum) c.Assert(hex.EncodeToString(hasher.Sum(nil)), Equals, actualMetadata.MD5Sum)
c.Assert(int64(len(data)), Equals, actualMetadata.Size) c.Assert(int64(len(data)), Equals, actualMetadata.Size)
@ -213,15 +213,15 @@ func (s *MyDonutSuite) TestNewObjectCanBeWritten(c *C) {
// test list objects // test list objects
func (s *MyDonutSuite) TestMultipleNewObjects(c *C) { func (s *MyDonutSuite) TestMultipleNewObjects(c *C) {
c.Assert(dd.MakeBucket("foo5", "private"), IsNil) c.Assert(dd.MakeBucket("foo5", "private", nil), IsNil)
one := ioutil.NopCloser(bytes.NewReader([]byte("one"))) one := ioutil.NopCloser(bytes.NewReader([]byte("one")))
_, err := dd.CreateObject("foo5", "obj1", "", int64(len("one")), one, nil) _, err := dd.CreateObject("foo5", "obj1", "", int64(len("one")), one, nil, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
two := ioutil.NopCloser(bytes.NewReader([]byte("two"))) two := ioutil.NopCloser(bytes.NewReader([]byte("two")))
_, err = dd.CreateObject("foo5", "obj2", "", int64(len("two")), two, nil) _, err = dd.CreateObject("foo5", "obj2", "", int64(len("two")), two, nil, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
var buffer1 bytes.Buffer var buffer1 bytes.Buffer
@ -244,7 +244,7 @@ func (s *MyDonutSuite) TestMultipleNewObjects(c *C) {
resources.Prefix = "o" resources.Prefix = "o"
resources.Delimiter = "1" resources.Delimiter = "1"
resources.Maxkeys = 10 resources.Maxkeys = 10
objectsMetadata, resources, err := dd.ListObjects("foo5", resources) objectsMetadata, resources, err := dd.ListObjects("foo5", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(resources.IsTruncated, Equals, false) c.Assert(resources.IsTruncated, Equals, false)
c.Assert(resources.CommonPrefixes[0], Equals, "obj1") c.Assert(resources.CommonPrefixes[0], Equals, "obj1")
@ -253,7 +253,7 @@ func (s *MyDonutSuite) TestMultipleNewObjects(c *C) {
resources.Prefix = "" resources.Prefix = ""
resources.Delimiter = "1" resources.Delimiter = "1"
resources.Maxkeys = 10 resources.Maxkeys = 10
objectsMetadata, resources, err = dd.ListObjects("foo5", resources) objectsMetadata, resources, err = dd.ListObjects("foo5", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(objectsMetadata[0].Object, Equals, "obj2") c.Assert(objectsMetadata[0].Object, Equals, "obj2")
c.Assert(resources.IsTruncated, Equals, false) c.Assert(resources.IsTruncated, Equals, false)
@ -263,14 +263,14 @@ func (s *MyDonutSuite) TestMultipleNewObjects(c *C) {
resources.Prefix = "o" resources.Prefix = "o"
resources.Delimiter = "" resources.Delimiter = ""
resources.Maxkeys = 10 resources.Maxkeys = 10
objectsMetadata, resources, err = dd.ListObjects("foo5", resources) objectsMetadata, resources, err = dd.ListObjects("foo5", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(resources.IsTruncated, Equals, false) c.Assert(resources.IsTruncated, Equals, false)
c.Assert(objectsMetadata[0].Object, Equals, "obj1") c.Assert(objectsMetadata[0].Object, Equals, "obj1")
c.Assert(objectsMetadata[1].Object, Equals, "obj2") c.Assert(objectsMetadata[1].Object, Equals, "obj2")
three := ioutil.NopCloser(bytes.NewReader([]byte("three"))) three := ioutil.NopCloser(bytes.NewReader([]byte("three")))
_, err = dd.CreateObject("foo5", "obj3", "", int64(len("three")), three, nil) _, err = dd.CreateObject("foo5", "obj3", "", int64(len("three")), three, nil, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
var buffer bytes.Buffer var buffer bytes.Buffer
@ -283,7 +283,7 @@ func (s *MyDonutSuite) TestMultipleNewObjects(c *C) {
resources.Prefix = "o" resources.Prefix = "o"
resources.Delimiter = "" resources.Delimiter = ""
resources.Maxkeys = 2 resources.Maxkeys = 2
objectsMetadata, resources, err = dd.ListObjects("foo5", resources) objectsMetadata, resources, err = dd.ListObjects("foo5", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(resources.IsTruncated, Equals, true) c.Assert(resources.IsTruncated, Equals, true)
c.Assert(len(objectsMetadata), Equals, 2) c.Assert(len(objectsMetadata), Equals, 2)

View File

@ -25,7 +25,6 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http"
"runtime/debug" "runtime/debug"
"sort" "sort"
"strconv" "strconv"
@ -33,6 +32,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/minio/minio/pkg/crypto/sha256"
"github.com/minio/minio/pkg/donut/cache/data" "github.com/minio/minio/pkg/donut/cache/data"
"github.com/minio/minio/pkg/donut/cache/metadata" "github.com/minio/minio/pkg/donut/cache/metadata"
"github.com/minio/minio/pkg/iodine" "github.com/minio/minio/pkg/iodine"
@ -55,7 +55,6 @@ type Config struct {
// API - local variables // API - local variables
type API struct { type API struct {
config *Config config *Config
req *http.Request
lock *sync.Mutex lock *sync.Mutex
objects *data.Cache objects *data.Cache
multiPartObjects map[string]*data.Cache multiPartObjects map[string]*data.Cache
@ -124,11 +123,6 @@ func New() (Interface, error) {
return a, nil return a, nil
} }
// SetRequest API for setting request header
func (donut API) SetRequest(req *http.Request) {
donut.req = req
}
// GetObject - GET object from cache buffer // GetObject - GET object from cache buffer
func (donut API) GetObject(w io.Writer, bucket string, object string) (int64, error) { func (donut API) GetObject(w io.Writer, bucket string, object string) (int64, error) {
donut.lock.Lock() donut.lock.Lock()
@ -186,6 +180,7 @@ func (donut API) GetPartialObject(w io.Writer, bucket, object string, start, len
"start": strconv.FormatInt(start, 10), "start": strconv.FormatInt(start, 10),
"length": strconv.FormatInt(length, 10), "length": strconv.FormatInt(length, 10),
} }
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
return 0, iodine.New(BucketNameInvalid{Bucket: bucket}, errParams) return 0, iodine.New(BucketNameInvalid{Bucket: bucket}, errParams)
} }
@ -232,10 +227,20 @@ func (donut API) GetPartialObject(w io.Writer, bucket, object string, start, len
} }
// GetBucketMetadata - // GetBucketMetadata -
func (donut API) GetBucketMetadata(bucket string) (BucketMetadata, error) { func (donut API) GetBucketMetadata(bucket string, signature *Signature) (BucketMetadata, error) {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return BucketMetadata{}, iodine.New(err, nil)
}
if !ok {
return BucketMetadata{}, iodine.New(SignatureDoesNotMatch{}, nil)
}
}
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
return BucketMetadata{}, iodine.New(BucketNameInvalid{Bucket: bucket}, nil) return BucketMetadata{}, iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
} }
@ -255,10 +260,20 @@ func (donut API) GetBucketMetadata(bucket string) (BucketMetadata, error) {
} }
// SetBucketMetadata - // SetBucketMetadata -
func (donut API) SetBucketMetadata(bucket string, metadata map[string]string) error { func (donut API) SetBucketMetadata(bucket string, metadata map[string]string, signature *Signature) error {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return iodine.New(err, nil)
}
if !ok {
return iodine.New(SignatureDoesNotMatch{}, nil)
}
}
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
return iodine.New(BucketNameInvalid{Bucket: bucket}, nil) return iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
} }
@ -296,12 +311,12 @@ func isMD5SumEqual(expectedMD5Sum, actualMD5Sum string) error {
} }
// CreateObject - create an object // CreateObject - create an object
func (donut API) CreateObject(bucket, key, expectedMD5Sum string, size int64, data io.Reader, metadata map[string]string) (ObjectMetadata, error) { func (donut API) CreateObject(bucket, key, expectedMD5Sum string, size int64, data io.Reader, metadata map[string]string, signature *Signature) (ObjectMetadata, error) {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
contentType := metadata["contentType"] contentType := metadata["contentType"]
objectMetadata, err := donut.createObject(bucket, key, contentType, expectedMD5Sum, size, data) objectMetadata, err := donut.createObject(bucket, key, contentType, expectedMD5Sum, size, data, signature)
// free // free
debug.FreeOSMemory() debug.FreeOSMemory()
@ -309,7 +324,7 @@ func (donut API) CreateObject(bucket, key, expectedMD5Sum string, size int64, da
} }
// createObject - PUT object to cache buffer // createObject - PUT object to cache buffer
func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, size int64, data io.Reader) (ObjectMetadata, error) { func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *Signature) (ObjectMetadata, error) {
if len(donut.config.NodeDiskMap) == 0 { if len(donut.config.NodeDiskMap) == 0 {
if size > int64(donut.config.MaxSize) { if size > int64(donut.config.MaxSize) {
generic := GenericObjectError{Bucket: bucket, Object: key} generic := GenericObjectError{Bucket: bucket, Object: key}
@ -369,6 +384,7 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
} }
// calculate md5 // calculate md5
hash := md5.New() hash := md5.New()
sha256hash := sha256.New()
var err error var err error
var totalLength int64 var totalLength int64
@ -376,12 +392,8 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
var length int var length int
byteBuffer := make([]byte, 1024*1024) byteBuffer := make([]byte, 1024*1024)
length, err = data.Read(byteBuffer) length, err = data.Read(byteBuffer)
// While hash.Write() wouldn't mind a Nil byteBuffer
// It is necessary for us to verify this and break
if length == 0 {
break
}
hash.Write(byteBuffer[0:length]) hash.Write(byteBuffer[0:length])
sha256hash.Write(byteBuffer[0:length])
ok := donut.objects.Append(objectKey, byteBuffer[0:length]) ok := donut.objects.Append(objectKey, byteBuffer[0:length])
if !ok { if !ok {
return ObjectMetadata{}, iodine.New(InternalError{}, nil) return ObjectMetadata{}, iodine.New(InternalError{}, nil)
@ -405,6 +417,15 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
return ObjectMetadata{}, iodine.New(BadDigest{}, nil) return ObjectMetadata{}, iodine.New(BadDigest{}, nil)
} }
} }
if signature != nil {
ok, err := signature.DoesSignatureMatch(hex.EncodeToString(sha256hash.Sum(nil)))
if err != nil {
return ObjectMetadata{}, iodine.New(err, nil)
}
if !ok {
return ObjectMetadata{}, iodine.New(SignatureDoesNotMatch{}, nil)
}
}
m := make(map[string]string) m := make(map[string]string)
m["contentType"] = contentType m["contentType"] = contentType
@ -424,10 +445,20 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
} }
// MakeBucket - create bucket in cache // MakeBucket - create bucket in cache
func (donut API) MakeBucket(bucketName, acl string) error { func (donut API) MakeBucket(bucketName, acl string, signature *Signature) error {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return iodine.New(err, nil)
}
if !ok {
return iodine.New(SignatureDoesNotMatch{}, nil)
}
}
if donut.storedBuckets.Stats().Items == totalBuckets { if donut.storedBuckets.Stats().Items == totalBuckets {
return iodine.New(TooManyBuckets{Bucket: bucketName}, nil) return iodine.New(TooManyBuckets{Bucket: bucketName}, nil)
} }
@ -463,10 +494,20 @@ func (donut API) MakeBucket(bucketName, acl string) error {
} }
// ListObjects - list objects from cache // ListObjects - list objects from cache
func (donut API) ListObjects(bucket string, resources BucketResourcesMetadata) ([]ObjectMetadata, BucketResourcesMetadata, error) { func (donut API) ListObjects(bucket string, resources BucketResourcesMetadata, signature *Signature) ([]ObjectMetadata, BucketResourcesMetadata, error) {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return nil, BucketResourcesMetadata{}, iodine.New(err, nil)
}
if !ok {
return nil, BucketResourcesMetadata{}, iodine.New(SignatureDoesNotMatch{}, nil)
}
}
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
return nil, BucketResourcesMetadata{IsTruncated: false}, iodine.New(BucketNameInvalid{Bucket: bucket}, nil) return nil, BucketResourcesMetadata{IsTruncated: false}, iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
} }
@ -556,10 +597,20 @@ func (b byBucketName) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (b byBucketName) Less(i, j int) bool { return b[i].Name < b[j].Name } func (b byBucketName) Less(i, j int) bool { return b[i].Name < b[j].Name }
// ListBuckets - List buckets from cache // ListBuckets - List buckets from cache
func (donut API) ListBuckets() ([]BucketMetadata, error) { func (donut API) ListBuckets(signature *Signature) ([]BucketMetadata, error) {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return nil, iodine.New(err, nil)
}
if !ok {
return nil, iodine.New(SignatureDoesNotMatch{}, nil)
}
}
var results []BucketMetadata var results []BucketMetadata
if len(donut.config.NodeDiskMap) > 0 { if len(donut.config.NodeDiskMap) > 0 {
buckets, err := donut.listBuckets() buckets, err := donut.listBuckets()
@ -580,10 +631,20 @@ func (donut API) ListBuckets() ([]BucketMetadata, error) {
} }
// GetObjectMetadata - get object metadata from cache // GetObjectMetadata - get object metadata from cache
func (donut API) GetObjectMetadata(bucket, key string) (ObjectMetadata, error) { func (donut API) GetObjectMetadata(bucket, key string, signature *Signature) (ObjectMetadata, error) {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return ObjectMetadata{}, iodine.New(err, nil)
}
if !ok {
return ObjectMetadata{}, iodine.New(SignatureDoesNotMatch{}, nil)
}
}
// check if bucket exists // check if bucket exists
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
return ObjectMetadata{}, iodine.New(BucketNameInvalid{Bucket: bucket}, nil) return ObjectMetadata{}, iodine.New(BucketNameInvalid{Bucket: bucket}, nil)

View File

@ -49,7 +49,7 @@ func (s *MyCacheSuite) SetUpSuite(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
// testing empty cache // testing empty cache
buckets, err := dc.ListBuckets() buckets, err := dc.ListBuckets(nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(buckets), Equals, 0) c.Assert(len(buckets), Equals, 0)
} }
@ -61,20 +61,20 @@ func (s *MyCacheSuite) TearDownSuite(c *C) {
// test make bucket without name // test make bucket without name
func (s *MyCacheSuite) TestBucketWithoutNameFails(c *C) { func (s *MyCacheSuite) TestBucketWithoutNameFails(c *C) {
// fail to create new bucket without a name // fail to create new bucket without a name
err := dc.MakeBucket("", "private") err := dc.MakeBucket("", "private", nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
err = dc.MakeBucket(" ", "private") err = dc.MakeBucket(" ", "private", nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
} }
// test empty bucket // test empty bucket
func (s *MyCacheSuite) TestEmptyBucket(c *C) { func (s *MyCacheSuite) TestEmptyBucket(c *C) {
c.Assert(dc.MakeBucket("foo1", "private"), IsNil) c.Assert(dc.MakeBucket("foo1", "private", nil), IsNil)
// check if bucket is empty // check if bucket is empty
var resources BucketResourcesMetadata var resources BucketResourcesMetadata
resources.Maxkeys = 1 resources.Maxkeys = 1
objectsMetadata, resources, err := dc.ListObjects("foo1", resources) objectsMetadata, resources, err := dc.ListObjects("foo1", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(objectsMetadata), Equals, 0) c.Assert(len(objectsMetadata), Equals, 0)
c.Assert(resources.CommonPrefixes, DeepEquals, []string{}) c.Assert(resources.CommonPrefixes, DeepEquals, []string{})
@ -84,11 +84,11 @@ func (s *MyCacheSuite) TestEmptyBucket(c *C) {
// test bucket list // test bucket list
func (s *MyCacheSuite) TestMakeBucketAndList(c *C) { func (s *MyCacheSuite) TestMakeBucketAndList(c *C) {
// create bucket // create bucket
err := dc.MakeBucket("foo2", "private") err := dc.MakeBucket("foo2", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
// check bucket exists // check bucket exists
buckets, err := dc.ListBuckets() buckets, err := dc.ListBuckets(nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(buckets), Equals, 5) c.Assert(len(buckets), Equals, 5)
c.Assert(buckets[0].ACL, Equals, BucketACL("private")) c.Assert(buckets[0].ACL, Equals, BucketACL("private"))
@ -96,33 +96,33 @@ func (s *MyCacheSuite) TestMakeBucketAndList(c *C) {
// test re-create bucket // test re-create bucket
func (s *MyCacheSuite) TestMakeBucketWithSameNameFails(c *C) { func (s *MyCacheSuite) TestMakeBucketWithSameNameFails(c *C) {
err := dc.MakeBucket("foo3", "private") err := dc.MakeBucket("foo3", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
err = dc.MakeBucket("foo3", "private") err = dc.MakeBucket("foo3", "private", nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
} }
// test make multiple buckets // test make multiple buckets
func (s *MyCacheSuite) TestCreateMultipleBucketsAndList(c *C) { func (s *MyCacheSuite) TestCreateMultipleBucketsAndList(c *C) {
// add a second bucket // add a second bucket
err := dc.MakeBucket("foo4", "private") err := dc.MakeBucket("foo4", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
err = dc.MakeBucket("bar1", "private") err = dc.MakeBucket("bar1", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
buckets, err := dc.ListBuckets() buckets, err := dc.ListBuckets(nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(buckets), Equals, 2) c.Assert(len(buckets), Equals, 2)
c.Assert(buckets[0].Name, Equals, "bar1") c.Assert(buckets[0].Name, Equals, "bar1")
c.Assert(buckets[1].Name, Equals, "foo4") c.Assert(buckets[1].Name, Equals, "foo4")
err = dc.MakeBucket("foobar1", "private") err = dc.MakeBucket("foobar1", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
buckets, err = dc.ListBuckets() buckets, err = dc.ListBuckets(nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(len(buckets), Equals, 3) c.Assert(len(buckets), Equals, 3)
@ -131,7 +131,7 @@ func (s *MyCacheSuite) TestCreateMultipleBucketsAndList(c *C) {
// test object create without bucket // test object create without bucket
func (s *MyCacheSuite) TestNewObjectFailsWithoutBucket(c *C) { func (s *MyCacheSuite) TestNewObjectFailsWithoutBucket(c *C) {
_, err := dc.CreateObject("unknown", "obj", "", 0, nil, nil) _, err := dc.CreateObject("unknown", "obj", "", 0, nil, nil, nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
} }
@ -143,10 +143,10 @@ func (s *MyCacheSuite) TestNewObjectMetadata(c *C) {
expectedMd5Sum := base64.StdEncoding.EncodeToString(hasher.Sum(nil)) expectedMd5Sum := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
reader := ioutil.NopCloser(bytes.NewReader([]byte(data))) reader := ioutil.NopCloser(bytes.NewReader([]byte(data)))
err := dc.MakeBucket("foo6", "private") err := dc.MakeBucket("foo6", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
objectMetadata, err := dc.CreateObject("foo6", "obj", expectedMd5Sum, int64(len(data)), reader, map[string]string{"contentType": "application/json"}) objectMetadata, err := dc.CreateObject("foo6", "obj", expectedMd5Sum, int64(len(data)), reader, map[string]string{"contentType": "application/json"}, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(objectMetadata.MD5Sum, Equals, hex.EncodeToString(hasher.Sum(nil))) c.Assert(objectMetadata.MD5Sum, Equals, hex.EncodeToString(hasher.Sum(nil)))
c.Assert(objectMetadata.Metadata["contentType"], Equals, "application/json") c.Assert(objectMetadata.Metadata["contentType"], Equals, "application/json")
@ -154,13 +154,13 @@ func (s *MyCacheSuite) TestNewObjectMetadata(c *C) {
// test create object fails without name // test create object fails without name
func (s *MyCacheSuite) TestNewObjectFailsWithEmptyName(c *C) { func (s *MyCacheSuite) TestNewObjectFailsWithEmptyName(c *C) {
_, err := dc.CreateObject("foo", "", "", 0, nil, nil) _, err := dc.CreateObject("foo", "", "", 0, nil, nil, nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
} }
// test create object // test create object
func (s *MyCacheSuite) TestNewObjectCanBeWritten(c *C) { func (s *MyCacheSuite) TestNewObjectCanBeWritten(c *C) {
err := dc.MakeBucket("foo", "private") err := dc.MakeBucket("foo", "private", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
data := "Hello World" data := "Hello World"
@ -170,7 +170,7 @@ func (s *MyCacheSuite) TestNewObjectCanBeWritten(c *C) {
expectedMd5Sum := base64.StdEncoding.EncodeToString(hasher.Sum(nil)) expectedMd5Sum := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
reader := ioutil.NopCloser(bytes.NewReader([]byte(data))) reader := ioutil.NopCloser(bytes.NewReader([]byte(data)))
actualMetadata, err := dc.CreateObject("foo", "obj", expectedMd5Sum, int64(len(data)), reader, map[string]string{"contentType": "application/octet-stream"}) actualMetadata, err := dc.CreateObject("foo", "obj", expectedMd5Sum, int64(len(data)), reader, map[string]string{"contentType": "application/octet-stream"}, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(actualMetadata.MD5Sum, Equals, hex.EncodeToString(hasher.Sum(nil))) c.Assert(actualMetadata.MD5Sum, Equals, hex.EncodeToString(hasher.Sum(nil)))
@ -180,7 +180,7 @@ func (s *MyCacheSuite) TestNewObjectCanBeWritten(c *C) {
c.Assert(size, Equals, int64(len(data))) c.Assert(size, Equals, int64(len(data)))
c.Assert(buffer.Bytes(), DeepEquals, []byte(data)) c.Assert(buffer.Bytes(), DeepEquals, []byte(data))
actualMetadata, err = dc.GetObjectMetadata("foo", "obj") actualMetadata, err = dc.GetObjectMetadata("foo", "obj", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(hex.EncodeToString(hasher.Sum(nil)), Equals, actualMetadata.MD5Sum) c.Assert(hex.EncodeToString(hasher.Sum(nil)), Equals, actualMetadata.MD5Sum)
c.Assert(int64(len(data)), Equals, actualMetadata.Size) c.Assert(int64(len(data)), Equals, actualMetadata.Size)
@ -188,15 +188,15 @@ func (s *MyCacheSuite) TestNewObjectCanBeWritten(c *C) {
// test list objects // test list objects
func (s *MyCacheSuite) TestMultipleNewObjects(c *C) { func (s *MyCacheSuite) TestMultipleNewObjects(c *C) {
c.Assert(dc.MakeBucket("foo5", "private"), IsNil) c.Assert(dc.MakeBucket("foo5", "private", nil), IsNil)
one := ioutil.NopCloser(bytes.NewReader([]byte("one"))) one := ioutil.NopCloser(bytes.NewReader([]byte("one")))
_, err := dc.CreateObject("foo5", "obj1", "", int64(len("one")), one, nil) _, err := dc.CreateObject("foo5", "obj1", "", int64(len("one")), one, nil, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
two := ioutil.NopCloser(bytes.NewReader([]byte("two"))) two := ioutil.NopCloser(bytes.NewReader([]byte("two")))
_, err = dc.CreateObject("foo5", "obj2", "", int64(len("two")), two, nil) _, err = dc.CreateObject("foo5", "obj2", "", int64(len("two")), two, nil, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
var buffer1 bytes.Buffer var buffer1 bytes.Buffer
@ -219,7 +219,7 @@ func (s *MyCacheSuite) TestMultipleNewObjects(c *C) {
resources.Prefix = "o" resources.Prefix = "o"
resources.Delimiter = "1" resources.Delimiter = "1"
resources.Maxkeys = 10 resources.Maxkeys = 10
objectsMetadata, resources, err := dc.ListObjects("foo5", resources) objectsMetadata, resources, err := dc.ListObjects("foo5", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(resources.IsTruncated, Equals, false) c.Assert(resources.IsTruncated, Equals, false)
c.Assert(resources.CommonPrefixes[0], Equals, "obj1") c.Assert(resources.CommonPrefixes[0], Equals, "obj1")
@ -228,7 +228,7 @@ func (s *MyCacheSuite) TestMultipleNewObjects(c *C) {
resources.Prefix = "" resources.Prefix = ""
resources.Delimiter = "1" resources.Delimiter = "1"
resources.Maxkeys = 10 resources.Maxkeys = 10
objectsMetadata, resources, err = dc.ListObjects("foo5", resources) objectsMetadata, resources, err = dc.ListObjects("foo5", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(objectsMetadata[0].Object, Equals, "obj2") c.Assert(objectsMetadata[0].Object, Equals, "obj2")
c.Assert(resources.IsTruncated, Equals, false) c.Assert(resources.IsTruncated, Equals, false)
@ -238,14 +238,14 @@ func (s *MyCacheSuite) TestMultipleNewObjects(c *C) {
resources.Prefix = "o" resources.Prefix = "o"
resources.Delimiter = "" resources.Delimiter = ""
resources.Maxkeys = 10 resources.Maxkeys = 10
objectsMetadata, resources, err = dc.ListObjects("foo5", resources) objectsMetadata, resources, err = dc.ListObjects("foo5", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(resources.IsTruncated, Equals, false) c.Assert(resources.IsTruncated, Equals, false)
c.Assert(objectsMetadata[0].Object, Equals, "obj1") c.Assert(objectsMetadata[0].Object, Equals, "obj1")
c.Assert(objectsMetadata[1].Object, Equals, "obj2") c.Assert(objectsMetadata[1].Object, Equals, "obj2")
three := ioutil.NopCloser(bytes.NewReader([]byte("three"))) three := ioutil.NopCloser(bytes.NewReader([]byte("three")))
_, err = dc.CreateObject("foo5", "obj3", "", int64(len("three")), three, nil) _, err = dc.CreateObject("foo5", "obj3", "", int64(len("three")), three, nil, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
var buffer bytes.Buffer var buffer bytes.Buffer
@ -258,7 +258,7 @@ func (s *MyCacheSuite) TestMultipleNewObjects(c *C) {
resources.Prefix = "o" resources.Prefix = "o"
resources.Delimiter = "" resources.Delimiter = ""
resources.Maxkeys = 2 resources.Maxkeys = 2
objectsMetadata, resources, err = dc.ListObjects("foo5", resources) objectsMetadata, resources, err = dc.ListObjects("foo5", resources, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(resources.IsTruncated, Equals, true) c.Assert(resources.IsTruncated, Equals, true)
c.Assert(len(objectsMetadata), Equals, 2) c.Assert(len(objectsMetadata), Equals, 2)

View File

@ -334,3 +334,19 @@ type MissingDateHeader struct{}
func (e MissingDateHeader) Error() string { func (e MissingDateHeader) Error() string {
return "Missing date header" return "Missing date header"
} }
// InvalidPartOrder parts are not ordered as Requested
type InvalidPartOrder struct {
UploadID string
}
func (e InvalidPartOrder) Error() string {
return "Invalid part order sent for " + e.UploadID
}
// MalformedXML invalid xml format
type MalformedXML struct{}
func (e MalformedXML) Error() string {
return "Malformed XML"
}

View File

@ -29,31 +29,32 @@ type Interface interface {
// ObjectStorage is a donut object storage interface // ObjectStorage is a donut object storage interface
type ObjectStorage interface { type ObjectStorage interface {
// Storage service operations // Storage service operations
GetBucketMetadata(bucket string) (BucketMetadata, error) GetBucketMetadata(bucket string, signature *Signature) (BucketMetadata, error)
SetBucketMetadata(bucket string, metadata map[string]string) error SetBucketMetadata(bucket string, metadata map[string]string, signature *Signature) error
ListBuckets() ([]BucketMetadata, error) ListBuckets(signature *Signature) ([]BucketMetadata, error)
MakeBucket(bucket string, ACL string) error MakeBucket(bucket string, ACL string, signature *Signature) error
// Bucket operations // Bucket operations
ListObjects(bucket string, resources BucketResourcesMetadata) ([]ObjectMetadata, BucketResourcesMetadata, error) ListObjects(string, BucketResourcesMetadata, *Signature) ([]ObjectMetadata, BucketResourcesMetadata, error)
// Object operations // Object operations
GetObject(w io.Writer, bucket, object string) (int64, error) GetObject(w io.Writer, bucket, object string) (int64, error)
GetPartialObject(w io.Writer, bucket, object string, start, length int64) (int64, error) GetPartialObject(w io.Writer, bucket, object string, start, length int64) (int64, error)
GetObjectMetadata(bucket, object string) (ObjectMetadata, error) GetObjectMetadata(bucket, object string, signature *Signature) (ObjectMetadata, error)
CreateObject(bucket, object, expectedMD5Sum string, size int64, reader io.Reader, metadata map[string]string) (ObjectMetadata, error) // bucket, object, expectedMD5Sum, size, reader, metadata, signature
CreateObject(string, string, string, int64, io.Reader, map[string]string, *Signature) (ObjectMetadata, error)
Multipart Multipart
} }
// Multipart API // Multipart API
type Multipart interface { type Multipart interface {
NewMultipartUpload(bucket, key, contentType string) (string, error) NewMultipartUpload(bucket, key, contentType string, signature *Signature) (string, error)
AbortMultipartUpload(bucket, key, uploadID string) error AbortMultipartUpload(bucket, key, uploadID string, signature *Signature) error
CreateObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader) (string, error) CreateObjectPart(string, string, string, int, string, string, int64, io.Reader, *Signature) (string, error)
CompleteMultipartUpload(bucket, key, uploadID string, parts map[int]string) (ObjectMetadata, error) CompleteMultipartUpload(bucket, key, uploadID string, data io.Reader, signature *Signature) (ObjectMetadata, error)
ListMultipartUploads(bucket string, resources BucketMultipartResourcesMetadata) (BucketMultipartResourcesMetadata, error) ListMultipartUploads(string, BucketMultipartResourcesMetadata, *Signature) (BucketMultipartResourcesMetadata, error)
ListObjectParts(bucket, key string, resources ObjectResourcesMetadata) (ObjectResourcesMetadata, error) ListObjectParts(string, string, ObjectResourcesMetadata, *Signature) (ObjectResourcesMetadata, error)
} }
// Management is a donut management system interface // Management is a donut management system interface

View File

@ -22,8 +22,10 @@ import (
"crypto/sha512" "crypto/sha512"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"encoding/xml"
"errors" "errors"
"io" "io"
"io/ioutil"
"math/rand" "math/rand"
"runtime/debug" "runtime/debug"
"sort" "sort"
@ -31,15 +33,26 @@ import (
"strings" "strings"
"time" "time"
"github.com/minio/minio/pkg/crypto/sha256"
"github.com/minio/minio/pkg/donut/cache/data" "github.com/minio/minio/pkg/donut/cache/data"
"github.com/minio/minio/pkg/iodine" "github.com/minio/minio/pkg/iodine"
) )
// NewMultipartUpload - initiate a new multipart session // NewMultipartUpload - initiate a new multipart session
func (donut API) NewMultipartUpload(bucket, key, contentType string) (string, error) { func (donut API) NewMultipartUpload(bucket, key, contentType string, signature *Signature) (string, error) {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return "", iodine.New(err, nil)
}
if !ok {
return "", iodine.New(SignatureDoesNotMatch{}, nil)
}
}
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
return "", iodine.New(BucketNameInvalid{Bucket: bucket}, nil) return "", iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
} }
@ -71,10 +84,20 @@ func (donut API) NewMultipartUpload(bucket, key, contentType string) (string, er
} }
// AbortMultipartUpload - abort an incomplete multipart session // AbortMultipartUpload - abort an incomplete multipart session
func (donut API) AbortMultipartUpload(bucket, key, uploadID string) error { func (donut API) AbortMultipartUpload(bucket, key, uploadID string, signature *Signature) error {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return iodine.New(err, nil)
}
if !ok {
return iodine.New(SignatureDoesNotMatch{}, nil)
}
}
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
return iodine.New(BucketNameInvalid{Bucket: bucket}, nil) return iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
} }
@ -90,11 +113,11 @@ func (donut API) AbortMultipartUpload(bucket, key, uploadID string) error {
} }
// CreateObjectPart - create a part in a multipart session // CreateObjectPart - create a part in a multipart session
func (donut API) CreateObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader) (string, error) { func (donut API) CreateObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *Signature) (string, error) {
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
etag, err := donut.createObjectPart(bucket, key, uploadID, partID, "", expectedMD5Sum, size, data) etag, err := donut.createObjectPart(bucket, key, uploadID, partID, "", expectedMD5Sum, size, data, signature)
// possible free // possible free
debug.FreeOSMemory() debug.FreeOSMemory()
@ -102,7 +125,7 @@ func (donut API) CreateObjectPart(bucket, key, uploadID string, partID int, cont
} }
// createObject - internal wrapper function called by CreateObjectPart // createObject - internal wrapper function called by CreateObjectPart
func (donut API) createObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader) (string, error) { func (donut API) createObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *Signature) (string, error) {
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
return "", iodine.New(BucketNameInvalid{Bucket: bucket}, nil) return "", iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
} }
@ -138,6 +161,7 @@ func (donut API) createObjectPart(bucket, key, uploadID string, partID int, cont
// calculate md5 // calculate md5
hash := md5.New() hash := md5.New()
sha256hash := sha256.New()
var err error var err error
var totalLength int64 var totalLength int64
@ -145,12 +169,8 @@ func (donut API) createObjectPart(bucket, key, uploadID string, partID int, cont
var length int var length int
byteBuffer := make([]byte, 1024*1024) byteBuffer := make([]byte, 1024*1024)
length, err = data.Read(byteBuffer) length, err = data.Read(byteBuffer)
// While hash.Write() wouldn't mind a Nil byteBuffer
// It is necessary for us to verify this and break
if length == 0 {
break
}
hash.Write(byteBuffer[0:length]) hash.Write(byteBuffer[0:length])
sha256hash.Write(byteBuffer[0:length])
ok := donut.multiPartObjects[uploadID].Append(partID, byteBuffer[0:length]) ok := donut.multiPartObjects[uploadID].Append(partID, byteBuffer[0:length])
if !ok { if !ok {
return "", iodine.New(InternalError{}, nil) return "", iodine.New(InternalError{}, nil)
@ -174,6 +194,17 @@ func (donut API) createObjectPart(bucket, key, uploadID string, partID int, cont
return "", iodine.New(BadDigest{}, nil) return "", iodine.New(BadDigest{}, nil)
} }
} }
if signature != nil {
ok, err := signature.DoesSignatureMatch(hex.EncodeToString(sha256hash.Sum(nil)))
if err != nil {
return "", iodine.New(err, nil)
}
if !ok {
return "", iodine.New(SignatureDoesNotMatch{}, nil)
}
}
newPart := PartMetadata{ newPart := PartMetadata{
PartNumber: partID, PartNumber: partID,
LastModified: time.Now().UTC(), LastModified: time.Now().UTC(),
@ -200,7 +231,7 @@ func (donut API) cleanupMultipartSession(bucket, key, uploadID string) {
} }
// CompleteMultipartUpload - complete a multipart upload and persist the data // CompleteMultipartUpload - complete a multipart upload and persist the data
func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, parts map[int]string) (ObjectMetadata, error) { func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, data io.Reader, signature *Signature) (ObjectMetadata, error) {
donut.lock.Lock() donut.lock.Lock()
if !IsValidBucket(bucket) { if !IsValidBucket(bucket) {
@ -221,11 +252,36 @@ func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, parts map
donut.lock.Unlock() donut.lock.Unlock()
return ObjectMetadata{}, iodine.New(InvalidUploadID{UploadID: uploadID}, nil) return ObjectMetadata{}, iodine.New(InvalidUploadID{UploadID: uploadID}, nil)
} }
partBytes, err := ioutil.ReadAll(data)
if err != nil {
donut.lock.Unlock()
return ObjectMetadata{}, iodine.New(err, nil)
}
if signature != nil {
ok, err := signature.DoesSignatureMatch(hex.EncodeToString(sha256.Sum256(partBytes)[:]))
if err != nil {
donut.lock.Unlock()
return ObjectMetadata{}, iodine.New(err, nil)
}
if !ok {
donut.lock.Unlock()
return ObjectMetadata{}, iodine.New(SignatureDoesNotMatch{}, nil)
}
}
parts := &CompleteMultipartUpload{}
if err := xml.Unmarshal(partBytes, parts); err != nil {
donut.lock.Unlock()
return ObjectMetadata{}, iodine.New(MalformedXML{}, nil)
}
if !sort.IsSorted(completedParts(parts.Part)) {
donut.lock.Unlock()
return ObjectMetadata{}, iodine.New(InvalidPartOrder{}, nil)
}
var size int64 var size int64
var fullObject bytes.Buffer var fullObject bytes.Buffer
for i := 1; i <= len(parts); i++ { for i := 1; i <= len(parts.Part); i++ {
recvMD5 := parts[i] recvMD5 := parts.Part[i-1].ETag
object, ok := donut.multiPartObjects[uploadID].Get(i) object, ok := donut.multiPartObjects[uploadID].Get(parts.Part[i-1].PartNumber)
if ok == false { if ok == false {
donut.lock.Unlock() donut.lock.Unlock()
return ObjectMetadata{}, iodine.New(errors.New("missing part: "+strconv.Itoa(i)), nil) return ObjectMetadata{}, iodine.New(errors.New("missing part: "+strconv.Itoa(i)), nil)
@ -255,7 +311,7 @@ func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, parts map
// this is needed for final verification inside CreateObject, do not convert this to hex // this is needed for final verification inside CreateObject, do not convert this to hex
md5sum := base64.StdEncoding.EncodeToString(md5sumSlice[:]) md5sum := base64.StdEncoding.EncodeToString(md5sumSlice[:])
donut.lock.Unlock() donut.lock.Unlock()
objectMetadata, err := donut.CreateObject(bucket, key, md5sum, size, &fullObject, nil) objectMetadata, err := donut.CreateObject(bucket, key, md5sum, size, &fullObject, nil, nil)
if err != nil { if err != nil {
// No need to call internal cleanup functions here, caller will call AbortMultipartUpload() // No need to call internal cleanup functions here, caller will call AbortMultipartUpload()
// which would in-turn cleanup properly in accordance with S3 Spec // which would in-turn cleanup properly in accordance with S3 Spec
@ -277,14 +333,25 @@ func (a byKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byKey) Less(i, j int) bool { return a[i].Key < a[j].Key } func (a byKey) Less(i, j int) bool { return a[i].Key < a[j].Key }
// ListMultipartUploads - list incomplete multipart sessions for a given bucket // ListMultipartUploads - list incomplete multipart sessions for a given bucket
func (donut API) ListMultipartUploads(bucket string, resources BucketMultipartResourcesMetadata) (BucketMultipartResourcesMetadata, error) { func (donut API) ListMultipartUploads(bucket string, resources BucketMultipartResourcesMetadata, signature *Signature) (BucketMultipartResourcesMetadata, error) {
// TODO handle delimiter // TODO handle delimiter
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return BucketMultipartResourcesMetadata{}, iodine.New(err, nil)
}
if !ok {
return BucketMultipartResourcesMetadata{}, iodine.New(SignatureDoesNotMatch{}, nil)
}
}
if !donut.storedBuckets.Exists(bucket) { if !donut.storedBuckets.Exists(bucket) {
return BucketMultipartResourcesMetadata{}, iodine.New(BucketNotFound{Bucket: bucket}, nil) return BucketMultipartResourcesMetadata{}, iodine.New(BucketNotFound{Bucket: bucket}, nil)
} }
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket) storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
var uploads []*UploadMetadata var uploads []*UploadMetadata
@ -340,11 +407,21 @@ func (a partNumber) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a partNumber) Less(i, j int) bool { return a[i].PartNumber < a[j].PartNumber } func (a partNumber) Less(i, j int) bool { return a[i].PartNumber < a[j].PartNumber }
// ListObjectParts - list parts from incomplete multipart session for a given object // ListObjectParts - list parts from incomplete multipart session for a given object
func (donut API) ListObjectParts(bucket, key string, resources ObjectResourcesMetadata) (ObjectResourcesMetadata, error) { func (donut API) ListObjectParts(bucket, key string, resources ObjectResourcesMetadata, signature *Signature) (ObjectResourcesMetadata, error) {
// Verify upload id // Verify upload id
donut.lock.Lock() donut.lock.Lock()
defer donut.lock.Unlock() defer donut.lock.Unlock()
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return ObjectResourcesMetadata{}, iodine.New(err, nil)
}
if !ok {
return ObjectResourcesMetadata{}, iodine.New(SignatureDoesNotMatch{}, nil)
}
}
if !donut.storedBuckets.Exists(bucket) { if !donut.storedBuckets.Exists(bucket) {
return ObjectResourcesMetadata{}, iodine.New(BucketNotFound{Bucket: bucket}, nil) return ObjectResourcesMetadata{}, iodine.New(BucketNotFound{Bucket: bucket}, nil)
} }

View File

@ -21,7 +21,6 @@ import (
"crypto/hmac" "crypto/hmac"
"encoding/hex" "encoding/hex"
"errors" "errors"
"io"
"net/http" "net/http"
"regexp" "regexp"
"sort" "sort"
@ -29,30 +28,30 @@ import (
"time" "time"
"unicode/utf8" "unicode/utf8"
"github.com/minio/minio/pkg/auth"
"github.com/minio/minio/pkg/crypto/sha256" "github.com/minio/minio/pkg/crypto/sha256"
"github.com/minio/minio/pkg/iodine" "github.com/minio/minio/pkg/iodine"
) )
// request - a http request // Signature - local variables
type request struct { type Signature struct {
receivedReq *http.Request AccessKeyID string
calculatedReq *http.Request SecretAccessKey string
user *auth.User AuthHeader string
body io.Reader Request *http.Request
} }
const ( const (
authHeader = "AWS4-HMAC-SHA256" authHeaderPrefix = "AWS4-HMAC-SHA256"
iso8601Format = "20060102T150405Z" iso8601Format = "20060102T150405Z"
yyyymmdd = "20060102" yyyymmdd = "20060102"
) )
var ignoredHeaders = map[string]bool{ var ignoredHeaders = map[string]bool{
"Authorization": true, "Authorization": true,
"Content-Type": true, "Content-Type": true,
"Content-Length": true, "Accept-Encoding": true,
"User-Agent": true, "Content-Length": true,
"User-Agent": true,
} }
// sumHMAC calculate hmac between two input byte array // sumHMAC calculate hmac between two input byte array
@ -101,38 +100,11 @@ func urlEncodeName(name string) (string, error) {
return encodedName, nil return encodedName, nil
} }
// newSignV4Request - populate a new signature v4 request
func newSignV4Request(user *auth.User, req *http.Request, body io.Reader) (*request, error) {
// save for subsequent use
r := new(request)
r.user = user
r.body = body
r.receivedReq = req
r.calculatedReq = req
return r, nil
}
// getHashedPayload get the hexadecimal value of the SHA256 hash of the request payload
func (r *request) getHashedPayload() string {
hash := func() string {
switch {
case r.body == nil:
return hex.EncodeToString(sha256.Sum256([]byte{}))
default:
sum256Bytes, _ := sha256.Sum(r.body)
return hex.EncodeToString(sum256Bytes)
}
}
hashedPayload := hash()
r.calculatedReq.Header.Set("x-amz-content-sha256", hashedPayload)
return hashedPayload
}
// getCanonicalHeaders generate a list of request headers with their values // getCanonicalHeaders generate a list of request headers with their values
func (r *request) getCanonicalHeaders() string { func (r *Signature) getCanonicalHeaders() string {
var headers []string var headers []string
vals := make(map[string][]string) vals := make(map[string][]string)
for k, vv := range r.calculatedReq.Header { for k, vv := range r.Request.Header {
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok { if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
continue // ignored header continue // ignored header
} }
@ -148,7 +120,7 @@ func (r *request) getCanonicalHeaders() string {
buf.WriteByte(':') buf.WriteByte(':')
switch { switch {
case k == "host": case k == "host":
buf.WriteString(r.calculatedReq.URL.Host) buf.WriteString(r.Request.Host)
fallthrough fallthrough
default: default:
for idx, v := range vals[k] { for idx, v := range vals[k] {
@ -164,9 +136,9 @@ func (r *request) getCanonicalHeaders() string {
} }
// getSignedHeaders generate a string i.e alphabetically sorted, semicolon-separated list of lowercase request header names // getSignedHeaders generate a string i.e alphabetically sorted, semicolon-separated list of lowercase request header names
func (r *request) getSignedHeaders() string { func (r *Signature) getSignedHeaders() string {
var headers []string var headers []string
for k := range r.calculatedReq.Header { for k := range r.Request.Header {
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok { if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
continue // ignored header continue // ignored header
} }
@ -187,24 +159,24 @@ func (r *request) getSignedHeaders() string {
// <SignedHeaders>\n // <SignedHeaders>\n
// <HashedPayload> // <HashedPayload>
// //
func (r *request) getCanonicalRequest(hashedPayload string) string { func (r *Signature) getCanonicalRequest() string {
r.calculatedReq.URL.RawQuery = strings.Replace(r.calculatedReq.URL.Query().Encode(), "+", "%20", -1) r.Request.URL.RawQuery = strings.Replace(r.Request.URL.Query().Encode(), "+", "%20", -1)
encodedPath, _ := urlEncodeName(r.calculatedReq.URL.Path) encodedPath, _ := urlEncodeName(r.Request.URL.Path)
// convert any space strings back to "+" // convert any space strings back to "+"
encodedPath = strings.Replace(encodedPath, "+", "%20", -1) encodedPath = strings.Replace(encodedPath, "+", "%20", -1)
canonicalRequest := strings.Join([]string{ canonicalRequest := strings.Join([]string{
r.calculatedReq.Method, r.Request.Method,
encodedPath, encodedPath,
r.calculatedReq.URL.RawQuery, r.Request.URL.RawQuery,
r.getCanonicalHeaders(), r.getCanonicalHeaders(),
r.getSignedHeaders(), r.getSignedHeaders(),
hashedPayload, r.Request.Header.Get("x-amz-content-sha256"),
}, "\n") }, "\n")
return canonicalRequest return canonicalRequest
} }
// getScope generate a string of a specific date, an AWS region, and a service // getScope generate a string of a specific date, an AWS region, and a service
func (r *request) getScope(t time.Time) string { func (r *Signature) getScope(t time.Time) string {
scope := strings.Join([]string{ scope := strings.Join([]string{
t.Format(yyyymmdd), t.Format(yyyymmdd),
"milkyway", "milkyway",
@ -215,16 +187,16 @@ func (r *request) getScope(t time.Time) string {
} }
// getStringToSign a string based on selected query values // getStringToSign a string based on selected query values
func (r *request) getStringToSign(canonicalRequest string, t time.Time) string { func (r *Signature) getStringToSign(canonicalRequest string, t time.Time) string {
stringToSign := authHeader + "\n" + t.Format(iso8601Format) + "\n" stringToSign := authHeaderPrefix + "\n" + t.Format(iso8601Format) + "\n"
stringToSign = stringToSign + r.getScope(t) + "\n" stringToSign = stringToSign + r.getScope(t) + "\n"
stringToSign = stringToSign + hex.EncodeToString(sha256.Sum256([]byte(canonicalRequest))) stringToSign = stringToSign + hex.EncodeToString(sha256.Sum256([]byte(canonicalRequest)))
return stringToSign return stringToSign
} }
// getSigningKey hmac seed to calculate final signature // getSigningKey hmac seed to calculate final signature
func (r *request) getSigningKey(t time.Time) []byte { func (r *Signature) getSigningKey(t time.Time) []byte {
secret := r.user.SecretAccessKey secret := r.SecretAccessKey
date := sumHMAC([]byte("AWS4"+secret), []byte(t.Format(yyyymmdd))) date := sumHMAC([]byte("AWS4"+secret), []byte(t.Format(yyyymmdd)))
region := sumHMAC(date, []byte("milkyway")) region := sumHMAC(date, []byte("milkyway"))
service := sumHMAC(region, []byte("s3")) service := sumHMAC(region, []byte("s3"))
@ -233,26 +205,29 @@ func (r *request) getSigningKey(t time.Time) []byte {
} }
// getSignature final signature in hexadecimal form // getSignature final signature in hexadecimal form
func (r *request) getSignature(signingKey []byte, stringToSign string) string { func (r *Signature) getSignature(signingKey []byte, stringToSign string) string {
return hex.EncodeToString(sumHMAC(signingKey, []byte(stringToSign))) return hex.EncodeToString(sumHMAC(signingKey, []byte(stringToSign)))
} }
// SignV4 the request before Do(), in accordance with - http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html // DoesSignatureMatch - Verify authorization header with calculated header in accordance with - http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
func (r *request) SignV4() (string, error) { // returns true if matches, false other wise if error is not nil then it is always false
func (r *Signature) DoesSignatureMatch(hashedPayload string) (bool, error) {
// set new calulated payload
r.Request.Header.Set("x-amz-content-sha256", hashedPayload)
// Add date if not present // Add date if not present
var date string var date string
if date = r.calculatedReq.Header.Get("x-amz-date"); date == "" { if date = r.Request.Header.Get("x-amz-date"); date == "" {
if date = r.calculatedReq.Header.Get("Date"); date == "" { if date = r.Request.Header.Get("Date"); date == "" {
return "", iodine.New(MissingDateHeader{}, nil) return false, iodine.New(MissingDateHeader{}, nil)
} }
} }
t, err := time.Parse(iso8601Format, date) t, err := time.Parse(iso8601Format, date)
if err != nil { if err != nil {
return "", iodine.New(err, nil) return false, iodine.New(err, nil)
} }
hashedPayload := r.getHashedPayload()
signedHeaders := r.getSignedHeaders() signedHeaders := r.getSignedHeaders()
canonicalRequest := r.getCanonicalRequest(hashedPayload) canonicalRequest := r.getCanonicalRequest()
scope := r.getScope(t) scope := r.getScope(t)
stringToSign := r.getStringToSign(canonicalRequest, t) stringToSign := r.getStringToSign(canonicalRequest, t)
signingKey := r.getSigningKey(t) signingKey := r.getSigningKey(t)
@ -260,10 +235,13 @@ func (r *request) SignV4() (string, error) {
// final Authorization header // final Authorization header
parts := []string{ parts := []string{
authHeader + " Credential=" + r.user.AccessKeyID + "/" + scope, authHeaderPrefix + " Credential=" + r.AccessKeyID + "/" + scope,
"SignedHeaders=" + signedHeaders, "SignedHeaders=" + signedHeaders,
"Signature=" + signature, "Signature=" + signature,
} }
auth := strings.Join(parts, ", ") newAuthHeader := strings.Join(parts, ", ")
return auth, nil if newAuthHeader != r.AuthHeader {
return false, nil
}
return true, nil
} }

View File

@ -29,7 +29,7 @@ func (api Minio) isValidOp(w http.ResponseWriter, req *http.Request, acceptsCont
vars := mux.Vars(req) vars := mux.Vars(req)
bucket := vars["bucket"] bucket := vars["bucket"]
bucketMetadata, err := api.Donut.GetBucketMetadata(bucket) bucketMetadata, err := api.Donut.GetBucketMetadata(bucket, nil)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case donut.BucketNotFound: case donut.BucketNotFound:
{ {
@ -42,7 +42,7 @@ func (api Minio) isValidOp(w http.ResponseWriter, req *http.Request, acceptsCont
return false return false
} }
case nil: case nil:
if _, err := stripAuth(req); err != nil { if _, err := StripAccessKeyID(req.Header.Get("Authorization")); err != nil {
if bucketMetadata.ACL.IsPrivate() { if bucketMetadata.ACL.IsPrivate() {
return true return true
//uncomment this when we have webcli //uncomment this when we have webcli
@ -95,12 +95,23 @@ func (api Minio) ListMultipartUploadsHandler(w http.ResponseWriter, req *http.Re
vars := mux.Vars(req) vars := mux.Vars(req)
bucket := vars["bucket"] bucket := vars["bucket"]
resources, err := api.Donut.ListMultipartUploads(bucket, resources) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
resources, err := api.Donut.ListMultipartUploads(bucket, resources, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: // success case nil: // success
{ {
// generate response // generate response
response := generateListMultipartUploadsResult(bucket, resources) response := generateListMultipartUploadsResponse(bucket, resources)
encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType)
// write headers // write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse))
@ -153,7 +164,18 @@ func (api Minio) ListObjectsHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req) vars := mux.Vars(req)
bucket := vars["bucket"] bucket := vars["bucket"]
objects, resources, err := api.Donut.ListObjects(bucket, resources) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
objects, resources, err := api.Donut.ListObjects(bucket, resources, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
// generate response // generate response
@ -194,12 +216,23 @@ func (api Minio) ListBucketsHandler(w http.ResponseWriter, req *http.Request) {
acceptsContentType := getContentType(req) acceptsContentType := getContentType(req)
// uncomment this when we have webcli // uncomment this when we have webcli
// without access key credentials one cannot list buckets // without access key credentials one cannot list buckets
// if _, err := stripAuth(req); err != nil { // if _, err := StripAccessKeyID(req); err != nil {
// writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) // writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path)
// return // return
// } // }
buckets, err := api.Donut.ListBuckets() var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
buckets, err := api.Donut.ListBuckets(signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
// generate response // generate response
@ -231,7 +264,7 @@ func (api Minio) PutBucketHandler(w http.ResponseWriter, req *http.Request) {
acceptsContentType := getContentType(req) acceptsContentType := getContentType(req)
// uncomment this when we have webcli // uncomment this when we have webcli
// without access key credentials one cannot create a bucket // without access key credentials one cannot create a bucket
// if _, err := stripAuth(req); err != nil { // if _, err := StripAccessKeyID(req); err != nil {
// writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path) // writeErrorResponse(w, req, AccessDenied, acceptsContentType, req.URL.Path)
// return // return
// } // }
@ -250,7 +283,18 @@ func (api Minio) PutBucketHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req) vars := mux.Vars(req)
bucket := vars["bucket"] bucket := vars["bucket"]
err := api.Donut.MakeBucket(bucket, getACLTypeString(aclType)) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
err := api.Donut.MakeBucket(bucket, getACLTypeString(aclType), signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
// Make sure to add Location information here only for bucket // Make sure to add Location information here only for bucket
@ -293,7 +337,18 @@ func (api Minio) PutBucketACLHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req) vars := mux.Vars(req)
bucket := vars["bucket"] bucket := vars["bucket"]
err := api.Donut.SetBucketMetadata(bucket, map[string]string{"acl": getACLTypeString(aclType)}) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
err := api.Donut.SetBucketMetadata(bucket, map[string]string{"acl": getACLTypeString(aclType)}, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
writeSuccessResponse(w, acceptsContentType) writeSuccessResponse(w, acceptsContentType)
@ -328,7 +383,18 @@ func (api Minio) HeadBucketHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req) vars := mux.Vars(req)
bucket := vars["bucket"] bucket := vars["bucket"]
_, err := api.Donut.GetBucketMetadata(bucket) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
_, err := api.Donut.GetBucketMetadata(bucket, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
writeSuccessResponse(w, acceptsContentType) writeSuccessResponse(w, acceptsContentType)

View File

@ -62,6 +62,14 @@ type ListObjectsResponse struct {
Prefix string Prefix string
} }
// Part container for part metadata
type Part struct {
PartNumber int
ETag string
LastModified string
Size int64
}
// ListPartsResponse - format for list parts response // ListPartsResponse - format for list parts response
type ListPartsResponse struct { type ListPartsResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListPartsResult" json:"-"` XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListPartsResult" json:"-"`
@ -134,14 +142,6 @@ type Bucket struct {
CreationDate string CreationDate string
} }
// Part container for part metadata
type Part struct {
PartNumber int
ETag string
LastModified string
Size int64
}
// Object container for object metadata // Object container for object metadata
type Object struct { type Object struct {
ETag string ETag string
@ -164,8 +164,8 @@ type Owner struct {
DisplayName string DisplayName string
} }
// InitiateMultipartUploadResult container for InitiateMultiPartUpload response, provides uploadID to start MultiPart upload // InitiateMultipartUploadResponse container for InitiateMultiPartUpload response, provides uploadID to start MultiPart upload
type InitiateMultipartUploadResult struct { type InitiateMultipartUploadResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ InitiateMultipartUploadResult" json:"-"` XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ InitiateMultipartUploadResult" json:"-"`
Bucket string Bucket string
@ -173,20 +173,8 @@ type InitiateMultipartUploadResult struct {
UploadID string `xml:"UploadId"` UploadID string `xml:"UploadId"`
} }
// completedParts is a sortable interface for Part slice // CompleteMultipartUploadResponse container for completed multipart upload response
type completedParts []Part type CompleteMultipartUploadResponse struct {
func (a completedParts) Len() int { return len(a) }
func (a completedParts) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a completedParts) Less(i, j int) bool { return a[i].PartNumber < a[j].PartNumber }
// CompleteMultipartUpload container for completing multipart upload
type CompleteMultipartUpload struct {
Part []Part
}
// CompleteMultipartUploadResult container for completed multipart upload response
type CompleteMultipartUploadResult struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CompleteMultipartUploadResult" json:"-"` XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CompleteMultipartUploadResult" json:"-"`
Location string Location string

View File

@ -19,7 +19,6 @@ package api
import ( import (
"errors" "errors"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/auth"
@ -41,64 +40,12 @@ type resourceHandler struct {
handler http.Handler handler http.Handler
} }
type authHeader struct {
prefix string
credential string
signedheaders string
signature string
accessKey string
}
const ( const (
iso8601Format = "20060102T150405Z" iso8601Format = "20060102T150405Z"
) )
const (
authHeaderPrefix = "AWS4-HMAC-SHA256"
)
// strip auth from authorization header
func stripAuth(r *http.Request) (*authHeader, error) {
ah := r.Header.Get("Authorization")
if ah == "" {
return nil, errors.New("Missing auth header")
}
a := new(authHeader)
authFields := strings.Split(ah, ",")
if len(authFields) != 3 {
return nil, errors.New("Missing fields in Auth header")
}
authPrefixFields := strings.Fields(authFields[0])
if len(authPrefixFields) != 2 {
return nil, errors.New("Missing fields in Auth header")
}
if authPrefixFields[0] != authHeaderPrefix {
return nil, errors.New("Missing fields is Auth header")
}
credentials := strings.Split(authPrefixFields[1], "=")
if len(credentials) != 2 {
return nil, errors.New("Missing fields in Auth header")
}
signedheaders := strings.Split(authFields[1], "=")
if len(signedheaders) != 2 {
return nil, errors.New("Missing fields in Auth header")
}
signature := strings.Split(authFields[2], "=")
if len(signature) != 2 {
return nil, errors.New("Missing fields in Auth header")
}
a.credential = credentials[1]
a.signedheaders = signedheaders[1]
a.signature = signature[1]
a.accessKey = strings.Split(a.credential, "/")[0]
if !auth.IsValidAccessKey(a.accessKey) {
return nil, errors.New("Invalid access key")
}
return a, nil
}
func parseDate(req *http.Request) (time.Time, error) { func parseDate(req *http.Request) (time.Time, error) {
amzDate := req.Header.Get("X-Amz-Date") amzDate := req.Header.Get("x-amz-date")
switch { switch {
case amzDate != "": case amzDate != "":
if _, err := time.Parse(time.RFC1123, amzDate); err == nil { if _, err := time.Parse(time.RFC1123, amzDate); err == nil {
@ -150,7 +97,7 @@ func (h timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
acceptsContentType := getContentType(r) acceptsContentType := getContentType(r)
// Verify if date headers are set, if not reject the request // Verify if date headers are set, if not reject the request
if r.Header.Get("Authorization") != "" { if r.Header.Get("Authorization") != "" {
if r.Header.Get("X-Amz-Date") == "" && r.Header.Get("Date") == "" { 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 // there is no way to knowing if this is a valid request, could be a attack reject such clients
writeErrorResponse(w, r, RequestTimeTooSkewed, acceptsContentType, r.URL.Path) writeErrorResponse(w, r, RequestTimeTooSkewed, acceptsContentType, r.URL.Path)
return return
@ -181,20 +128,20 @@ 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)
ah, err := stripAuth(r) accessKeyID, err := StripAccessKeyID(r.Header.Get("Authorization"))
switch err.(type) { switch err.(type) {
case nil: case nil:
// load auth config
authConfig, err := auth.LoadConfig() authConfig, err := auth.LoadConfig()
if err != nil { if err != nil {
writeErrorResponse(w, r, InternalError, acceptsContentType, r.URL.Path) writeErrorResponse(w, r, InternalError, acceptsContentType, r.URL.Path)
return return
} }
_, ok := authConfig.Users[ah.accessKey] // Access key not found
if !ok { if _, ok := authConfig.Users[accessKeyID]; !ok {
writeErrorResponse(w, r, AccessDenied, acceptsContentType, r.URL.Path) writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path)
return return
} }
// Success
h.handler.ServeHTTP(w, r) h.handler.ServeHTTP(w, r)
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

View File

@ -18,11 +18,8 @@ package api
import ( import (
"net/http" "net/http"
"sort"
"strconv" "strconv"
"encoding/xml"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/minio/minio/pkg/donut" "github.com/minio/minio/pkg/donut"
"github.com/minio/minio/pkg/iodine" "github.com/minio/minio/pkg/iodine"
@ -57,7 +54,18 @@ func (api Minio) GetObjectHandler(w http.ResponseWriter, req *http.Request) {
bucket = vars["bucket"] bucket = vars["bucket"]
object = vars["object"] object = vars["object"]
metadata, err := api.Donut.GetObjectMetadata(bucket, object) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
metadata, err := api.Donut.GetObjectMetadata(bucket, object, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: // success case nil: // success
{ {
@ -120,7 +128,18 @@ func (api Minio) HeadObjectHandler(w http.ResponseWriter, req *http.Request) {
bucket = vars["bucket"] bucket = vars["bucket"]
object = vars["object"] object = vars["object"]
metadata, err := api.Donut.GetObjectMetadata(bucket, object) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
metadata, err := api.Donut.GetObjectMetadata(bucket, object, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
setObjectHeaders(w, metadata) setObjectHeaders(w, metadata)
@ -205,7 +224,18 @@ func (api Minio) PutObjectHandler(w http.ResponseWriter, req *http.Request) {
return return
} }
metadata, err := api.Donut.CreateObject(bucket, object, md5, sizeInt64, req.Body, nil) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
metadata, err := api.Donut.CreateObject(bucket, object, md5, sizeInt64, req.Body, nil, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
w.Header().Set("ETag", metadata.MD5Sum) w.Header().Set("ETag", metadata.MD5Sum)
@ -218,6 +248,10 @@ func (api Minio) PutObjectHandler(w http.ResponseWriter, req *http.Request) {
writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path)
case donut.BadDigest: case donut.BadDigest:
writeErrorResponse(w, req, BadDigest, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, BadDigest, acceptsContentType, req.URL.Path)
case donut.MissingDateHeader:
writeErrorResponse(w, req, RequestTimeTooSkewed, acceptsContentType, req.URL.Path)
case donut.SignatureDoesNotMatch:
writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path)
case donut.IncompleteBody: case donut.IncompleteBody:
writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path)
case donut.EntityTooLarge: case donut.EntityTooLarge:
@ -258,11 +292,22 @@ func (api Minio) NewMultipartUploadHandler(w http.ResponseWriter, req *http.Requ
bucket = vars["bucket"] bucket = vars["bucket"]
object = vars["object"] object = vars["object"]
uploadID, err := api.Donut.NewMultipartUpload(bucket, object, "") var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
uploadID, err := api.Donut.NewMultipartUpload(bucket, object, req.Header.Get("Content-Type"), signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
{ {
response := generateInitiateMultipartUploadResult(bucket, object, uploadID) response := generateInitiateMultipartUploadResponse(bucket, object, uploadID)
encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType)
// write headers // write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse))
@ -331,7 +376,18 @@ func (api Minio) PutObjectPartHandler(w http.ResponseWriter, req *http.Request)
writeErrorResponse(w, req, InvalidPart, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InvalidPart, acceptsContentType, req.URL.Path)
} }
calculatedMD5, err := api.Donut.CreateObjectPart(bucket, object, uploadID, partID, "", md5, sizeInt64, req.Body) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
calculatedMD5, err := api.Donut.CreateObjectPart(bucket, object, uploadID, partID, "", md5, sizeInt64, req.Body, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
w.Header().Set("ETag", calculatedMD5) w.Header().Set("ETag", calculatedMD5)
@ -342,6 +398,8 @@ func (api Minio) PutObjectPartHandler(w http.ResponseWriter, req *http.Request)
writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, MethodNotAllowed, acceptsContentType, req.URL.Path)
case donut.BadDigest: case donut.BadDigest:
writeErrorResponse(w, req, BadDigest, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, BadDigest, acceptsContentType, req.URL.Path)
case donut.SignatureDoesNotMatch:
writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path)
case donut.IncompleteBody: case donut.IncompleteBody:
writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path)
case donut.EntityTooLarge: case donut.EntityTooLarge:
@ -376,7 +434,18 @@ func (api Minio) AbortMultipartUploadHandler(w http.ResponseWriter, req *http.Re
objectResourcesMetadata := getObjectResources(req.URL.Query()) objectResourcesMetadata := getObjectResources(req.URL.Query())
err := api.Donut.AbortMultipartUpload(bucket, object, objectResourcesMetadata.UploadID) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
err := api.Donut.AbortMultipartUpload(bucket, object, objectResourcesMetadata.UploadID, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
setCommonHeaders(w, getContentTypeString(acceptsContentType), 0) setCommonHeaders(w, getContentTypeString(acceptsContentType), 0)
@ -414,11 +483,22 @@ func (api Minio) ListObjectPartsHandler(w http.ResponseWriter, req *http.Request
bucket := vars["bucket"] bucket := vars["bucket"]
object := vars["object"] object := vars["object"]
objectResourcesMetadata, err := api.Donut.ListObjectParts(bucket, object, objectResourcesMetadata) var signature *donut.Signature
if _, ok := req.Header["Authorization"]; ok {
// Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
}
objectResourcesMetadata, err := api.Donut.ListObjectParts(bucket, object, objectResourcesMetadata, signature)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
{ {
response := generateListPartsResult(objectResourcesMetadata) response := generateListPartsResponse(objectResourcesMetadata)
encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType)
// write headers // write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse))
@ -449,35 +529,27 @@ func (api Minio) CompleteMultipartUploadHandler(w http.ResponseWriter, req *http
return return
} }
decoder := xml.NewDecoder(req.Body)
parts := &CompleteMultipartUpload{}
err := decoder.Decode(parts)
if err != nil {
log.Error.Println(iodine.New(err, nil))
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
if !sort.IsSorted(completedParts(parts.Part)) {
writeErrorResponse(w, req, InvalidPartOrder, acceptsContentType, req.URL.Path)
return
}
vars := mux.Vars(req) vars := mux.Vars(req)
bucket := vars["bucket"] bucket := vars["bucket"]
object := vars["object"] object := vars["object"]
objectResourcesMetadata := getObjectResources(req.URL.Query()) objectResourcesMetadata := getObjectResources(req.URL.Query())
partMap := make(map[int]string) var signature *donut.Signature
for _, part := range parts.Part { if _, ok := req.Header["Authorization"]; ok {
partMap[part.PartNumber] = part.ETag // Init signature V4 verification
var err error
signature, err = InitSignatureV4(req)
if err != nil {
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)
return
}
} }
metadata, err := api.Donut.CompleteMultipartUpload(bucket, object, objectResourcesMetadata.UploadID, req.Body, signature)
metadata, err := api.Donut.CompleteMultipartUpload(bucket, object, objectResourcesMetadata.UploadID, partMap)
switch iodine.ToError(err).(type) { switch iodine.ToError(err).(type) {
case nil: case nil:
{ {
response := generateCompleteMultpartUploadResult(bucket, object, "", metadata.MD5Sum) response := generateCompleteMultpartUploadResponse(bucket, object, "", metadata.MD5Sum)
encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType) encodedSuccessResponse := encodeSuccessResponse(response, acceptsContentType)
// write headers // write headers
setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse)) setCommonHeaders(w, getContentTypeString(acceptsContentType), len(encodedSuccessResponse))
@ -486,6 +558,16 @@ func (api Minio) CompleteMultipartUploadHandler(w http.ResponseWriter, req *http
} }
case donut.InvalidUploadID: case donut.InvalidUploadID:
writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, NoSuchUpload, acceptsContentType, req.URL.Path)
case donut.InvalidPartOrder:
writeErrorResponse(w, req, InvalidPartOrder, acceptsContentType, req.URL.Path)
case donut.MissingDateHeader:
writeErrorResponse(w, req, RequestTimeTooSkewed, acceptsContentType, req.URL.Path)
case donut.SignatureDoesNotMatch:
writeErrorResponse(w, req, SignatureDoesNotMatch, acceptsContentType, req.URL.Path)
case donut.IncompleteBody:
writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path)
case donut.MalformedXML:
writeErrorResponse(w, req, MalformedXML, acceptsContentType, req.URL.Path)
default: default:
log.Error.Println(iodine.New(err, nil)) log.Error.Println(iodine.New(err, nil))
writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InternalError, acceptsContentType, req.URL.Path)

View File

@ -85,7 +85,7 @@ func generateListObjectsResponse(bucket string, objects []donut.ObjectMetadata,
continue continue
} }
content.Key = object.Object content.Key = object.Object
content.LastModified = object.Created.Format(iso8601Format) content.LastModified = object.Created.Format(rfcFormat)
content.ETag = "\"" + object.MD5Sum + "\"" content.ETag = "\"" + object.MD5Sum + "\""
content.Size = object.Size content.Size = object.Size
content.StorageClass = "STANDARD" content.StorageClass = "STANDARD"
@ -111,18 +111,18 @@ func generateListObjectsResponse(bucket string, objects []donut.ObjectMetadata,
return data return data
} }
// generateInitiateMultipartUploadResult // generateInitiateMultipartUploadResponse
func generateInitiateMultipartUploadResult(bucket, key, uploadID string) InitiateMultipartUploadResult { func generateInitiateMultipartUploadResponse(bucket, key, uploadID string) InitiateMultipartUploadResponse {
return InitiateMultipartUploadResult{ return InitiateMultipartUploadResponse{
Bucket: bucket, Bucket: bucket,
Key: key, Key: key,
UploadID: uploadID, UploadID: uploadID,
} }
} }
// generateCompleteMultipartUploadResult // generateCompleteMultipartUploadResponse
func generateCompleteMultpartUploadResult(bucket, key, location, etag string) CompleteMultipartUploadResult { func generateCompleteMultpartUploadResponse(bucket, key, location, etag string) CompleteMultipartUploadResponse {
return CompleteMultipartUploadResult{ return CompleteMultipartUploadResponse{
Location: location, Location: location,
Bucket: bucket, Bucket: bucket,
Key: key, Key: key,
@ -131,7 +131,7 @@ func generateCompleteMultpartUploadResult(bucket, key, location, etag string) Co
} }
// generateListPartsResult // generateListPartsResult
func generateListPartsResult(objectMetadata donut.ObjectResourcesMetadata) ListPartsResponse { func generateListPartsResponse(objectMetadata donut.ObjectResourcesMetadata) ListPartsResponse {
// TODO - support EncodingType in xml decoding // TODO - support EncodingType in xml decoding
listPartsResponse := ListPartsResponse{} listPartsResponse := ListPartsResponse{}
listPartsResponse.Bucket = objectMetadata.Bucket listPartsResponse.Bucket = objectMetadata.Bucket
@ -160,8 +160,8 @@ func generateListPartsResult(objectMetadata donut.ObjectResourcesMetadata) ListP
return listPartsResponse return listPartsResponse
} }
// generateListMultipartUploadsResult // generateListMultipartUploadsResponse
func generateListMultipartUploadsResult(bucket string, metadata donut.BucketMultipartResourcesMetadata) ListMultipartUploadsResponse { func generateListMultipartUploadsResponse(bucket string, metadata donut.BucketMultipartResourcesMetadata) ListMultipartUploadsResponse {
listMultipartUploadsResponse := ListMultipartUploadsResponse{} listMultipartUploadsResponse := ListMultipartUploadsResponse{}
listMultipartUploadsResponse.Bucket = bucket listMultipartUploadsResponse.Bucket = bucket
listMultipartUploadsResponse.Delimiter = metadata.Delimiter listMultipartUploadsResponse.Delimiter = metadata.Delimiter

View File

@ -0,0 +1,85 @@
/*
* Minimalist Object 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"
"net/http"
"strings"
"github.com/minio/minio/pkg/auth"
"github.com/minio/minio/pkg/donut"
"github.com/minio/minio/pkg/iodine"
)
const (
authHeaderPrefix = "AWS4-HMAC-SHA256"
)
// StripAccessKeyID - strip only access key id from auth header
func StripAccessKeyID(ah string) (string, error) {
if ah == "" {
return "", errors.New("Missing auth header")
}
authFields := strings.Split(ah, ",")
if len(authFields) != 3 {
return "", errors.New("Missing fields in Auth header")
}
authPrefixFields := strings.Fields(authFields[0])
if len(authPrefixFields) != 2 {
return "", errors.New("Missing fields in Auth header")
}
if authPrefixFields[0] != authHeaderPrefix {
return "", errors.New("Missing fields is Auth header")
}
credentials := strings.Split(authPrefixFields[1], "=")
if len(credentials) != 2 {
return "", errors.New("Missing fields in Auth header")
}
if len(strings.Split(authFields[1], "=")) != 2 {
return "", errors.New("Missing fields in Auth header")
}
if len(strings.Split(authFields[2], "=")) != 2 {
return "", errors.New("Missing fields in Auth header")
}
accessKeyID := strings.Split(credentials[1], "/")[0]
if !auth.IsValidAccessKey(accessKeyID) {
return "", errors.New("Invalid access key")
}
return accessKeyID, nil
}
// InitSignatureV4 initializing signature verification
func InitSignatureV4(req *http.Request) (*donut.Signature, error) {
// strip auth from authorization header
ah := req.Header.Get("Authorization")
accessKeyID, err := StripAccessKeyID(ah)
if err != nil {
return nil, iodine.New(err, nil)
}
authConfig, err := auth.LoadConfig()
if _, ok := authConfig.Users[accessKeyID]; !ok {
return nil, errors.New("Access ID not found")
}
signature := &donut.Signature{
AccessKeyID: authConfig.Users[accessKeyID].AccessKeyID,
SecretAccessKey: authConfig.Users[accessKeyID].SecretAccessKey,
AuthHeader: ah,
Request: req,
}
return signature, nil
}

View File

@ -21,13 +21,13 @@ import (
"io/ioutil" "io/ioutil"
"strings" "strings"
"testing" "testing"
"time"
"encoding/xml" "encoding/xml"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
. "github.com/minio/check" . "github.com/minio/check"
"github.com/minio/minio/pkg/donut"
"github.com/minio/minio/pkg/server/api" "github.com/minio/minio/pkg/server/api"
) )
@ -49,16 +49,9 @@ func (s *MyAPIDonutCacheSuite) TearDownSuite(c *C) {
testAPIDonutCacheServer.Close() testAPIDonutCacheServer.Close()
} }
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 *MyAPIDonutCacheSuite) TestNonExistantBucket(c *C) { func (s *MyAPIDonutCacheSuite) TestNonExistantBucket(c *C) {
request, err := http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/nonexistantbucket", nil) request, err := http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/nonexistantbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -69,7 +62,6 @@ func (s *MyAPIDonutCacheSuite) TestNonExistantBucket(c *C) {
func (s *MyAPIDonutCacheSuite) TestEmptyObject(c *C) { func (s *MyAPIDonutCacheSuite) TestEmptyObject(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/emptyobject", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/emptyobject", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -78,7 +70,6 @@ func (s *MyAPIDonutCacheSuite) TestEmptyObject(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/emptyobject/object", nil) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/emptyobject/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -87,7 +78,6 @@ func (s *MyAPIDonutCacheSuite) TestEmptyObject(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/emptyobject/object", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/emptyobject/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -103,7 +93,6 @@ func (s *MyAPIDonutCacheSuite) TestEmptyObject(c *C) {
func (s *MyAPIDonutCacheSuite) TestBucket(c *C) { func (s *MyAPIDonutCacheSuite) TestBucket(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/bucket", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/bucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -112,7 +101,6 @@ func (s *MyAPIDonutCacheSuite) TestBucket(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/bucket", nil) request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/bucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -124,7 +112,6 @@ func (s *MyAPIDonutCacheSuite) TestObject(c *C) {
buffer := bytes.NewBufferString("hello world") buffer := bytes.NewBufferString("hello world")
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/testobject", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/testobject", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -133,7 +120,6 @@ func (s *MyAPIDonutCacheSuite) TestObject(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/testobject/object", buffer) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/testobject/object", buffer)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -142,7 +128,6 @@ func (s *MyAPIDonutCacheSuite) TestObject(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/testobject/object", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/testobject/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -158,7 +143,6 @@ func (s *MyAPIDonutCacheSuite) TestObject(c *C) {
func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) { func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/multipleobjects", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/multipleobjects", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -167,7 +151,6 @@ func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/multipleobjects/object", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/multipleobjects/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -180,7 +163,6 @@ func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
buffer1 := bytes.NewBufferString("hello one") buffer1 := bytes.NewBufferString("hello one")
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/multipleobjects/object1", buffer1) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/multipleobjects/object1", buffer1)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -189,7 +171,6 @@ func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/multipleobjects/object1", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/multipleobjects/object1", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -204,7 +185,6 @@ func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
buffer2 := bytes.NewBufferString("hello two") buffer2 := bytes.NewBufferString("hello two")
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/multipleobjects/object2", buffer2) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/multipleobjects/object2", buffer2)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -213,7 +193,6 @@ func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/multipleobjects/object2", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/multipleobjects/object2", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -228,7 +207,6 @@ func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
buffer3 := bytes.NewBufferString("hello three") buffer3 := bytes.NewBufferString("hello three")
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/multipleobjects/object3", buffer3) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/multipleobjects/object3", buffer3)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -237,7 +215,6 @@ func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/multipleobjects/object3", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/multipleobjects/object3", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -253,7 +230,6 @@ func (s *MyAPIDonutCacheSuite) TestMultipleObjects(c *C) {
func (s *MyAPIDonutCacheSuite) TestNotImplemented(c *C) { func (s *MyAPIDonutCacheSuite) TestNotImplemented(c *C) {
request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/bucket/object?policy", nil) request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/bucket/object?policy", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -265,7 +241,6 @@ func (s *MyAPIDonutCacheSuite) TestNotImplemented(c *C) {
func (s *MyAPIDonutCacheSuite) TestHeader(c *C) { func (s *MyAPIDonutCacheSuite) TestHeader(c *C) {
request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/bucket/object", nil) request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/bucket/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -278,7 +253,6 @@ func (s *MyAPIDonutCacheSuite) TestPutBucket(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/put-bucket", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/put-bucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -290,7 +264,6 @@ func (s *MyAPIDonutCacheSuite) TestPutObject(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/put-object", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/put-object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -299,7 +272,6 @@ func (s *MyAPIDonutCacheSuite) TestPutObject(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/put-object/object", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/put-object/object", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -309,7 +281,6 @@ func (s *MyAPIDonutCacheSuite) TestPutObject(c *C) {
func (s *MyAPIDonutCacheSuite) TestListBuckets(c *C) { func (s *MyAPIDonutCacheSuite) TestListBuckets(c *C) {
request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/", nil) request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -325,7 +296,6 @@ func (s *MyAPIDonutCacheSuite) TestListBuckets(c *C) {
func (s *MyAPIDonutCacheSuite) TestNotBeAbleToCreateObjectInNonexistantBucket(c *C) { func (s *MyAPIDonutCacheSuite) TestNotBeAbleToCreateObjectInNonexistantBucket(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/innonexistantbucket/object", bytes.NewBufferString("hello world")) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/innonexistantbucket/object", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -337,7 +307,6 @@ func (s *MyAPIDonutCacheSuite) TestHeadOnObject(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/headonobject", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/headonobject", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -346,7 +315,6 @@ func (s *MyAPIDonutCacheSuite) TestHeadOnObject(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/headonobject/object1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/headonobject/object1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -354,7 +322,6 @@ func (s *MyAPIDonutCacheSuite) TestHeadOnObject(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/headonobject/object1", nil) request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/headonobject/object1", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -365,7 +332,6 @@ func (s *MyAPIDonutCacheSuite) TestHeadOnBucket(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/headonbucket", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/headonbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -374,18 +340,17 @@ func (s *MyAPIDonutCacheSuite) TestHeadOnBucket(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/headonbucket", nil) request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/headonbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
} }
/* Enable when we have full working signature v4
func (s *MyAPIDonutCacheSuite) TestDateFormat(c *C) { func (s *MyAPIDonutCacheSuite) TestDateFormat(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/dateformat", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/dateformat", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
// set an invalid date // set an invalid date
request.Header.Set("Date", "asfasdfadf") request.Header.Set("Date", "asfasdfadf")
@ -397,16 +362,15 @@ func (s *MyAPIDonutCacheSuite) TestDateFormat(c *C) {
"The difference between the request time and the server's time is too large.", http.StatusForbidden) "The difference between the request time and the server's time is too large.", http.StatusForbidden)
request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
} }
*/
func (s *MyAPIDonutCacheSuite) TestXMLNameNotInBucketListJson(c *C) { func (s *MyAPIDonutCacheSuite) TestXMLNameNotInBucketListJson(c *C) {
request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/", nil) request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("Accept", "application/json") request.Header.Add("Accept", "application/json")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -422,7 +386,6 @@ func (s *MyAPIDonutCacheSuite) TestXMLNameNotInObjectListJson(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/xmlnamenotinobjectlistjson", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/xmlnamenotinobjectlistjson", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("Accept", "application/json") request.Header.Add("Accept", "application/json")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -432,7 +395,6 @@ func (s *MyAPIDonutCacheSuite) TestXMLNameNotInObjectListJson(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/xmlnamenotinobjectlistjson", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/xmlnamenotinobjectlistjson", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("Accept", "application/json") request.Header.Add("Accept", "application/json")
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -447,7 +409,6 @@ func (s *MyAPIDonutCacheSuite) TestXMLNameNotInObjectListJson(c *C) {
func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) { func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/contenttype-persists", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/contenttype-persists", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -457,7 +418,6 @@ func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/contenttype-persists/one", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/contenttype-persists/one", bytes.NewBufferString("hello world"))
delete(request.Header, "Content-Type") delete(request.Header, "Content-Type")
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -466,7 +426,6 @@ func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/contenttype-persists/one", nil) request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/contenttype-persists/one", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -474,7 +433,6 @@ func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/contenttype-persists/one", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/contenttype-persists/one", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -486,7 +444,6 @@ func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) {
delete(request.Header, "Content-Type") delete(request.Header, "Content-Type")
request.Header.Add("Content-Type", "application/json") request.Header.Add("Content-Type", "application/json")
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -494,7 +451,6 @@ func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/contenttype-persists/two", nil) request, err = http.NewRequest("HEAD", testAPIDonutCacheServer.URL+"/contenttype-persists/two", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -502,7 +458,6 @@ func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/contenttype-persists/two", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/contenttype-persists/two", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -512,7 +467,6 @@ func (s *MyAPIDonutCacheSuite) TestContentTypePersists(c *C) {
func (s *MyAPIDonutCacheSuite) TestPartialContent(c *C) { func (s *MyAPIDonutCacheSuite) TestPartialContent(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/partial-content", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/partial-content", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -521,7 +475,6 @@ func (s *MyAPIDonutCacheSuite) TestPartialContent(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/partial-content/bar", bytes.NewBufferString("Hello World")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/partial-content/bar", bytes.NewBufferString("Hello World"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -533,7 +486,6 @@ func (s *MyAPIDonutCacheSuite) TestPartialContent(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("Accept", "application/json") request.Header.Add("Accept", "application/json")
request.Header.Add("Range", "bytes=6-7") request.Header.Add("Range", "bytes=6-7")
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -548,7 +500,6 @@ func (s *MyAPIDonutCacheSuite) TestPartialContent(c *C) {
func (s *MyAPIDonutCacheSuite) TestListObjectsHandlerErrors(c *C) { func (s *MyAPIDonutCacheSuite) TestListObjectsHandlerErrors(c *C) {
request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/objecthandlererrors-.", nil) request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/objecthandlererrors-.", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -557,7 +508,6 @@ func (s *MyAPIDonutCacheSuite) TestListObjectsHandlerErrors(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/objecthandlererrors", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/objecthandlererrors", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -569,7 +519,6 @@ func (s *MyAPIDonutCacheSuite) TestPutBucketErrors(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/putbucket-.", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/putbucket-.", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -579,7 +528,6 @@ func (s *MyAPIDonutCacheSuite) TestPutBucketErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/putbucket", nil) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/putbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -589,7 +537,6 @@ func (s *MyAPIDonutCacheSuite) TestPutBucketErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/putbucket", nil) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/putbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -598,7 +545,6 @@ func (s *MyAPIDonutCacheSuite) TestPutBucketErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/putbucket?acl", nil) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/putbucket?acl", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "unknown") request.Header.Add("x-amz-acl", "unknown")
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -608,7 +554,6 @@ func (s *MyAPIDonutCacheSuite) TestPutBucketErrors(c *C) {
func (s *MyAPIDonutCacheSuite) TestGetObjectErrors(c *C) { func (s *MyAPIDonutCacheSuite) TestGetObjectErrors(c *C) {
request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/getobjecterrors", nil) request, err := http.NewRequest("GET", testAPIDonutCacheServer.URL+"/getobjecterrors", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -617,7 +562,6 @@ func (s *MyAPIDonutCacheSuite) TestGetObjectErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/getobjecterrors", nil) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/getobjecterrors", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -626,7 +570,6 @@ func (s *MyAPIDonutCacheSuite) TestGetObjectErrors(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/getobjecterrors/bar", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/getobjecterrors/bar", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -635,7 +578,6 @@ func (s *MyAPIDonutCacheSuite) TestGetObjectErrors(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/getobjecterrors-./bar", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/getobjecterrors-./bar", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -646,7 +588,6 @@ func (s *MyAPIDonutCacheSuite) TestGetObjectErrors(c *C) {
func (s *MyAPIDonutCacheSuite) TestGetObjectRangeErrors(c *C) { func (s *MyAPIDonutCacheSuite) TestGetObjectRangeErrors(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/getobjectrangeerrors", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/getobjectrangeerrors", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -655,7 +596,6 @@ func (s *MyAPIDonutCacheSuite) TestGetObjectRangeErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/getobjectrangeerrors/bar", bytes.NewBufferString("Hello World")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/getobjectrangeerrors/bar", bytes.NewBufferString("Hello World"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -665,7 +605,6 @@ func (s *MyAPIDonutCacheSuite) TestGetObjectRangeErrors(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/getobjectrangeerrors/bar", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/getobjectrangeerrors/bar", nil)
request.Header.Add("Range", "bytes=7-6") request.Header.Add("Range", "bytes=7-6")
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -676,7 +615,6 @@ func (s *MyAPIDonutCacheSuite) TestGetObjectRangeErrors(c *C) {
func (s *MyAPIDonutCacheSuite) TestObjectMultipartAbort(c *C) { func (s *MyAPIDonutCacheSuite) TestObjectMultipartAbort(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartabort", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartabort", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -685,13 +623,12 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartAbort(c *C) {
request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/objectmultipartabort/object?uploads", bytes.NewBufferString("")) request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/objectmultipartabort/object?uploads", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
decoder := xml.NewDecoder(response.Body) decoder := xml.NewDecoder(response.Body)
newResponse := &api.InitiateMultipartUploadResult{} newResponse := &api.InitiateMultipartUploadResponse{}
err = decoder.Decode(newResponse) err = decoder.Decode(newResponse)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -700,7 +637,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartAbort(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartabort/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartabort/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response1, err := client.Do(request) response1, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -708,7 +644,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartAbort(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartabort/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartabort/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response2, err := client.Do(request) response2, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -716,7 +651,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartAbort(c *C) {
request, err = http.NewRequest("DELETE", testAPIDonutCacheServer.URL+"/objectmultipartabort/object?uploadId="+uploadID, nil) request, err = http.NewRequest("DELETE", testAPIDonutCacheServer.URL+"/objectmultipartabort/object?uploadId="+uploadID, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response3, err := client.Do(request) response3, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -726,7 +660,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartAbort(c *C) {
func (s *MyAPIDonutCacheSuite) TestBucketMultipartList(c *C) { func (s *MyAPIDonutCacheSuite) TestBucketMultipartList(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/bucketmultipartlist", bytes.NewBufferString("")) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/bucketmultipartlist", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -735,13 +668,12 @@ func (s *MyAPIDonutCacheSuite) TestBucketMultipartList(c *C) {
request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/bucketmultipartlist/object?uploads", bytes.NewBufferString("")) request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/bucketmultipartlist/object?uploads", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
decoder := xml.NewDecoder(response.Body) decoder := xml.NewDecoder(response.Body)
newResponse := &api.InitiateMultipartUploadResult{} newResponse := &api.InitiateMultipartUploadResponse{}
err = decoder.Decode(newResponse) err = decoder.Decode(newResponse)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -750,7 +682,6 @@ func (s *MyAPIDonutCacheSuite) TestBucketMultipartList(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/bucketmultipartlist/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/bucketmultipartlist/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response1, err := client.Do(request) response1, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -758,7 +689,6 @@ func (s *MyAPIDonutCacheSuite) TestBucketMultipartList(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/bucketmultipartlist/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/bucketmultipartlist/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response2, err := client.Do(request) response2, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -766,7 +696,6 @@ func (s *MyAPIDonutCacheSuite) TestBucketMultipartList(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/bucketmultipartlist?uploads", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/bucketmultipartlist?uploads", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response3, err := client.Do(request) response3, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -782,7 +711,6 @@ func (s *MyAPIDonutCacheSuite) TestBucketMultipartList(c *C) {
func (s *MyAPIDonutCacheSuite) TestObjectMultipartList(c *C) { func (s *MyAPIDonutCacheSuite) TestObjectMultipartList(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartlist", bytes.NewBufferString("")) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartlist", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -791,13 +719,12 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartList(c *C) {
request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/objectmultipartlist/object?uploads", bytes.NewBufferString("")) request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/objectmultipartlist/object?uploads", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
decoder := xml.NewDecoder(response.Body) decoder := xml.NewDecoder(response.Body)
newResponse := &api.InitiateMultipartUploadResult{} newResponse := &api.InitiateMultipartUploadResponse{}
err = decoder.Decode(newResponse) err = decoder.Decode(newResponse)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -806,7 +733,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartList(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartlist/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartlist/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response1, err := client.Do(request) response1, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -814,7 +740,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartList(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartlist/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultipartlist/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response2, err := client.Do(request) response2, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -822,7 +747,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartList(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/objectmultipartlist/object?uploadId="+uploadID, nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/objectmultipartlist/object?uploadId="+uploadID, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response3, err := client.Do(request) response3, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -833,7 +757,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipartList(c *C) {
func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) { func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultiparts", nil) request, err := http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultiparts", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -842,7 +765,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/objectmultiparts/object?uploads", nil) request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/objectmultiparts/object?uploads", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -850,7 +772,7 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
decoder := xml.NewDecoder(response.Body) decoder := xml.NewDecoder(response.Body)
newResponse := &api.InitiateMultipartUploadResult{} newResponse := &api.InitiateMultipartUploadResponse{}
err = decoder.Decode(newResponse) err = decoder.Decode(newResponse)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -859,7 +781,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response1, err := client.Do(request) response1, err := client.Do(request)
@ -868,7 +789,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutCacheServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response2, err := client.Do(request) response2, err := client.Do(request)
@ -876,8 +796,8 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {
c.Assert(response2.StatusCode, Equals, http.StatusOK) c.Assert(response2.StatusCode, Equals, http.StatusOK)
// complete multipart upload // complete multipart upload
completeUploads := &api.CompleteMultipartUpload{ completeUploads := &donut.CompleteMultipartUpload{
Part: []api.Part{ Part: []donut.CompletePart{
{ {
PartNumber: 1, PartNumber: 1,
ETag: response1.Header.Get("ETag"), ETag: response1.Header.Get("ETag"),
@ -895,7 +815,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/objectmultiparts/object?uploadId="+uploadID, &completeBuffer) request, err = http.NewRequest("POST", testAPIDonutCacheServer.URL+"/objectmultiparts/object?uploadId="+uploadID, &completeBuffer)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -903,7 +822,6 @@ func (s *MyAPIDonutCacheSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/objectmultiparts/object", nil) request, err = http.NewRequest("GET", testAPIDonutCacheServer.URL+"/objectmultiparts/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)

View File

@ -24,7 +24,6 @@ import (
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
"time"
"encoding/xml" "encoding/xml"
"net/http" "net/http"
@ -88,7 +87,6 @@ func (s *MyAPIDonutSuite) TearDownSuite(c *C) {
func (s *MyAPIDonutSuite) TestNonExistantBucket(c *C) { func (s *MyAPIDonutSuite) TestNonExistantBucket(c *C) {
request, err := http.NewRequest("HEAD", testAPIDonutServer.URL+"/nonexistantbucket", nil) request, err := http.NewRequest("HEAD", testAPIDonutServer.URL+"/nonexistantbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -99,7 +97,6 @@ func (s *MyAPIDonutSuite) TestNonExistantBucket(c *C) {
func (s *MyAPIDonutSuite) TestEmptyObject(c *C) { func (s *MyAPIDonutSuite) TestEmptyObject(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/emptyobject", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/emptyobject", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -108,7 +105,6 @@ func (s *MyAPIDonutSuite) TestEmptyObject(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/emptyobject/object", nil) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/emptyobject/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -117,7 +113,6 @@ func (s *MyAPIDonutSuite) TestEmptyObject(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/emptyobject/object", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/emptyobject/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -133,7 +128,6 @@ func (s *MyAPIDonutSuite) TestEmptyObject(c *C) {
func (s *MyAPIDonutSuite) TestBucket(c *C) { func (s *MyAPIDonutSuite) TestBucket(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/bucket", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/bucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -142,7 +136,6 @@ func (s *MyAPIDonutSuite) TestBucket(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/bucket", nil) request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/bucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -154,7 +147,6 @@ func (s *MyAPIDonutSuite) TestObject(c *C) {
buffer := bytes.NewBufferString("hello world") buffer := bytes.NewBufferString("hello world")
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/testobject", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/testobject", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -163,7 +155,6 @@ func (s *MyAPIDonutSuite) TestObject(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/testobject/object", buffer) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/testobject/object", buffer)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -172,7 +163,6 @@ func (s *MyAPIDonutSuite) TestObject(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/testobject/object", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/testobject/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -188,7 +178,6 @@ func (s *MyAPIDonutSuite) TestObject(c *C) {
func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) { func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/multipleobjects", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/multipleobjects", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -197,7 +186,6 @@ func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/multipleobjects/object", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/multipleobjects/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -210,7 +198,6 @@ func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
buffer1 := bytes.NewBufferString("hello one") buffer1 := bytes.NewBufferString("hello one")
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/multipleobjects/object1", buffer1) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/multipleobjects/object1", buffer1)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -219,7 +206,6 @@ func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/multipleobjects/object1", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/multipleobjects/object1", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -234,7 +220,6 @@ func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
buffer2 := bytes.NewBufferString("hello two") buffer2 := bytes.NewBufferString("hello two")
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/multipleobjects/object2", buffer2) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/multipleobjects/object2", buffer2)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -243,7 +228,6 @@ func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/multipleobjects/object2", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/multipleobjects/object2", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -258,7 +242,6 @@ func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
buffer3 := bytes.NewBufferString("hello three") buffer3 := bytes.NewBufferString("hello three")
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/multipleobjects/object3", buffer3) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/multipleobjects/object3", buffer3)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -267,7 +250,6 @@ func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/multipleobjects/object3", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/multipleobjects/object3", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -283,7 +265,6 @@ func (s *MyAPIDonutSuite) TestMultipleObjects(c *C) {
func (s *MyAPIDonutSuite) TestNotImplemented(c *C) { func (s *MyAPIDonutSuite) TestNotImplemented(c *C) {
request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/bucket/object?policy", nil) request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/bucket/object?policy", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -295,7 +276,6 @@ func (s *MyAPIDonutSuite) TestNotImplemented(c *C) {
func (s *MyAPIDonutSuite) TestHeader(c *C) { func (s *MyAPIDonutSuite) TestHeader(c *C) {
request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/bucket/object", nil) request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/bucket/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -308,7 +288,6 @@ func (s *MyAPIDonutSuite) TestPutBucket(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/put-bucket", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/put-bucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -320,7 +299,6 @@ func (s *MyAPIDonutSuite) TestPutObject(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/put-object", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/put-object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -329,7 +307,6 @@ func (s *MyAPIDonutSuite) TestPutObject(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/put-object/object", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/put-object/object", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -339,7 +316,6 @@ func (s *MyAPIDonutSuite) TestPutObject(c *C) {
func (s *MyAPIDonutSuite) TestListBuckets(c *C) { func (s *MyAPIDonutSuite) TestListBuckets(c *C) {
request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/", nil) request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -355,7 +331,6 @@ func (s *MyAPIDonutSuite) TestListBuckets(c *C) {
func (s *MyAPIDonutSuite) TestNotBeAbleToCreateObjectInNonexistantBucket(c *C) { func (s *MyAPIDonutSuite) TestNotBeAbleToCreateObjectInNonexistantBucket(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/innonexistantbucket/object", bytes.NewBufferString("hello world")) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/innonexistantbucket/object", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -367,7 +342,6 @@ func (s *MyAPIDonutSuite) TestHeadOnObject(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/headonobject", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/headonobject", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -376,7 +350,6 @@ func (s *MyAPIDonutSuite) TestHeadOnObject(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/headonobject/object1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/headonobject/object1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -384,7 +357,6 @@ func (s *MyAPIDonutSuite) TestHeadOnObject(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/headonobject/object1", nil) request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/headonobject/object1", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -395,7 +367,6 @@ func (s *MyAPIDonutSuite) TestHeadOnBucket(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/headonbucket", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/headonbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -404,18 +375,17 @@ func (s *MyAPIDonutSuite) TestHeadOnBucket(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/headonbucket", nil) request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/headonbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
} }
/*
func (s *MyAPIDonutSuite) TestDateFormat(c *C) { func (s *MyAPIDonutSuite) TestDateFormat(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/dateformat", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/dateformat", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
// set an invalid date // set an invalid date
request.Header.Set("Date", "asfasdfadf") request.Header.Set("Date", "asfasdfadf")
@ -427,16 +397,16 @@ func (s *MyAPIDonutSuite) TestDateFormat(c *C) {
"The difference between the request time and the server's time is too large.", http.StatusForbidden) "The difference between the request time and the server's time is too large.", http.StatusForbidden)
request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
} }
*/
func (s *MyAPIDonutSuite) TestXMLNameNotInBucketListJson(c *C) { func (s *MyAPIDonutSuite) TestXMLNameNotInBucketListJson(c *C) {
request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/", nil) request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("Accept", "application/json") request.Header.Add("Accept", "application/json")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -452,7 +422,6 @@ func (s *MyAPIDonutSuite) TestXMLNameNotInObjectListJson(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/xmlnamenotinobjectlistjson", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/xmlnamenotinobjectlistjson", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("Accept", "application/json") request.Header.Add("Accept", "application/json")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -462,7 +431,6 @@ func (s *MyAPIDonutSuite) TestXMLNameNotInObjectListJson(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/xmlnamenotinobjectlistjson", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/xmlnamenotinobjectlistjson", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("Accept", "application/json") request.Header.Add("Accept", "application/json")
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -477,7 +445,6 @@ func (s *MyAPIDonutSuite) TestXMLNameNotInObjectListJson(c *C) {
func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) { func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/contenttype-persists", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/contenttype-persists", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -487,7 +454,6 @@ func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/contenttype-persists/one", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/contenttype-persists/one", bytes.NewBufferString("hello world"))
delete(request.Header, "Content-Type") delete(request.Header, "Content-Type")
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -496,7 +462,6 @@ func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/contenttype-persists/one", nil) request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/contenttype-persists/one", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -504,7 +469,6 @@ func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/contenttype-persists/one", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/contenttype-persists/one", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -516,7 +480,6 @@ func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) {
delete(request.Header, "Content-Type") delete(request.Header, "Content-Type")
request.Header.Add("Content-Type", "application/json") request.Header.Add("Content-Type", "application/json")
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -524,7 +487,6 @@ func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/contenttype-persists/two", nil) request, err = http.NewRequest("HEAD", testAPIDonutServer.URL+"/contenttype-persists/two", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -532,7 +494,6 @@ func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/contenttype-persists/two", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/contenttype-persists/two", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -542,7 +503,6 @@ func (s *MyAPIDonutSuite) TestContentTypePersists(c *C) {
func (s *MyAPIDonutSuite) TestPartialContent(c *C) { func (s *MyAPIDonutSuite) TestPartialContent(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/partial-content", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/partial-content", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -551,7 +511,6 @@ func (s *MyAPIDonutSuite) TestPartialContent(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/partial-content/bar", bytes.NewBufferString("Hello World")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/partial-content/bar", bytes.NewBufferString("Hello World"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -563,7 +522,6 @@ func (s *MyAPIDonutSuite) TestPartialContent(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("Accept", "application/json") request.Header.Add("Accept", "application/json")
request.Header.Add("Range", "bytes=6-7") request.Header.Add("Range", "bytes=6-7")
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -578,7 +536,6 @@ func (s *MyAPIDonutSuite) TestPartialContent(c *C) {
func (s *MyAPIDonutSuite) TestListObjectsHandlerErrors(c *C) { func (s *MyAPIDonutSuite) TestListObjectsHandlerErrors(c *C) {
request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/objecthandlererrors-.", nil) request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/objecthandlererrors-.", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -587,7 +544,6 @@ func (s *MyAPIDonutSuite) TestListObjectsHandlerErrors(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/objecthandlererrors", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/objecthandlererrors", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -599,7 +555,6 @@ func (s *MyAPIDonutSuite) TestPutBucketErrors(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/putbucket-.", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/putbucket-.", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -609,7 +564,6 @@ func (s *MyAPIDonutSuite) TestPutBucketErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/putbucket", nil) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/putbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -619,7 +573,6 @@ func (s *MyAPIDonutSuite) TestPutBucketErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/putbucket", nil) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/putbucket", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "private") request.Header.Add("x-amz-acl", "private")
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -628,7 +581,6 @@ func (s *MyAPIDonutSuite) TestPutBucketErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/putbucket?acl", nil) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/putbucket?acl", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
request.Header.Add("x-amz-acl", "unknown") request.Header.Add("x-amz-acl", "unknown")
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -638,7 +590,6 @@ func (s *MyAPIDonutSuite) TestPutBucketErrors(c *C) {
func (s *MyAPIDonutSuite) TestGetObjectErrors(c *C) { func (s *MyAPIDonutSuite) TestGetObjectErrors(c *C) {
request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/getobjecterrors", nil) request, err := http.NewRequest("GET", testAPIDonutServer.URL+"/getobjecterrors", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -647,7 +598,6 @@ func (s *MyAPIDonutSuite) TestGetObjectErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/getobjecterrors", nil) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/getobjecterrors", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -656,7 +606,6 @@ func (s *MyAPIDonutSuite) TestGetObjectErrors(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/getobjecterrors/bar", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/getobjecterrors/bar", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -665,7 +614,6 @@ func (s *MyAPIDonutSuite) TestGetObjectErrors(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/getobjecterrors-./bar", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/getobjecterrors-./bar", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -676,7 +624,6 @@ func (s *MyAPIDonutSuite) TestGetObjectErrors(c *C) {
func (s *MyAPIDonutSuite) TestGetObjectRangeErrors(c *C) { func (s *MyAPIDonutSuite) TestGetObjectRangeErrors(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/getobjectrangeerrors", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/getobjectrangeerrors", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -685,7 +632,6 @@ func (s *MyAPIDonutSuite) TestGetObjectRangeErrors(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/getobjectrangeerrors/bar", bytes.NewBufferString("Hello World")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/getobjectrangeerrors/bar", bytes.NewBufferString("Hello World"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -695,7 +641,6 @@ func (s *MyAPIDonutSuite) TestGetObjectRangeErrors(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/getobjectrangeerrors/bar", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/getobjectrangeerrors/bar", nil)
request.Header.Add("Range", "bytes=7-6") request.Header.Add("Range", "bytes=7-6")
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -706,7 +651,6 @@ func (s *MyAPIDonutSuite) TestGetObjectRangeErrors(c *C) {
func (s *MyAPIDonutSuite) TestObjectMultipartAbort(c *C) { func (s *MyAPIDonutSuite) TestObjectMultipartAbort(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartabort", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartabort", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -715,13 +659,12 @@ func (s *MyAPIDonutSuite) TestObjectMultipartAbort(c *C) {
request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/objectmultipartabort/object?uploads", bytes.NewBufferString("")) request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/objectmultipartabort/object?uploads", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
decoder := xml.NewDecoder(response.Body) decoder := xml.NewDecoder(response.Body)
newResponse := &api.InitiateMultipartUploadResult{} newResponse := &api.InitiateMultipartUploadResponse{}
err = decoder.Decode(newResponse) err = decoder.Decode(newResponse)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -730,7 +673,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipartAbort(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartabort/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartabort/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response1, err := client.Do(request) response1, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -738,7 +680,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipartAbort(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartabort/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartabort/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response2, err := client.Do(request) response2, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -746,7 +687,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipartAbort(c *C) {
request, err = http.NewRequest("DELETE", testAPIDonutServer.URL+"/objectmultipartabort/object?uploadId="+uploadID, nil) request, err = http.NewRequest("DELETE", testAPIDonutServer.URL+"/objectmultipartabort/object?uploadId="+uploadID, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response3, err := client.Do(request) response3, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -756,7 +696,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipartAbort(c *C) {
func (s *MyAPIDonutSuite) TestBucketMultipartList(c *C) { func (s *MyAPIDonutSuite) TestBucketMultipartList(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/bucketmultipartlist", bytes.NewBufferString("")) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/bucketmultipartlist", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -765,13 +704,12 @@ func (s *MyAPIDonutSuite) TestBucketMultipartList(c *C) {
request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/bucketmultipartlist/object?uploads", bytes.NewBufferString("")) request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/bucketmultipartlist/object?uploads", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
decoder := xml.NewDecoder(response.Body) decoder := xml.NewDecoder(response.Body)
newResponse := &api.InitiateMultipartUploadResult{} newResponse := &api.InitiateMultipartUploadResponse{}
err = decoder.Decode(newResponse) err = decoder.Decode(newResponse)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -780,7 +718,6 @@ func (s *MyAPIDonutSuite) TestBucketMultipartList(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/bucketmultipartlist/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/bucketmultipartlist/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response1, err := client.Do(request) response1, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -788,7 +725,6 @@ func (s *MyAPIDonutSuite) TestBucketMultipartList(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/bucketmultipartlist/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/bucketmultipartlist/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response2, err := client.Do(request) response2, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -796,7 +732,6 @@ func (s *MyAPIDonutSuite) TestBucketMultipartList(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/bucketmultipartlist?uploads", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/bucketmultipartlist?uploads", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response3, err := client.Do(request) response3, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -812,7 +747,6 @@ func (s *MyAPIDonutSuite) TestBucketMultipartList(c *C) {
func (s *MyAPIDonutSuite) TestObjectMultipartList(c *C) { func (s *MyAPIDonutSuite) TestObjectMultipartList(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartlist", bytes.NewBufferString("")) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartlist", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -821,13 +755,12 @@ func (s *MyAPIDonutSuite) TestObjectMultipartList(c *C) {
request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/objectmultipartlist/object?uploads", bytes.NewBufferString("")) request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/objectmultipartlist/object?uploads", bytes.NewBufferString(""))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
decoder := xml.NewDecoder(response.Body) decoder := xml.NewDecoder(response.Body)
newResponse := &api.InitiateMultipartUploadResult{} newResponse := &api.InitiateMultipartUploadResponse{}
err = decoder.Decode(newResponse) err = decoder.Decode(newResponse)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -836,7 +769,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipartList(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartlist/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartlist/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response1, err := client.Do(request) response1, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -844,7 +776,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipartList(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartlist/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultipartlist/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response2, err := client.Do(request) response2, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -852,7 +783,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipartList(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/objectmultipartlist/object?uploadId="+uploadID, nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/objectmultipartlist/object?uploadId="+uploadID, nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response3, err := client.Do(request) response3, err := client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -863,7 +793,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipartList(c *C) {
func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) { func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {
request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultiparts", nil) request, err := http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultiparts", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client := http.Client{} client := http.Client{}
response, err := client.Do(request) response, err := client.Do(request)
@ -872,7 +801,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/objectmultiparts/object?uploads", nil) request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/objectmultiparts/object?uploads", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response, err = client.Do(request) response, err = client.Do(request)
@ -880,7 +808,7 @@ func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {
c.Assert(response.StatusCode, Equals, http.StatusOK) c.Assert(response.StatusCode, Equals, http.StatusOK)
decoder := xml.NewDecoder(response.Body) decoder := xml.NewDecoder(response.Body)
newResponse := &api.InitiateMultipartUploadResult{} newResponse := &api.InitiateMultipartUploadResponse{}
err = decoder.Decode(newResponse) err = decoder.Decode(newResponse)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -889,7 +817,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=1", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response1, err := client.Do(request) response1, err := client.Do(request)
@ -898,7 +825,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testAPIDonutServer.URL+"/objectmultiparts/object?uploadId="+uploadID+"&partNumber=2", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
client = http.Client{} client = http.Client{}
response2, err := client.Do(request) response2, err := client.Do(request)
@ -906,8 +832,8 @@ func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {
c.Assert(response2.StatusCode, Equals, http.StatusOK) c.Assert(response2.StatusCode, Equals, http.StatusOK)
// complete multipart upload // complete multipart upload
completeUploads := &api.CompleteMultipartUpload{ completeUploads := &donut.CompleteMultipartUpload{
Part: []api.Part{ Part: []donut.CompletePart{
{ {
PartNumber: 1, PartNumber: 1,
ETag: response1.Header.Get("ETag"), ETag: response1.Header.Get("ETag"),
@ -925,7 +851,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/objectmultiparts/object?uploadId="+uploadID, &completeBuffer) request, err = http.NewRequest("POST", testAPIDonutServer.URL+"/objectmultiparts/object?uploadId="+uploadID, &completeBuffer)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -933,7 +858,6 @@ func (s *MyAPIDonutSuite) TestObjectMultipart(c *C) {
request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/objectmultiparts/object", nil) request, err = http.NewRequest("GET", testAPIDonutServer.URL+"/objectmultiparts/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
setDummyAuthHeader(request)
response, err = client.Do(request) response, err = client.Do(request)
c.Assert(err, IsNil) c.Assert(err, IsNil)