Protect against deletion of objects with the same prefix

Signed-off-by: Sylvain Baubeau <sbaubeau@redhat.com>
This commit is contained in:
Sylvain Baubeau 2015-07-02 10:59:14 +02:00
parent 01686e2c07
commit 91d74a3ee2

View file

@ -447,32 +447,36 @@ func (d *driver) Move(ctx context.Context, sourcePath string, destPath string) e
// Delete recursively deletes all objects stored at "path" and its subpaths. // Delete recursively deletes all objects stored at "path" and its subpaths.
func (d *driver) Delete(ctx context.Context, path string) error { func (d *driver) Delete(ctx context.Context, path string) error {
opts := swift.ObjectsOpts{ opts := swift.ObjectsOpts{
Prefix: d.swiftPath(path), Prefix: d.swiftPath(path) + "/",
} }
objects, err := d.Conn.ObjectNamesAll(d.Container, &opts) objects, err := d.Conn.Objects(d.Container, &opts)
if err != nil { if err != nil {
return parseError(path, err) return parseError(path, err)
} }
if len(objects) == 0 {
return storagedriver.PathNotFoundError{Path: path}
}
if d.BulkDeleteSupport { if d.BulkDeleteSupport {
if _, err := d.Conn.BulkDelete(d.Container, objects); err != swift.Forbidden { filenames := make([]string, len(objects))
for i, obj := range objects {
filenames[i] = obj.Name
}
if _, err := d.Conn.BulkDelete(d.Container, filenames); err != swift.Forbidden {
return parseError(path, err) return parseError(path, err)
} }
} }
for _, name := range objects { for _, obj := range objects {
if _, headers, err := d.Conn.Object(d.Container, name); err == nil { if obj.PseudoDirectory {
continue
}
if _, headers, err := d.Conn.Object(d.Container, obj.Name); err == nil {
manifest, ok := headers["X-Object-Manifest"] manifest, ok := headers["X-Object-Manifest"]
if ok { if ok {
components := strings.SplitN(manifest, "/", 2) components := strings.SplitN(manifest, "/", 2)
segContainer := components[0] segContainer := components[0]
segments, err := d.getAllSegments(components[1]) segments, err := d.getAllSegments(components[1])
if err != nil { if err != nil {
return parseError(name, err) return parseError(obj.Name, err)
} }
for _, s := range segments { for _, s := range segments {
@ -482,14 +486,20 @@ func (d *driver) Delete(ctx context.Context, path string) error {
} }
} }
} else { } else {
return parseError(name, err) return parseError(obj.Name, err)
} }
if err := d.Conn.ObjectDelete(d.Container, name); err != nil { if err := d.Conn.ObjectDelete(d.Container, obj.Name); err != nil {
return parseError(name, err) return parseError(obj.Name, err)
} }
} }
if _, err := d.Stat(ctx, path); err == nil {
return parseError(path, d.Conn.ObjectDelete(d.Container, d.swiftPath(path)))
} else if len(objects) == 0 {
return storagedriver.PathNotFoundError{Path: path}
}
return nil return nil
} }