diff --git a/main.go b/main.go index 0d5451a38..1908c0bd1 100644 --- a/main.go +++ b/main.go @@ -201,9 +201,5 @@ func main() { } return nil } - err := app.Run(os.Args) - if err != nil { - log.Error.Println(err) - } - + app.RunAndExitOnError() } diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index ea659cb01..c83a6f92e 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -379,14 +379,15 @@ func (s *MySuite) TestHeader(c *C) { testServer := httptest.NewServer(httpHandler) defer testServer.Close() + typedDriver.On("CreateBucket", "bucket").Return(nil).Once() + driver.CreateBucket("bucket") + typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNotFound{}).Once() response, err := http.Get(testServer.URL + "/bucket/object") c.Assert(err, IsNil) verifyError(c, response, "NoSuchKey", "The specified key does not exist.", http.StatusNotFound) buffer := bytes.NewBufferString("hello world") - typedDriver.On("CreateBucket", "bucket").Return(nil).Once() - driver.CreateBucket("bucket") typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(nil).Once() driver.CreateObject("bucket", "object", "", "", buffer) diff --git a/pkg/drivers/donut/donut.go b/pkg/drivers/donut/donut.go index 5497df602..d29ca2f33 100644 --- a/pkg/drivers/donut/donut.go +++ b/pkg/drivers/donut/donut.go @@ -154,16 +154,14 @@ func (d donutDriver) GetObject(target io.Writer, bucketName, objectName string) return 0, iodine.New(err, nil) } if _, ok := buckets[bucketName]; !ok { - return 0, iodine.New(errors.New("bucket does not exist"), errParams) + return 0, drivers.BucketNotFound{Bucket: bucketName} } reader, size, err := buckets[bucketName].GetObject(objectName) - if os.IsNotExist(err) { + if err != nil { return 0, drivers.ObjectNotFound{ Bucket: bucketName, Object: objectName, } - } else if err != nil { - return 0, iodine.New(err, errParams) } n, err := io.CopyN(target, reader, size) return n, iodine.New(err, errParams) @@ -193,16 +191,14 @@ func (d donutDriver) GetPartialObject(w io.Writer, bucketName, objectName string return 0, iodine.New(err, nil) } if _, ok := buckets[bucketName]; !ok { - return 0, iodine.New(errors.New("bucket does not exist"), errParams) + return 0, drivers.BucketNotFound{Bucket: bucketName} } reader, size, err := buckets[bucketName].GetObject(objectName) - if os.IsNotExist(err) { + if err != nil { return 0, drivers.ObjectNotFound{ Bucket: bucketName, Object: objectName, } - } else if err != nil { - return 0, iodine.New(err, errParams) } if start > size || (start+length-1) > size { return 0, iodine.New(errors.New("invalid range"), errParams) @@ -227,31 +223,35 @@ func (d donutDriver) GetObjectMetadata(bucketName, objectName, prefixName string return drivers.ObjectMetadata{}, iodine.New(err, errParams) } if _, ok := buckets[bucketName]; !ok { - return drivers.ObjectMetadata{}, iodine.New(errors.New("bucket does not exist"), errParams) + return drivers.ObjectMetadata{}, drivers.BucketNotFound{Bucket: bucketName} } objectList, err := buckets[bucketName].ListObjects() if err != nil { return drivers.ObjectMetadata{}, iodine.New(err, errParams) } - donutObjectMetadata, err := objectList[objectName].GetDonutObjectMetadata() - if os.IsNotExist(err) { + object, ok := objectList[objectName] + if !ok { // return ObjectNotFound quickly on an error, API needs this to handle invalid requests return drivers.ObjectMetadata{}, drivers.ObjectNotFound{ Bucket: bucketName, Object: objectName, } - } else if err != nil { - return drivers.ObjectMetadata{}, iodine.New(err, errParams) } - objectMetadata, err := objectList[objectName].GetObjectMetadata() - if os.IsNotExist(err) { + donutObjectMetadata, err := object.GetDonutObjectMetadata() + if err != nil { + // return ObjectNotFound quickly on an error, API needs this to handle invalid requests + return drivers.ObjectMetadata{}, drivers.ObjectNotFound{ + Bucket: bucketName, + Object: objectName, + } + } + objectMetadata, err := object.GetObjectMetadata() + if err != nil { // return ObjectNotFound quickly on an error, API needs this to handle invalid requests return drivers.ObjectMetadata{}, drivers.ObjectNotFound{ Bucket: bucketName, Object: objectName, } - } else if err != nil { - return drivers.ObjectMetadata{}, iodine.New(err, errParams) } created, err := time.Parse(time.RFC3339Nano, donutObjectMetadata["created"]) if err != nil { @@ -289,7 +289,7 @@ func (d donutDriver) ListObjects(bucketName string, resources drivers.BucketReso return nil, drivers.BucketResourcesMetadata{}, iodine.New(err, errParams) } if _, ok := buckets[bucketName]; !ok { - return nil, drivers.BucketResourcesMetadata{}, iodine.New(errors.New("bucket does not exist"), errParams) + return nil, drivers.BucketResourcesMetadata{}, drivers.BucketNotFound{Bucket: bucketName} } objectList, err := buckets[bucketName].ListObjects() if err != nil { @@ -360,7 +360,7 @@ func (d donutDriver) CreateObject(bucketName, objectName, contentType, expectedM return iodine.New(err, errParams) } if _, ok := buckets[bucketName]; !ok { - return iodine.New(errors.New("bucket does not exist"), errParams) + return drivers.BucketNotFound{Bucket: bucketName} } if contentType == "" { contentType = "application/octet-stream" diff --git a/pkg/drivers/file/file_object.go b/pkg/drivers/file/file_object.go index 02537b51e..bd70fdf47 100644 --- a/pkg/drivers/file/file_object.go +++ b/pkg/drivers/file/file_object.go @@ -134,11 +134,13 @@ func (file *fileDriver) GetObjectMetadata(bucket, object, prefix string) (driver if drivers.IsValidBucket(bucket) == false { return drivers.ObjectMetadata{}, drivers.BucketNameInvalid{Bucket: bucket} } - if drivers.IsValidObject(object) == false { return drivers.ObjectMetadata{}, drivers.ObjectNameInvalid{Bucket: bucket, Object: bucket} } - + // check bucket exists + if _, err := os.Stat(path.Join(file.root, bucket)); os.IsNotExist(err) { + return drivers.ObjectMetadata{}, drivers.BucketNotFound{Bucket: bucket} + } // Do not use path.Join() since path.Join strips off any object names with '/', use them as is // in a static manner so that we can send a proper 'ObjectNotFound' reply back upon os.Stat() objectPath := file.root + "/" + bucket + "/" + object diff --git a/pkg/drivers/memory/memory.go b/pkg/drivers/memory/memory.go index 7ec382ce0..bc66f924c 100644 --- a/pkg/drivers/memory/memory.go +++ b/pkg/drivers/memory/memory.go @@ -71,6 +71,9 @@ func start(ctrlChannel <-chan string, errorChannel chan<- error) { // GetObject - GET object from memory buffer func (memory memoryDriver) GetObject(w io.Writer, bucket string, object string) (int64, error) { + if _, ok := memory.bucketdata[bucket]; ok == false { + return 0, drivers.BucketNotFound{Bucket: bucket} + } // get object key := object if val, ok := memory.objectdata[key]; ok { @@ -269,6 +272,10 @@ func (memory memoryDriver) ListBuckets() ([]drivers.BucketMetadata, error) { // GetObjectMetadata - get object metadata from memory func (memory memoryDriver) GetObjectMetadata(bucket, key, prefix string) (drivers.ObjectMetadata, error) { + // check if bucket exists + if _, ok := memory.bucketdata[bucket]; ok == false { + return drivers.ObjectMetadata{}, drivers.BucketNotFound{Bucket: bucket} + } if object, ok := memory.objectdata[key]; ok == true { return object.metadata, nil }