Return proper return for all drivers when BucketNotFound

master
Harshavardhana 10 years ago
parent 0475d7d056
commit d324c4b061
  1. 6
      main.go
  2. 5
      pkg/api/api_test.go
  3. 38
      pkg/drivers/donut/donut.go
  4. 6
      pkg/drivers/file/file_object.go
  5. 7
      pkg/drivers/memory/memory.go

@ -201,9 +201,5 @@ func main() {
} }
return nil return nil
} }
err := app.Run(os.Args) app.RunAndExitOnError()
if err != nil {
log.Error.Println(err)
}
} }

@ -379,14 +379,15 @@ func (s *MySuite) TestHeader(c *C) {
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
typedDriver.On("CreateBucket", "bucket").Return(nil).Once()
driver.CreateBucket("bucket")
typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNotFound{}).Once() typedDriver.On("GetObjectMetadata", "bucket", "object", "").Return(drivers.ObjectMetadata{}, drivers.ObjectNotFound{}).Once()
response, err := http.Get(testServer.URL + "/bucket/object") response, err := http.Get(testServer.URL + "/bucket/object")
c.Assert(err, IsNil) c.Assert(err, IsNil)
verifyError(c, response, "NoSuchKey", "The specified key does not exist.", http.StatusNotFound) verifyError(c, response, "NoSuchKey", "The specified key does not exist.", http.StatusNotFound)
buffer := bytes.NewBufferString("hello world") 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() typedDriver.On("CreateObject", "bucket", "object", "", "", mock.Anything).Return(nil).Once()
driver.CreateObject("bucket", "object", "", "", buffer) driver.CreateObject("bucket", "object", "", "", buffer)

@ -154,16 +154,14 @@ func (d donutDriver) GetObject(target io.Writer, bucketName, objectName string)
return 0, iodine.New(err, nil) return 0, iodine.New(err, nil)
} }
if _, ok := buckets[bucketName]; !ok { 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) reader, size, err := buckets[bucketName].GetObject(objectName)
if os.IsNotExist(err) { if err != nil {
return 0, drivers.ObjectNotFound{ return 0, drivers.ObjectNotFound{
Bucket: bucketName, Bucket: bucketName,
Object: objectName, Object: objectName,
} }
} else if err != nil {
return 0, iodine.New(err, errParams)
} }
n, err := io.CopyN(target, reader, size) n, err := io.CopyN(target, reader, size)
return n, iodine.New(err, errParams) 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) return 0, iodine.New(err, nil)
} }
if _, ok := buckets[bucketName]; !ok { 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) reader, size, err := buckets[bucketName].GetObject(objectName)
if os.IsNotExist(err) { if err != nil {
return 0, drivers.ObjectNotFound{ return 0, drivers.ObjectNotFound{
Bucket: bucketName, Bucket: bucketName,
Object: objectName, Object: objectName,
} }
} else if err != nil {
return 0, iodine.New(err, errParams)
} }
if start > size || (start+length-1) > size { if start > size || (start+length-1) > size {
return 0, iodine.New(errors.New("invalid range"), errParams) 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) return drivers.ObjectMetadata{}, iodine.New(err, errParams)
} }
if _, ok := buckets[bucketName]; !ok { 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() objectList, err := buckets[bucketName].ListObjects()
if err != nil { if err != nil {
return drivers.ObjectMetadata{}, iodine.New(err, errParams) return drivers.ObjectMetadata{}, iodine.New(err, errParams)
} }
donutObjectMetadata, err := objectList[objectName].GetDonutObjectMetadata() object, ok := objectList[objectName]
if os.IsNotExist(err) { if !ok {
// return ObjectNotFound quickly on an error, API needs this to handle invalid requests // return ObjectNotFound quickly on an error, API needs this to handle invalid requests
return drivers.ObjectMetadata{}, drivers.ObjectNotFound{ return drivers.ObjectMetadata{}, drivers.ObjectNotFound{
Bucket: bucketName, Bucket: bucketName,
Object: objectName, Object: objectName,
} }
} else if err != nil {
return drivers.ObjectMetadata{}, iodine.New(err, errParams)
} }
objectMetadata, err := objectList[objectName].GetObjectMetadata() donutObjectMetadata, err := object.GetDonutObjectMetadata()
if os.IsNotExist(err) { 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 ObjectNotFound quickly on an error, API needs this to handle invalid requests
return drivers.ObjectMetadata{}, drivers.ObjectNotFound{ return drivers.ObjectMetadata{}, drivers.ObjectNotFound{
Bucket: bucketName, Bucket: bucketName,
Object: objectName, Object: objectName,
} }
} else if err != nil {
return drivers.ObjectMetadata{}, iodine.New(err, errParams)
} }
created, err := time.Parse(time.RFC3339Nano, donutObjectMetadata["created"]) created, err := time.Parse(time.RFC3339Nano, donutObjectMetadata["created"])
if err != nil { if err != nil {
@ -289,7 +289,7 @@ func (d donutDriver) ListObjects(bucketName string, resources drivers.BucketReso
return nil, drivers.BucketResourcesMetadata{}, iodine.New(err, errParams) return nil, drivers.BucketResourcesMetadata{}, iodine.New(err, errParams)
} }
if _, ok := buckets[bucketName]; !ok { 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() objectList, err := buckets[bucketName].ListObjects()
if err != nil { if err != nil {
@ -360,7 +360,7 @@ func (d donutDriver) CreateObject(bucketName, objectName, contentType, expectedM
return iodine.New(err, errParams) return iodine.New(err, errParams)
} }
if _, ok := buckets[bucketName]; !ok { if _, ok := buckets[bucketName]; !ok {
return iodine.New(errors.New("bucket does not exist"), errParams) return drivers.BucketNotFound{Bucket: bucketName}
} }
if contentType == "" { if contentType == "" {
contentType = "application/octet-stream" contentType = "application/octet-stream"

@ -134,11 +134,13 @@ func (file *fileDriver) GetObjectMetadata(bucket, object, prefix string) (driver
if drivers.IsValidBucket(bucket) == false { if drivers.IsValidBucket(bucket) == false {
return drivers.ObjectMetadata{}, drivers.BucketNameInvalid{Bucket: bucket} return drivers.ObjectMetadata{}, drivers.BucketNameInvalid{Bucket: bucket}
} }
if drivers.IsValidObject(object) == false { if drivers.IsValidObject(object) == false {
return drivers.ObjectMetadata{}, drivers.ObjectNameInvalid{Bucket: bucket, Object: bucket} 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 // 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() // in a static manner so that we can send a proper 'ObjectNotFound' reply back upon os.Stat()
objectPath := file.root + "/" + bucket + "/" + object objectPath := file.root + "/" + bucket + "/" + object

@ -71,6 +71,9 @@ func start(ctrlChannel <-chan string, errorChannel chan<- error) {
// GetObject - GET object from memory buffer // GetObject - GET object from memory buffer
func (memory memoryDriver) GetObject(w io.Writer, bucket string, object string) (int64, error) { 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 // get object
key := object key := object
if val, ok := memory.objectdata[key]; ok { if val, ok := memory.objectdata[key]; ok {
@ -269,6 +272,10 @@ func (memory memoryDriver) ListBuckets() ([]drivers.BucketMetadata, error) {
// GetObjectMetadata - get object metadata from memory // GetObjectMetadata - get object metadata from memory
func (memory memoryDriver) GetObjectMetadata(bucket, key, prefix string) (drivers.ObjectMetadata, error) { 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 { if object, ok := memory.objectdata[key]; ok == true {
return object.metadata, nil return object.metadata, nil
} }

Loading…
Cancel
Save