All other API's now support signature v4

master
Harshavardhana 9 years ago
parent 00890c254e
commit 84f427f14a
  1. 44
      pkg/donut/donut-v1_test.go
  2. 73
      pkg/donut/donut-v2.go
  3. 44
      pkg/donut/donut-v2_test.go
  4. 20
      pkg/donut/interfaces.go
  5. 49
      pkg/donut/multipart.go
  6. 80
      pkg/server/api/bucket-handlers.go
  7. 65
      pkg/server/api/object-handlers.go
  8. 2
      pkg/server/api/response.go

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

@ -180,6 +180,7 @@ func (donut API) GetPartialObject(w io.Writer, bucket, object string, start, len
"start": strconv.FormatInt(start, 10),
"length": strconv.FormatInt(length, 10),
}
if !IsValidBucket(bucket) {
return 0, iodine.New(BucketNameInvalid{Bucket: bucket}, errParams)
}
@ -226,10 +227,20 @@ func (donut API) GetPartialObject(w io.Writer, bucket, object string, start, len
}
// GetBucketMetadata -
func (donut API) GetBucketMetadata(bucket string) (BucketMetadata, error) {
func (donut API) GetBucketMetadata(bucket string, signature *Signature) (BucketMetadata, error) {
donut.lock.Lock()
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) {
return BucketMetadata{}, iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
}
@ -249,10 +260,20 @@ func (donut API) GetBucketMetadata(bucket string) (BucketMetadata, error) {
}
// 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()
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) {
return iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
}
@ -424,10 +445,20 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
}
// 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()
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 {
return iodine.New(TooManyBuckets{Bucket: bucketName}, nil)
}
@ -463,10 +494,20 @@ func (donut API) MakeBucket(bucketName, acl string) error {
}
// 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()
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) {
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 }
// ListBuckets - List buckets from cache
func (donut API) ListBuckets() ([]BucketMetadata, error) {
func (donut API) ListBuckets(signature *Signature) ([]BucketMetadata, error) {
donut.lock.Lock()
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
if len(donut.config.NodeDiskMap) > 0 {
buckets, err := donut.listBuckets()
@ -580,10 +631,20 @@ func (donut API) ListBuckets() ([]BucketMetadata, error) {
}
// 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()
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
if !IsValidBucket(bucket) {
return ObjectMetadata{}, iodine.New(BucketNameInvalid{Bucket: bucket}, nil)

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

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

@ -39,10 +39,20 @@ import (
)
// 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()
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) {
return "", iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
}
@ -74,10 +84,20 @@ func (donut API) NewMultipartUpload(bucket, key, contentType string) (string, er
}
// 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()
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) {
return iodine.New(BucketNameInvalid{Bucket: bucket}, nil)
}
@ -313,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 }
// 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
donut.lock.Lock()
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) {
return BucketMultipartResourcesMetadata{}, iodine.New(BucketNotFound{Bucket: bucket}, nil)
}
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
var uploads []*UploadMetadata
@ -376,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 }
// 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
donut.lock.Lock()
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) {
return ObjectResourcesMetadata{}, iodine.New(BucketNotFound{Bucket: bucket}, nil)
}

@ -29,7 +29,7 @@ func (api Minio) isValidOp(w http.ResponseWriter, req *http.Request, acceptsCont
vars := mux.Vars(req)
bucket := vars["bucket"]
bucketMetadata, err := api.Donut.GetBucketMetadata(bucket)
bucketMetadata, err := api.Donut.GetBucketMetadata(bucket, nil)
switch iodine.ToError(err).(type) {
case donut.BucketNotFound:
{
@ -95,7 +95,18 @@ func (api Minio) ListMultipartUploadsHandler(w http.ResponseWriter, req *http.Re
vars := mux.Vars(req)
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) {
case nil: // success
{
@ -153,7 +164,18 @@ func (api Minio) ListObjectsHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
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) {
case nil:
// generate response
@ -199,7 +221,18 @@ func (api Minio) ListBucketsHandler(w http.ResponseWriter, req *http.Request) {
// 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) {
case nil:
// generate response
@ -250,7 +283,18 @@ func (api Minio) PutBucketHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
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) {
case nil:
// 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)
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) {
case nil:
writeSuccessResponse(w, acceptsContentType)
@ -328,7 +383,18 @@ func (api Minio) HeadBucketHandler(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
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) {
case nil:
writeSuccessResponse(w, acceptsContentType)

@ -54,7 +54,18 @@ func (api Minio) GetObjectHandler(w http.ResponseWriter, req *http.Request) {
bucket = vars["bucket"]
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) {
case nil: // success
{
@ -117,7 +128,18 @@ func (api Minio) HeadObjectHandler(w http.ResponseWriter, req *http.Request) {
bucket = vars["bucket"]
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) {
case nil:
setObjectHeaders(w, metadata)
@ -270,7 +292,18 @@ func (api Minio) NewMultipartUploadHandler(w http.ResponseWriter, req *http.Requ
bucket = vars["bucket"]
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) {
case nil:
{
@ -401,7 +434,18 @@ func (api Minio) AbortMultipartUploadHandler(w http.ResponseWriter, req *http.Re
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) {
case nil:
setCommonHeaders(w, getContentTypeString(acceptsContentType), 0)
@ -439,7 +483,18 @@ func (api Minio) ListObjectPartsHandler(w http.ResponseWriter, req *http.Request
bucket := vars["bucket"]
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) {
case nil:
{

@ -85,7 +85,7 @@ func generateListObjectsResponse(bucket string, objects []donut.ObjectMetadata,
continue
}
content.Key = object.Object
content.LastModified = object.Created.Format(iso8601Format)
content.LastModified = object.Created.Format(rfcFormat)
content.ETag = "\"" + object.MD5Sum + "\""
content.Size = object.Size
content.StorageClass = "STANDARD"

Loading…
Cancel
Save