From c4cf7635bf7d922dbfca3a830aec0ba602f2822b Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 14 Jul 2015 09:17:30 -0700 Subject: [PATCH] Read req.Body for PutBucket() if any --- pkg/donut/donut-v1_test.go | 24 ++++++++++++------------ pkg/donut/donut-v2.go | 14 ++++++++++++-- pkg/donut/donut-v2_test.go | 24 ++++++++++++------------ pkg/donut/interfaces.go | 2 +- pkg/server/api/bucket-handlers.go | 12 +++++++++++- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/pkg/donut/donut-v1_test.go b/pkg/donut/donut-v1_test.go index 52f3ed767..f3a4e2de4 100644 --- a/pkg/donut/donut-v1_test.go +++ b/pkg/donut/donut-v1_test.go @@ -86,16 +86,16 @@ 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", nil) + err := dd.MakeBucket("", "private", nil, nil) c.Assert(err, Not(IsNil)) - err = dd.MakeBucket(" ", "private", nil) + err = dd.MakeBucket(" ", "private", nil, nil) c.Assert(err, Not(IsNil)) } // test empty bucket func (s *MyDonutSuite) TestEmptyBucket(c *C) { - c.Assert(dd.MakeBucket("foo1", "private", nil), IsNil) + c.Assert(dd.MakeBucket("foo1", "private", nil, nil), IsNil) // check if bucket is empty var resources BucketResourcesMetadata resources.Maxkeys = 1 @@ -109,7 +109,7 @@ func (s *MyDonutSuite) TestEmptyBucket(c *C) { // test bucket list func (s *MyDonutSuite) TestMakeBucketAndList(c *C) { // create bucket - err := dd.MakeBucket("foo2", "private", nil) + err := dd.MakeBucket("foo2", "private", nil, nil) c.Assert(err, IsNil) // check bucket exists @@ -121,20 +121,20 @@ func (s *MyDonutSuite) TestMakeBucketAndList(c *C) { // test re-create bucket func (s *MyDonutSuite) TestMakeBucketWithSameNameFails(c *C) { - err := dd.MakeBucket("foo3", "private", nil) + err := dd.MakeBucket("foo3", "private", nil, nil) c.Assert(err, IsNil) - err = dd.MakeBucket("foo3", "private", nil) + err = dd.MakeBucket("foo3", "private", nil, 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", nil) + err := dd.MakeBucket("foo4", "private", nil, nil) c.Assert(err, IsNil) - err = dd.MakeBucket("bar1", "private", nil) + err = dd.MakeBucket("bar1", "private", nil, nil) c.Assert(err, IsNil) buckets, err := dd.ListBuckets(nil) @@ -144,7 +144,7 @@ func (s *MyDonutSuite) TestCreateMultipleBucketsAndList(c *C) { c.Assert(buckets[0].Name, Equals, "bar1") c.Assert(buckets[1].Name, Equals, "foo4") - err = dd.MakeBucket("foobar1", "private", nil) + err = dd.MakeBucket("foobar1", "private", nil, nil) c.Assert(err, IsNil) buckets, err = dd.ListBuckets(nil) @@ -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", nil) + err := dd.MakeBucket("foo6", "private", nil, 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", nil) + err := dd.MakeBucket("foo", "private", nil, nil) c.Assert(err, IsNil) data := "Hello World" @@ -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", nil), IsNil) + c.Assert(dd.MakeBucket("foo5", "private", nil, nil), IsNil) one := ioutil.NopCloser(bytes.NewReader([]byte("one"))) diff --git a/pkg/donut/donut-v2.go b/pkg/donut/donut-v2.go index bcb0997c2..c0a1e83f9 100644 --- a/pkg/donut/donut-v2.go +++ b/pkg/donut/donut-v2.go @@ -448,12 +448,22 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s } // MakeBucket - create bucket in cache -func (donut API) MakeBucket(bucketName, acl string, signature *Signature) error { +func (donut API) MakeBucket(bucketName, acl string, location io.Reader, signature *Signature) error { donut.lock.Lock() defer donut.lock.Unlock() + // do not have to parse location constraint, using this just for signature verification + locationSum := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + if location != nil { + locationConstraintBytes, err := ioutil.ReadAll(location) + if err != nil { + return iodine.New(InternalError{}, nil) + } + locationSum = hex.EncodeToString(sha256.Sum256(locationConstraintBytes)[:]) + } + if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") + ok, err := signature.DoesSignatureMatch(locationSum) if err != nil { return iodine.New(err, nil) } diff --git a/pkg/donut/donut-v2_test.go b/pkg/donut/donut-v2_test.go index 2604c401b..27706dbf9 100644 --- a/pkg/donut/donut-v2_test.go +++ b/pkg/donut/donut-v2_test.go @@ -61,16 +61,16 @@ 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", nil) + err := dc.MakeBucket("", "private", nil, nil) c.Assert(err, Not(IsNil)) - err = dc.MakeBucket(" ", "private", nil) + err = dc.MakeBucket(" ", "private", nil, nil) c.Assert(err, Not(IsNil)) } // test empty bucket func (s *MyCacheSuite) TestEmptyBucket(c *C) { - c.Assert(dc.MakeBucket("foo1", "private", nil), IsNil) + c.Assert(dc.MakeBucket("foo1", "private", nil, nil), IsNil) // check if bucket is empty var resources BucketResourcesMetadata resources.Maxkeys = 1 @@ -84,7 +84,7 @@ func (s *MyCacheSuite) TestEmptyBucket(c *C) { // test bucket list func (s *MyCacheSuite) TestMakeBucketAndList(c *C) { // create bucket - err := dc.MakeBucket("foo2", "private", nil) + err := dc.MakeBucket("foo2", "private", nil, nil) c.Assert(err, IsNil) // check bucket exists @@ -96,20 +96,20 @@ func (s *MyCacheSuite) TestMakeBucketAndList(c *C) { // test re-create bucket func (s *MyCacheSuite) TestMakeBucketWithSameNameFails(c *C) { - err := dc.MakeBucket("foo3", "private", nil) + err := dc.MakeBucket("foo3", "private", nil, nil) c.Assert(err, IsNil) - err = dc.MakeBucket("foo3", "private", nil) + err = dc.MakeBucket("foo3", "private", nil, 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", nil) + err := dc.MakeBucket("foo4", "private", nil, nil) c.Assert(err, IsNil) - err = dc.MakeBucket("bar1", "private", nil) + err = dc.MakeBucket("bar1", "private", nil, nil) c.Assert(err, IsNil) buckets, err := dc.ListBuckets(nil) @@ -119,7 +119,7 @@ func (s *MyCacheSuite) TestCreateMultipleBucketsAndList(c *C) { c.Assert(buckets[0].Name, Equals, "bar1") c.Assert(buckets[1].Name, Equals, "foo4") - err = dc.MakeBucket("foobar1", "private", nil) + err = dc.MakeBucket("foobar1", "private", nil, nil) c.Assert(err, IsNil) buckets, err = dc.ListBuckets(nil) @@ -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", nil) + err := dc.MakeBucket("foo6", "private", nil, 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", nil) + err := dc.MakeBucket("foo", "private", nil, nil) c.Assert(err, IsNil) data := "Hello World" @@ -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", nil), IsNil) + c.Assert(dc.MakeBucket("foo5", "private", nil, nil), IsNil) one := ioutil.NopCloser(bytes.NewReader([]byte("one"))) diff --git a/pkg/donut/interfaces.go b/pkg/donut/interfaces.go index a2870770e..4a8d0a88d 100644 --- a/pkg/donut/interfaces.go +++ b/pkg/donut/interfaces.go @@ -32,7 +32,7 @@ type ObjectStorage interface { 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 + MakeBucket(bucket string, ACL string, location io.Reader, signature *Signature) error // Bucket operations ListObjects(string, BucketResourcesMetadata, *Signature) ([]ObjectMetadata, BucketResourcesMetadata, error) diff --git a/pkg/server/api/bucket-handlers.go b/pkg/server/api/bucket-handlers.go index 12b4d9527..d5b34d35a 100644 --- a/pkg/server/api/bucket-handlers.go +++ b/pkg/server/api/bucket-handlers.go @@ -296,7 +296,17 @@ func (api Minio) PutBucketHandler(w http.ResponseWriter, req *http.Request) { } } - err := api.Donut.MakeBucket(bucket, getACLTypeString(aclType), signature) + // if body of request is non-nil then check for validity of Content-Length + if req.Body != nil { + /// if Content-Length missing, deny the request + size := req.Header.Get("Content-Length") + if size == "" { + writeErrorResponse(w, req, MissingContentLength, acceptsContentType, req.URL.Path) + return + } + } + + err := api.Donut.MakeBucket(bucket, getACLTypeString(aclType), req.Body, signature) switch iodine.ToError(err).(type) { case nil: // Make sure to add Location information here only for bucket