Change CreateObject() to take size argument from content-length

master
Harshavardhana 10 years ago
parent c342ce1588
commit f7caef2d26
  1. 9
      pkg/api/api_object_handlers.go
  2. 34
      pkg/api/api_test.go
  3. 8
      pkg/storage/donut/donut_bucket.go
  4. 17
      pkg/storage/donut/donut_test.go
  5. 37
      pkg/storage/drivers/api_testsuite.go
  6. 2
      pkg/storage/drivers/driver.go
  7. 7
      pkg/storage/drivers/errors.go

@ -18,6 +18,7 @@ package api
import ( import (
"net/http" "net/http"
"strconv"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/minio-io/minio/pkg/iodine" "github.com/minio-io/minio/pkg/iodine"
@ -155,10 +156,10 @@ func (server *minioAPI) putObjectHandler(w http.ResponseWriter, req *http.Reques
writeErrorResponse(w, req, InvalidDigest, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, InvalidDigest, acceptsContentType, req.URL.Path)
return return
} }
/// if Content-Length missing, incomplete request throw IncompleteBody /// if Content-Length missing, throw away
size := req.Header.Get("Content-Length") size := req.Header.Get("Content-Length")
if size == "" { if size == "" {
writeErrorResponse(w, req, IncompleteBody, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, MissingContentLength, acceptsContentType, req.URL.Path)
return return
} }
/// maximum Upload size for objects in a single operation /// maximum Upload size for objects in a single operation
@ -171,7 +172,9 @@ func (server *minioAPI) putObjectHandler(w http.ResponseWriter, req *http.Reques
writeErrorResponse(w, req, EntityTooSmall, acceptsContentType, req.URL.Path) writeErrorResponse(w, req, EntityTooSmall, acceptsContentType, req.URL.Path)
return return
} }
calculatedMD5, err := server.driver.CreateObject(bucket, object, "", md5, req.Body) // ignoring error here, TODO find a way to reply back if we can
sizeInt, _ := strconv.ParseInt(size, 10, 64)
calculatedMD5, err := server.driver.CreateObject(bucket, object, "", md5, sizeInt, req.Body)
switch err := iodine.ToError(err).(type) { switch err := iodine.ToError(err).(type) {
case nil: case nil:
{ {

@ -168,7 +168,7 @@ func (s *MySuite) TestEmptyObject(c *C) {
Size: 0, Size: 0,
} }
typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once() typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once()
typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(metadata.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "object", "", "", 0, mock.Anything).Return(metadata.Md5, nil).Once()
typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Twice() typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Twice()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Once() typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Once()
typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once() typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once()
@ -179,7 +179,7 @@ func (s *MySuite) TestEmptyObject(c *C) {
buffer := bytes.NewBufferString("") buffer := bytes.NewBufferString("")
driver.CreateBucket("bucket", "private") driver.CreateBucket("bucket", "private")
driver.CreateObject("bucket", "object", "", "", buffer) driver.CreateObject("bucket", "object", "", "", 0, buffer)
request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil) request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -250,7 +250,7 @@ func (s *MySuite) TestObject(c *C) {
Size: 11, Size: 11,
} }
typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once() typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once()
typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(metadata.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything, mock.Anything).Return(metadata.Md5, nil).Once()
typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Twice() typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Twice()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Twice() typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(metadata, nil).Twice()
typedDriver.SetGetObjectWriter("bucket", "object", []byte("hello world")) typedDriver.SetGetObjectWriter("bucket", "object", []byte("hello world"))
@ -262,7 +262,7 @@ func (s *MySuite) TestObject(c *C) {
buffer := bytes.NewBufferString("hello world") buffer := bytes.NewBufferString("hello world")
driver.CreateBucket("bucket", "private") driver.CreateBucket("bucket", "private")
driver.CreateObject("bucket", "object", "", "", buffer) driver.CreateObject("bucket", "object", "", "", int64(buffer.Len()), buffer)
request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil) request, err := http.NewRequest("GET", testServer.URL+"/bucket/object", nil)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -325,12 +325,12 @@ func (s *MySuite) TestMultipleObjects(c *C) {
typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once() typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once()
driver.CreateBucket("bucket", "private") driver.CreateBucket("bucket", "private")
typedDriver.On("CreateObject", "bucket", "object1", "", "", mock.Anything).Return(metadata1.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "object1", "", "", mock.Anything, mock.Anything).Return(metadata1.Md5, nil).Once()
driver.CreateObject("bucket", "object1", "", "", buffer1) driver.CreateObject("bucket", "object1", "", "", int64(buffer1.Len()), buffer1)
typedDriver.On("CreateObject", "bucket", "object2", "", "", mock.Anything).Return(metadata2.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "object2", "", "", mock.Anything, mock.Anything).Return(metadata2.Md5, nil).Once()
driver.CreateObject("bucket", "object2", "", "", buffer2) driver.CreateObject("bucket", "object2", "", "", int64(buffer2.Len()), buffer2)
typedDriver.On("CreateObject", "bucket", "object3", "", "", mock.Anything).Return(metadata3.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "object3", "", "", mock.Anything, mock.Anything).Return(metadata3.Md5, nil).Once()
driver.CreateObject("bucket", "object3", "", "", buffer3) driver.CreateObject("bucket", "object3", "", "", int64(buffer3.Len()), buffer3)
// test non-existant object // test non-existant object
typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(drivers.BucketMetadata{}, nil).Once()
@ -506,8 +506,8 @@ func (s *MySuite) TestHeader(c *C) {
buffer := bytes.NewBufferString("hello world") buffer := bytes.NewBufferString("hello world")
typedDriver.On("GetBucketMetadata", "foo").Return(bucketMetadata, nil).Once() typedDriver.On("GetBucketMetadata", "foo").Return(bucketMetadata, nil).Once()
typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(objectMetadata.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything, mock.Anything).Return(objectMetadata.Md5, nil).Once()
driver.CreateObject("bucket", "object", "", "", buffer) driver.CreateObject("bucket", "object", "", "", int64(buffer.Len()), buffer)
typedDriver.On("GetBucketMetadata", "bucket").Return(bucketMetadata, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(bucketMetadata, nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(objectMetadata, nil).Once() typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(objectMetadata, nil).Once()
@ -618,7 +618,7 @@ func (s *MySuite) TestPutObject(c *C) {
Size: 11, Size: 11,
} }
typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything).Return(twoMetadata.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything, mock.Anything).Return(twoMetadata.Md5, nil).Once()
request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world"))
c.Assert(err, IsNil) c.Assert(err, IsNil)
setAuthHeader(request) setAuthHeader(request)
@ -905,7 +905,7 @@ func (s *MySuite) TestContentTypePersists(c *C) {
} }
typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once()
typedDriver.On("CreateObject", "bucket", "one", "", "", mock.Anything).Return(oneMetadata.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "one", "", "", mock.Anything, mock.Anything).Return(oneMetadata.Md5, nil).Once()
request, err := http.NewRequest("PUT", testServer.URL+"/bucket/one", bytes.NewBufferString("hello world")) request, err := http.NewRequest("PUT", testServer.URL+"/bucket/one", bytes.NewBufferString("hello world"))
delete(request.Header, "Content-Type") delete(request.Header, "Content-Type")
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -952,7 +952,7 @@ func (s *MySuite) TestContentTypePersists(c *C) {
} }
typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once()
typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything).Return(twoMetadata.Md5, nil).Once() typedDriver.On("CreateObject", "bucket", "two", "", "", mock.Anything, mock.Anything).Return(twoMetadata.Md5, nil).Once()
request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world")) request, err = http.NewRequest("PUT", testServer.URL+"/bucket/two", bytes.NewBufferString("hello world"))
delete(request.Header, "Content-Type") delete(request.Header, "Content-Type")
request.Header.Add("Content-Type", "application/json") request.Header.Add("Content-Type", "application/json")
@ -1010,11 +1010,11 @@ func (s *MySuite) TestPartialContent(c *C) {
} }
typedDriver.On("CreateBucket", "foo", "private").Return(nil).Once() typedDriver.On("CreateBucket", "foo", "private").Return(nil).Once()
typedDriver.On("CreateObject", "foo", "bar", "", "", mock.Anything).Return(metadata.Md5, nil).Once() typedDriver.On("CreateObject", "foo", "bar", "", "", mock.Anything, mock.Anything).Return(metadata.Md5, nil).Once()
err := driver.CreateBucket("foo", "private") err := driver.CreateBucket("foo", "private")
c.Assert(err, IsNil) c.Assert(err, IsNil)
driver.CreateObject("foo", "bar", "", "", bytes.NewBufferString("hello world")) driver.CreateObject("foo", "bar", "", "", int64(len("hello world")), bytes.NewBufferString("hello world"))
// prepare for GET on range request // prepare for GET on range request
typedDriver.SetGetObjectWriter("foo", "bar", []byte("hello world")) typedDriver.SetGetObjectWriter("foo", "bar", []byte("hello world"))

