diff --git a/backend/posix/posix.go b/backend/posix/posix.go index cebfa45..ae2a715 100644 --- a/backend/posix/posix.go +++ b/backend/posix/posix.go @@ -223,6 +223,12 @@ func (p *Posix) CreateMultipartUpload(_ context.Context, mpu *s3.CreateMultipart return nil, fmt.Errorf("stat bucket: %w", err) } + if strings.HasSuffix(*mpu.Key, "/") { + // directory objects can't be uploaded with mutlipart uploads + // because posix directories can't contain data + return nil, s3err.GetAPIError(s3err.ErrDirectoryObjectContainsData) + } + // generate random uuid for upload id uploadID := uuid.New().String() // hash object name for multipart container @@ -960,6 +966,13 @@ func (p *Posix) PutObject(ctx context.Context, po *s3.PutObjectInput) (string, e if strings.HasSuffix(*po.Key, "/") { // object is directory + if po.ContentLength != 0 { + // posix directories can't contain data, send error + // if reuests has a data payload associated with a + // directory object + return "", s3err.GetAPIError(s3err.ErrDirectoryObjectContainsData) + } + err = mkdirAll(name, os.FileMode(0755), *po.Bucket, *po.Key) if err != nil { return "", err diff --git a/s3err/s3err.go b/s3err/s3err.go index 82e791f..838ee0f 100644 --- a/s3err/s3err.go +++ b/s3err/s3err.go @@ -115,6 +115,7 @@ const ( // Non-AWS errors ErrExistingObjectIsDirectory ErrObjectParentIsFile + ErrDirectoryObjectContainsData ) var errorCodeResponse = map[ErrorCode]APIError{ @@ -408,6 +409,11 @@ var errorCodeResponse = map[ErrorCode]APIError{ Description: "Object parent already exists as a file.", HTTPStatusCode: http.StatusConflict, }, + ErrDirectoryObjectContainsData: { + Code: "DirectoryObjectContainsData", + Description: "Directory object contains data payload.", + HTTPStatusCode: http.StatusBadRequest, + }, } // GetAPIError provides API Error for input API error code.