xl,fs: Return 404 if object ends with a separator (#3897)

HEAD Object for FS and XL was returning invalid object name when
an object name has a trailing slash separator, this PR changes the
behavior and will always return 404 object not found, this guarantees
a better compatibility with S3 spec.
This commit is contained in:
Anis Elleuch 2017-03-14 06:20:46 +01:00 committed by Harshavardhana
parent 5f7565762e
commit a5e60706a2
3 changed files with 33 additions and 37 deletions

View File

@ -470,6 +470,12 @@ func (fs fsObjects) getObjectInfo(bucket, object string) (ObjectInfo, error) {
// GetObjectInfo - reads object metadata and replies back ObjectInfo.
func (fs fsObjects) GetObjectInfo(bucket, object string) (ObjectInfo, error) {
// This is a special case with object whose name ends with
// a slash separator, we always return object not found here.
if hasSuffix(object, slashSeparator) {
return ObjectInfo{}, toObjectErr(traceError(errFileNotFound), bucket, object)
}
if err := checkGetObjArgs(bucket, object); err != nil {
return ObjectInfo{}, err
}

View File

@ -735,12 +735,13 @@ func (s *ObjectLayerAPISuite) TestGetDirectoryReturnsObjectNotFound(c *C) {
// Tests validate that GetObject on an existing directory fails as expected.
func testGetDirectoryReturnsObjectNotFound(obj ObjectLayer, instanceType string, c TestErrHandler) {
err := obj.MakeBucket("bucket")
bucketName := "bucket"
err := obj.MakeBucket(bucketName)
if err != nil {
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
_, err = obj.PutObject("bucket", "dir1/dir3/object",
_, err = obj.PutObject(bucketName, "dir1/dir3/object",
int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")),
bytes.NewBufferString("One or more of the specified parts could not be found. The part might not have been uploaded, or the specified entity tag might not have matched the part's entity tag."), nil, "")
@ -748,42 +749,25 @@ func testGetDirectoryReturnsObjectNotFound(obj ObjectLayer, instanceType string,
c.Fatalf("%s: <ERROR> %s", instanceType, err)
}
_, err = obj.GetObjectInfo("bucket", "dir1")
for i, objName := range []string{"dir1", "dir1/", "dir1/dir3", "dir1/dir3/"} {
_, err = obj.GetObjectInfo(bucketName, objName)
if isErrObjectNotFound(err) {
err = errorCause(err)
err1 := err.(ObjectNotFound)
if err1.Bucket != "bucket" {
c.Errorf("%s: Expected the bucket name in the error message to be `%s`, but instead found `%s`",
instanceType, "bucket", err1.Bucket)
if err1.Bucket != bucketName {
c.Errorf("Test %d, %s: Expected the bucket name in the error message to be `%s`, but instead found `%s`",
i+1, instanceType, bucketName, err1.Bucket)
}
if err1.Object != "dir1" {
c.Errorf("%s: Expected the object name in the error message to be `%s`, but instead found `%s`",
instanceType, "dir1", err1.Object)
if err1.Object != objName {
c.Errorf("Test %d, %s: Expected the object name in the error message to be `%s`, but instead found `%s`",
i+1, instanceType, objName, err1.Object)
}
} else {
if err.Error() != "ObjectNotFound" {
c.Errorf("%s: Expected the error message to be `%s`, but instead found `%s`", instanceType,
c.Errorf("Test %d, %s: Expected the error message to be `%s`, but instead found `%s`", i+1, instanceType,
"ObjectNotFound", err.Error())
}
}
_, err = obj.GetObjectInfo("bucket", "dir1/")
if isErrObjectNameInvalid(err) {
err = errorCause(err)
err1 := err.(ObjectNameInvalid)
if err1.Bucket != "bucket" {
c.Errorf("%s: Expected the bucket name in the error message to be `%s`, but instead found `%s`",
instanceType, "bucket", err1.Bucket)
}
if err1.Object != "dir1/" {
c.Errorf("%s: Expected the object name in the error message to be `%s`, but instead found `%s`",
instanceType, "dir1/", err1.Object)
}
} else {
// force a failure with a line number.
if err.Error() != "ObjectNotFound" {
c.Errorf("%s: Expected the error message to be `%s`, but instead found `%s`", instanceType, "ObjectNotFound", err.Error())
}
}
}

View File

@ -321,6 +321,12 @@ func (xl xlObjects) GetObject(bucket, object string, startOffset int64, length i
// GetObjectInfo - reads object metadata and replies back ObjectInfo.
func (xl xlObjects) GetObjectInfo(bucket, object string) (ObjectInfo, error) {
// This is a special case with object whose name ends with
// a slash separator, we always return object not found here.
if hasSuffix(object, slashSeparator) {
return ObjectInfo{}, toObjectErr(traceError(errFileNotFound), bucket, object)
}
if err := checkGetObjArgs(bucket, object); err != nil {
return ObjectInfo{}, err
}