@ -151,11 +151,17 @@ func (b bucket) PutObject(objectName string, objectData io.Reader, expectedMD5Su
donutObjectMetadata := make(map[string]string) donutObjectMetadata := make(map[string]string)
objectMetadata["version"] = "1.0" objectMetadata["version"] = "1.0"
donutObjectMetadata["version"] = "1.0" donutObjectMetadata["version"] = "1.0"
size := metadata["contentLength"]
sizeInt, err := strconv.ParseInt(size, 10, 64)
if err != nil {
return "", iodine.New(err, nil)
}
// if total writers are only '1' do not compute erasure // if total writers are only '1' do not compute erasure
switch len(writers) == 1 { switch len(writers) == 1 {
case true: case true:
mw := io.MultiWriter(writers[0], summer) mw := io.MultiWriter(writers[0], summer)
totalLength, err := io.Copy(mw, objectData) totalLength, err := io.CopyN(mw, objectData, sizeInt)
if err != nil { if err != nil {
return "", iodine.New(err, nil) return "", iodine.New(err, nil)
} }

@ -184,6 +184,7 @@ func (s *MySuite) TestNewObjectMetadata(c *C) {
hasher.Write([]byte(data)) hasher.Write([]byte(data))
expectedMd5Sum := hex.EncodeToString(hasher.Sum(nil)) expectedMd5Sum := hex.EncodeToString(hasher.Sum(nil))
reader := ioutil.NopCloser(bytes.NewReader([]byte(data))) reader := ioutil.NopCloser(bytes.NewReader([]byte(data)))
metadata["contentLength"] = strconv.Itoa(len(data))
err = donut.MakeBucket("foo", "private") err = donut.MakeBucket("foo", "private")
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -210,9 +211,6 @@ func (s *MySuite) TestNewObjectFailsWithEmptyName(c *C) {
_, err = donut.PutObject("foo", "", "", nil, nil) _, err = donut.PutObject("foo", "", "", nil, nil)
c.Assert(err, Not(IsNil)) c.Assert(err, Not(IsNil))
_, err = donut.PutObject("foo", " ", "", nil, nil)
c.Assert(err, Not(IsNil))
} }
// test create object // test create object
@ -234,6 +232,7 @@ func (s *MySuite) TestNewObjectCanBeWritten(c *C) {
hasher.Write([]byte(data)) hasher.Write([]byte(data))
expectedMd5Sum := hex.EncodeToString(hasher.Sum(nil)) expectedMd5Sum := hex.EncodeToString(hasher.Sum(nil))
reader := ioutil.NopCloser(bytes.NewReader([]byte(data))) reader := ioutil.NopCloser(bytes.NewReader([]byte(data)))
metadata["contentLength"] = strconv.Itoa(len(data))
calculatedMd5Sum, err := donut.PutObject("foo", "obj", expectedMd5Sum, reader, metadata) calculatedMd5Sum, err := donut.PutObject("foo", "obj", expectedMd5Sum, reader, metadata)
c.Assert(err, IsNil) c.Assert(err, IsNil)
@ -268,11 +267,16 @@ func (s *MySuite) TestMultipleNewObjects(c *C) {
c.Assert(donut.MakeBucket("foo", "private"), IsNil) c.Assert(donut.MakeBucket("foo", "private"), IsNil)
one := ioutil.NopCloser(bytes.NewReader([]byte("one"))) one := ioutil.NopCloser(bytes.NewReader([]byte("one")))
_, err = donut.PutObject("foo", "obj1", "", one, nil) metadata := make(map[string]string)
metadata["contentLength"] = strconv.Itoa(len("one"))
_, err = donut.PutObject("foo", "obj1", "", one, metadata)
c.Assert(err, IsNil) c.Assert(err, IsNil)
two := ioutil.NopCloser(bytes.NewReader([]byte("two"))) two := ioutil.NopCloser(bytes.NewReader([]byte("two")))
_, err = donut.PutObject("foo", "obj2", "", two, nil)
metadata["contentLength"] = strconv.Itoa(len("two"))
_, err = donut.PutObject("foo", "obj2", "", two, metadata)
c.Assert(err, IsNil) c.Assert(err, IsNil)
obj1, size, err := donut.GetObject("foo", "obj1") obj1, size, err := donut.GetObject("foo", "obj1")
@ -315,7 +319,8 @@ func (s *MySuite) TestMultipleNewObjects(c *C) {
c.Assert(listObjects, DeepEquals, []string{"obj1", "obj2"}) c.Assert(listObjects, DeepEquals, []string{"obj1", "obj2"})
three := ioutil.NopCloser(bytes.NewReader([]byte("three"))) three := ioutil.NopCloser(bytes.NewReader([]byte("three")))
_, err = donut.PutObject("foo", "obj3", "", three, nil) metadata["contentLength"] = strconv.Itoa(len("three"))
_, err = donut.PutObject("foo", "obj3", "", three, metadata)
c.Assert(err, IsNil) c.Assert(err, IsNil)
obj3, size, err := donut.GetObject("foo", "obj3") obj3, size, err := donut.GetObject("foo", "obj3")

@ -73,7 +73,8 @@ func testMultipleObjectCreation(c *check.C, create func() Driver) {
key := "obj" + strconv.Itoa(i) key := "obj" + strconv.Itoa(i)
objects[key] = []byte(randomString) objects[key] = []byte(randomString)
calculatedmd5sum, err := drivers.CreateObject("bucket", key, "", expectedmd5Sum, bytes.NewBufferString(randomString)) calculatedmd5sum, err := drivers.CreateObject("bucket", key, "", expectedmd5Sum, int64(len(randomString)),
bytes.NewBufferString(randomString))
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(calculatedmd5sum, check.Equals, expectedmd5Sumhex) c.Assert(calculatedmd5sum, check.Equals, expectedmd5Sumhex)
} }
@ -107,7 +108,7 @@ func testPaging(c *check.C, create func() Driver) {
// check before paging occurs // check before paging occurs
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
key := "obj" + strconv.Itoa(i) key := "obj" + strconv.Itoa(i)
drivers.CreateObject("bucket", key, "", "", bytes.NewBufferString(key)) drivers.CreateObject("bucket", key, "", "", int64(len(key)), bytes.NewBufferString(key))
resources.Maxkeys = 5 resources.Maxkeys = 5
resources.Prefix = "" resources.Prefix = ""
objects, resources, err = drivers.ListObjects("bucket", resources) objects, resources, err = drivers.ListObjects("bucket", resources)
@ -118,7 +119,7 @@ func testPaging(c *check.C, create func() Driver) {
// check after paging occurs pages work // check after paging occurs pages work
for i := 6; i <= 10; i++ { for i := 6; i <= 10; i++ {
key := "obj" + strconv.Itoa(i) key := "obj" + strconv.Itoa(i)
drivers.CreateObject("bucket", key, "", "", bytes.NewBufferString(key)) drivers.CreateObject("bucket", key, "", "", int64(len(key)), bytes.NewBufferString(key))
resources.Maxkeys = 5 resources.Maxkeys = 5
resources.Prefix = "" resources.Prefix = ""
objects, resources, err = drivers.ListObjects("bucket", resources) objects, resources, err = drivers.ListObjects("bucket", resources)
@ -128,8 +129,8 @@ func testPaging(c *check.C, create func() Driver) {
} }
// check paging with prefix at end returns less objects // check paging with prefix at end returns less objects
{ {
drivers.CreateObject("bucket", "newPrefix", "", "", bytes.NewBufferString("prefix1")) drivers.CreateObject("bucket", "newPrefix", "", "", int64(len("prefix1")), bytes.NewBufferString("prefix1"))
drivers.CreateObject("bucket", "newPrefix2", "", "", bytes.NewBufferString("prefix2")) drivers.CreateObject("bucket", "newPrefix2", "", "", int64(len("prefix2")), bytes.NewBufferString("prefix2"))
resources.Prefix = "new" resources.Prefix = "new"
resources.Maxkeys = 5 resources.Maxkeys = 5
objects, resources, err = drivers.ListObjects("bucket", resources) objects, resources, err = drivers.ListObjects("bucket", resources)
@ -150,8 +151,8 @@ func testPaging(c *check.C, create func() Driver) {
// check delimited results with delimiter and prefix // check delimited results with delimiter and prefix
{ {
drivers.CreateObject("bucket", "this/is/delimited", "", "", bytes.NewBufferString("prefix1")) drivers.CreateObject("bucket", "this/is/delimited", "", "", int64(len("prefix1")), bytes.NewBufferString("prefix1"))
drivers.CreateObject("bucket", "this/is/also/a/delimited/file", "", "", bytes.NewBufferString("prefix2")) drivers.CreateObject("bucket", "this/is/also/a/delimited/file", "", "", int64(len("prefix2")), bytes.NewBufferString("prefix2"))
var prefixes []string var prefixes []string
resources.CommonPrefixes = prefixes // allocate new everytime resources.CommonPrefixes = prefixes // allocate new everytime
resources.Delimiter = "/" resources.Delimiter = "/"
@ -210,14 +211,14 @@ func testObjectOverwriteFails(c *check.C, create func() Driver) {
hasher1.Write([]byte("one")) hasher1.Write([]byte("one"))
md5Sum1 := base64.StdEncoding.EncodeToString(hasher1.Sum(nil)) md5Sum1 := base64.StdEncoding.EncodeToString(hasher1.Sum(nil))
md5Sum1hex := hex.EncodeToString(hasher1.Sum(nil)) md5Sum1hex := hex.EncodeToString(hasher1.Sum(nil))
md5Sum11, err := drivers.CreateObject("bucket", "object", "", md5Sum1, bytes.NewBufferString("one")) md5Sum11, err := drivers.CreateObject("bucket", "object", "", md5Sum1, int64(len("one")), bytes.NewBufferString("one"))
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(md5Sum1hex, check.Equals, md5Sum11) c.Assert(md5Sum1hex, check.Equals, md5Sum11)
hasher2 := md5.New() hasher2 := md5.New()
hasher2.Write([]byte("three")) hasher2.Write([]byte("three"))
md5Sum2 := base64.StdEncoding.EncodeToString(hasher2.Sum(nil)) md5Sum2 := base64.StdEncoding.EncodeToString(hasher2.Sum(nil))
_, err = drivers.CreateObject("bucket", "object", "", md5Sum2, bytes.NewBufferString("three")) _, err = drivers.CreateObject("bucket", "object", "", md5Sum2, int64(len("three")), bytes.NewBufferString("three"))
c.Assert(err, check.Not(check.IsNil)) c.Assert(err, check.Not(check.IsNil))
var bytesBuffer bytes.Buffer var bytesBuffer bytes.Buffer
@ -229,7 +230,7 @@ func testObjectOverwriteFails(c *check.C, create func() Driver) {
func testNonExistantBucketOperations(c *check.C, create func() Driver) { func testNonExistantBucketOperations(c *check.C, create func() Driver) {
drivers := create() drivers := create()
_, err := drivers.CreateObject("bucket", "object", "", "", bytes.NewBufferString("one")) _, err := drivers.CreateObject("bucket", "object", "", "", int64(len("one")), bytes.NewBufferString("one"))
c.Assert(err, check.Not(check.IsNil)) c.Assert(err, check.Not(check.IsNil))
} }
@ -260,7 +261,8 @@ func testPutObjectInSubdir(c *check.C, create func() Driver) {
hasher.Write([]byte("hello world")) hasher.Write([]byte("hello world"))
md5Sum1 := base64.StdEncoding.EncodeToString(hasher.Sum(nil)) md5Sum1 := base64.StdEncoding.EncodeToString(hasher.Sum(nil))
md5Sum1hex := hex.EncodeToString(hasher.Sum(nil)) md5Sum1hex := hex.EncodeToString(hasher.Sum(nil))
md5Sum11, err := drivers.CreateObject("bucket", "dir1/dir2/object", "", md5Sum1, bytes.NewBufferString("hello world")) md5Sum11, err := drivers.CreateObject("bucket", "dir1/dir2/object", "", md5Sum1, int64(len("hello world")),
bytes.NewBufferString("hello world"))
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(md5Sum11, check.Equals, md5Sum1hex) c.Assert(md5Sum11, check.Equals, md5Sum1hex)
@ -356,7 +358,8 @@ func testGetDirectoryReturnsObjectNotFound(c *check.C, create func() Driver) {
err := drivers.CreateBucket("bucket", "") err := drivers.CreateBucket("bucket", "")
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
_, err = drivers.CreateObject("bucket", "dir1/dir2/object", "", "", bytes.NewBufferString("hello world")) _, err = drivers.CreateObject("bucket", "dir1/dir2/object", "", "", int64(len("hello world")),
bytes.NewBufferString("hello world"))
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
var byteBuffer bytes.Buffer var byteBuffer bytes.Buffer
@ -400,19 +403,19 @@ func testDefaultContentType(c *check.C, create func() Driver) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
// test empty // test empty
_, err = drivers.CreateObject("bucket", "one", "", "", bytes.NewBufferString("one")) _, err = drivers.CreateObject("bucket", "one", "", "", int64(len("one")), bytes.NewBufferString("one"))
metadata, err := drivers.GetObjectMetadata("bucket", "one", "") metadata, err := drivers.GetObjectMetadata("bucket", "one", "")
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(metadata.ContentType, check.Equals, "application/octet-stream") c.Assert(metadata.ContentType, check.Equals, "application/octet-stream")
// test custom // test custom
drivers.CreateObject("bucket", "two", "application/text", "", bytes.NewBufferString("two")) drivers.CreateObject("bucket", "two", "application/text", "", int64(len("two")), bytes.NewBufferString("two"))
metadata, err = drivers.GetObjectMetadata("bucket", "two", "") metadata, err = drivers.GetObjectMetadata("bucket", "two", "")
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(metadata.ContentType, check.Equals, "application/text") c.Assert(metadata.ContentType, check.Equals, "application/text")
// test trim space // test trim space
drivers.CreateObject("bucket", "three", "\tapplication/json ", "", bytes.NewBufferString("three")) drivers.CreateObject("bucket", "three", "\tapplication/json ", "", int64(len("three")), bytes.NewBufferString("three"))
metadata, err = drivers.GetObjectMetadata("bucket", "three", "") metadata, err = drivers.GetObjectMetadata("bucket", "three", "")
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(metadata.ContentType, check.Equals, "application/json") c.Assert(metadata.ContentType, check.Equals, "application/json")
@ -425,12 +428,12 @@ func testContentMd5Set(c *check.C, create func() Driver) {
// test md5 invalid // test md5 invalid
badmd5Sum := "NWJiZjVhNTIzMjhlNzQzOWFlNmU3MTlkZmU3MTIyMDA" badmd5Sum := "NWJiZjVhNTIzMjhlNzQzOWFlNmU3MTlkZmU3MTIyMDA"
calculatedmd5sum, err := drivers.CreateObject("bucket", "one", "", badmd5Sum, bytes.NewBufferString("one")) calculatedmd5sum, err := drivers.CreateObject("bucket", "one", "", badmd5Sum, int64(len("one")), bytes.NewBufferString("one"))
c.Assert(err, check.Not(check.IsNil)) c.Assert(err, check.Not(check.IsNil))
c.Assert(calculatedmd5sum, check.Not(check.Equals), badmd5Sum) c.Assert(calculatedmd5sum, check.Not(check.Equals), badmd5Sum)
goodmd5sum := "NWJiZjVhNTIzMjhlNzQzOWFlNmU3MTlkZmU3MTIyMDA=" goodmd5sum := "NWJiZjVhNTIzMjhlNzQzOWFlNmU3MTlkZmU3MTIyMDA="
calculatedmd5sum, err = drivers.CreateObject("bucket", "two", "", goodmd5sum, bytes.NewBufferString("one")) calculatedmd5sum, err = drivers.CreateObject("bucket", "two", "", goodmd5sum, int64(len("one")), bytes.NewBufferString("one"))
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(calculatedmd5sum, check.Equals, goodmd5sum) c.Assert(calculatedmd5sum, check.Equals, goodmd5sum)
} }

@ -37,7 +37,7 @@ type Driver interface {
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 string, object string, prefix string) (ObjectMetadata, error) GetObjectMetadata(bucket string, object string, prefix string) (ObjectMetadata, error)
ListObjects(bucket string, resources BucketResourcesMetadata) ([]ObjectMetadata, BucketResourcesMetadata, error) ListObjects(bucket string, resources BucketResourcesMetadata) ([]ObjectMetadata, BucketResourcesMetadata, error)
CreateObject(bucket string, key string, contentType string, md5sum string, data io.Reader) (string, error) CreateObject(bucket string, key string, contentType string, md5sum string, size int64, data io.Reader) (string, error)
} }
// BucketACL - bucket level access control // BucketACL - bucket level access control

@ -92,9 +92,8 @@ type ObjectExists GenericObjectError
// EntityTooLarge - object size exceeds maximum limit // EntityTooLarge - object size exceeds maximum limit
type EntityTooLarge struct { type EntityTooLarge struct {
GenericObjectError GenericObjectError
Size string Size string
TotalSize string MaxSize string
MaxSize string
} }
// ObjectNameInvalid - object name provided is invalid // ObjectNameInvalid - object name provided is invalid
@ -170,7 +169,7 @@ func (e ObjectNameInvalid) Error() string {
// Return string an error formatted as the given text // Return string an error formatted as the given text
func (e EntityTooLarge) Error() string { func (e EntityTooLarge) Error() string {
return e.Bucket + "#" + e.Object + "with " + e.Size + "reached maximum allowed size limit " + e.TotalSize return e.Bucket + "#" + e.Object + "with " + e.Size + "reached maximum allowed size limit " + e.MaxSize
} }
// Return string an error formatted as the given text // Return string an error formatted as the given text

Loading…
Cancel
Save