Wrap storagedrivers to validate paths upper in the call stack
Signed-off-by: Ahmet Alp Balkan <ahmetalpbalkan@gmail.com>
This commit is contained in:
parent
03406ab708
commit
6e280b0e3e
6 changed files with 107 additions and 107 deletions
|
@ -58,7 +58,12 @@ func Create(name string, parameters map[string]interface{}) (storagedriver.Stora
|
|||
// }
|
||||
// return driverClient, nil
|
||||
}
|
||||
return driverFactory.Create(parameters)
|
||||
d, err := driverFactory.Create(parameters)
|
||||
if err == nil {
|
||||
// Wrap the storage driver for path validation
|
||||
d = storagedriver.Wrap(d)
|
||||
}
|
||||
return d, err
|
||||
}
|
||||
|
||||
// InvalidStorageDriverError records an attempt to construct an unregistered storage driver
|
||||
|
|
|
@ -56,10 +56,6 @@ func New(rootDirectory string) *Driver {
|
|||
|
||||
// GetContent retrieves the content stored at "path" as a []byte.
|
||||
func (d *Driver) GetContent(path string) ([]byte, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
rc, err := d.ReadStream(path, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -76,10 +72,6 @@ func (d *Driver) GetContent(path string) ([]byte, error) {
|
|||
|
||||
// PutContent stores the []byte content at a location designated by "path".
|
||||
func (d *Driver) PutContent(subPath string, contents []byte) error {
|
||||
if !storagedriver.PathRegexp.MatchString(subPath) {
|
||||
return storagedriver.InvalidPathError{Path: subPath}
|
||||
}
|
||||
|
||||
if _, err := d.WriteStream(subPath, 0, bytes.NewReader(contents)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -90,10 +82,6 @@ func (d *Driver) PutContent(subPath string, contents []byte) error {
|
|||
// ReadStream retrieves an io.ReadCloser for the content stored at "path" with a
|
||||
// given byte offset.
|
||||
func (d *Driver) ReadStream(path string, offset int64) (io.ReadCloser, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset}
|
||||
}
|
||||
|
@ -122,10 +110,6 @@ func (d *Driver) ReadStream(path string, offset int64) (io.ReadCloser, error) {
|
|||
// WriteStream stores the contents of the provided io.Reader at a location
|
||||
// designated by the given path.
|
||||
func (d *Driver) WriteStream(subPath string, offset int64, reader io.Reader) (nn int64, err error) {
|
||||
if !storagedriver.PathRegexp.MatchString(subPath) {
|
||||
return 0, storagedriver.InvalidPathError{Path: subPath}
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
return 0, storagedriver.InvalidOffsetError{Path: subPath, Offset: offset}
|
||||
}
|
||||
|
@ -166,10 +150,6 @@ func (d *Driver) WriteStream(subPath string, offset int64, reader io.Reader) (nn
|
|||
// Stat retrieves the FileInfo for the given path, including the current size
|
||||
// in bytes and the creation time.
|
||||
func (d *Driver) Stat(subPath string) (storagedriver.FileInfo, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(subPath) {
|
||||
return nil, storagedriver.InvalidPathError{Path: subPath}
|
||||
}
|
||||
|
||||
fullPath := d.fullPath(subPath)
|
||||
|
||||
fi, err := os.Stat(fullPath)
|
||||
|
@ -190,10 +170,6 @@ func (d *Driver) Stat(subPath string) (storagedriver.FileInfo, error) {
|
|||
// List returns a list of the objects that are direct descendants of the given
|
||||
// path.
|
||||
func (d *Driver) List(subPath string) ([]string, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(subPath) && subPath != "/" {
|
||||
return nil, storagedriver.InvalidPathError{Path: subPath}
|
||||
}
|
||||
|
||||
if subPath[len(subPath)-1] != '/' {
|
||||
subPath += "/"
|
||||
}
|
||||
|
@ -225,12 +201,6 @@ func (d *Driver) List(subPath string) ([]string, error) {
|
|||
// Move moves an object stored at sourcePath to destPath, removing the original
|
||||
// object.
|
||||
func (d *Driver) Move(sourcePath string, destPath string) error {
|
||||
if !storagedriver.PathRegexp.MatchString(sourcePath) {
|
||||
return storagedriver.InvalidPathError{Path: sourcePath}
|
||||
} else if !storagedriver.PathRegexp.MatchString(destPath) {
|
||||
return storagedriver.InvalidPathError{Path: destPath}
|
||||
}
|
||||
|
||||
source := d.fullPath(sourcePath)
|
||||
dest := d.fullPath(destPath)
|
||||
|
||||
|
@ -248,10 +218,6 @@ func (d *Driver) Move(sourcePath string, destPath string) error {
|
|||
|
||||
// Delete recursively deletes all objects stored at "path" and its subpaths.
|
||||
func (d *Driver) Delete(subPath string) error {
|
||||
if !storagedriver.PathRegexp.MatchString(subPath) {
|
||||
return storagedriver.InvalidPathError{Path: subPath}
|
||||
}
|
||||
|
||||
fullPath := d.fullPath(subPath)
|
||||
|
||||
_, err := os.Stat(fullPath)
|
||||
|
|
|
@ -46,10 +46,6 @@ func New() *Driver {
|
|||
|
||||
// GetContent retrieves the content stored at "path" as a []byte.
|
||||
func (d *Driver) GetContent(path string) ([]byte, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
d.mutex.RLock()
|
||||
defer d.mutex.RUnlock()
|
||||
|
||||
|
@ -64,10 +60,6 @@ func (d *Driver) GetContent(path string) ([]byte, error) {
|
|||
|
||||
// PutContent stores the []byte content at a location designated by "path".
|
||||
func (d *Driver) PutContent(p string, contents []byte) error {
|
||||
if !storagedriver.PathRegexp.MatchString(p) {
|
||||
return storagedriver.InvalidPathError{Path: p}
|
||||
}
|
||||
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
|
@ -87,10 +79,6 @@ func (d *Driver) PutContent(p string, contents []byte) error {
|
|||
// ReadStream retrieves an io.ReadCloser for the content stored at "path" with a
|
||||
// given byte offset.
|
||||
func (d *Driver) ReadStream(path string, offset int64) (io.ReadCloser, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
d.mutex.RLock()
|
||||
defer d.mutex.RUnlock()
|
||||
|
||||
|
@ -115,10 +103,6 @@ func (d *Driver) ReadStream(path string, offset int64) (io.ReadCloser, error) {
|
|||
// WriteStream stores the contents of the provided io.ReadCloser at a location
|
||||
// designated by the given path.
|
||||
func (d *Driver) WriteStream(path string, offset int64, reader io.Reader) (nn int64, err error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return 0, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
|
@ -160,10 +144,6 @@ func (d *Driver) WriteStream(path string, offset int64, reader io.Reader) (nn in
|
|||
|
||||
// Stat returns info about the provided path.
|
||||
func (d *Driver) Stat(path string) (storagedriver.FileInfo, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
d.mutex.RLock()
|
||||
defer d.mutex.RUnlock()
|
||||
|
||||
|
@ -190,10 +170,6 @@ func (d *Driver) Stat(path string) (storagedriver.FileInfo, error) {
|
|||
// List returns a list of the objects that are direct descendants of the given
|
||||
// path.
|
||||
func (d *Driver) List(path string) ([]string, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) && path != "/" {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
normalized := normalize(path)
|
||||
|
||||
found := d.root.find(normalized)
|
||||
|
@ -221,12 +197,6 @@ func (d *Driver) List(path string) ([]string, error) {
|
|||
// Move moves an object stored at sourcePath to destPath, removing the original
|
||||
// object.
|
||||
func (d *Driver) Move(sourcePath string, destPath string) error {
|
||||
if !storagedriver.PathRegexp.MatchString(sourcePath) {
|
||||
return storagedriver.InvalidPathError{Path: sourcePath}
|
||||
} else if !storagedriver.PathRegexp.MatchString(destPath) {
|
||||
return storagedriver.InvalidPathError{Path: destPath}
|
||||
}
|
||||
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
|
@ -243,10 +213,6 @@ func (d *Driver) Move(sourcePath string, destPath string) error {
|
|||
|
||||
// Delete recursively deletes all objects stored at "path" and its subpaths.
|
||||
func (d *Driver) Delete(path string) error {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
|
|
|
@ -196,10 +196,6 @@ func New(params DriverParameters) (*Driver, error) {
|
|||
|
||||
// GetContent retrieves the content stored at "path" as a []byte.
|
||||
func (d *Driver) GetContent(path string) ([]byte, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
content, err := d.Bucket.Get(d.s3Path(path))
|
||||
if err != nil {
|
||||
return nil, parseError(path, err)
|
||||
|
@ -209,20 +205,12 @@ func (d *Driver) GetContent(path string) ([]byte, error) {
|
|||
|
||||
// PutContent stores the []byte content at a location designated by "path".
|
||||
func (d *Driver) PutContent(path string, contents []byte) error {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return parseError(path, d.Bucket.Put(d.s3Path(path), contents, d.getContentType(), getPermissions(), d.getOptions()))
|
||||
}
|
||||
|
||||
// ReadStream retrieves an io.ReadCloser for the content stored at "path" with a
|
||||
// given byte offset.
|
||||
func (d *Driver) ReadStream(path string, offset int64) (io.ReadCloser, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
return nil, storagedriver.InvalidOffsetError{Path: path, Offset: offset}
|
||||
}
|
||||
|
@ -249,10 +237,6 @@ func (d *Driver) ReadStream(path string, offset int64) (io.ReadCloser, error) {
|
|||
// offset. Offsets past the current size will write from the position
|
||||
// beyond the end of the file.
|
||||
func (d *Driver) WriteStream(path string, offset int64, reader io.Reader) (totalRead int64, err error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return 0, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
return 0, storagedriver.InvalidOffsetError{Path: path, Offset: offset}
|
||||
}
|
||||
|
@ -510,10 +494,6 @@ func (d *Driver) WriteStream(path string, offset int64, reader io.Reader) (total
|
|||
// Stat retrieves the FileInfo for the given path, including the current size
|
||||
// in bytes and the creation time.
|
||||
func (d *Driver) Stat(path string) (storagedriver.FileInfo, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
listResponse, err := d.Bucket.List(d.s3Path(path), "", "", 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -547,10 +527,6 @@ func (d *Driver) Stat(path string) (storagedriver.FileInfo, error) {
|
|||
|
||||
// List returns a list of the objects that are direct descendants of the given path.
|
||||
func (d *Driver) List(path string) ([]string, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) && path != "/" {
|
||||
return nil, storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
if path != "/" && path[len(path)-1] != '/' {
|
||||
path = path + "/"
|
||||
}
|
||||
|
@ -587,12 +563,6 @@ func (d *Driver) List(path string) ([]string, error) {
|
|||
// Move moves an object stored at sourcePath to destPath, removing the original
|
||||
// object.
|
||||
func (d *Driver) Move(sourcePath string, destPath string) error {
|
||||
if !storagedriver.PathRegexp.MatchString(sourcePath) {
|
||||
return storagedriver.InvalidPathError{Path: sourcePath}
|
||||
} else if !storagedriver.PathRegexp.MatchString(destPath) {
|
||||
return storagedriver.InvalidPathError{Path: destPath}
|
||||
}
|
||||
|
||||
/* This is terrible, but aws doesn't have an actual move. */
|
||||
_, err := d.Bucket.PutCopy(d.s3Path(destPath), getPermissions(),
|
||||
s3.CopyOptions{Options: d.getOptions(), ContentType: d.getContentType()}, d.Bucket.Name+"/"+d.s3Path(sourcePath))
|
||||
|
@ -605,10 +575,6 @@ func (d *Driver) Move(sourcePath string, destPath string) error {
|
|||
|
||||
// Delete recursively deletes all objects stored at "path" and its subpaths.
|
||||
func (d *Driver) Delete(path string) error {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
listResponse, err := d.Bucket.List(d.s3Path(path), "", "", listMax)
|
||||
if err != nil || len(listResponse.Contents) == 0 {
|
||||
return storagedriver.PathNotFoundError{Path: path}
|
||||
|
@ -638,10 +604,6 @@ func (d *Driver) Delete(path string) error {
|
|||
// URLFor returns a URL which may be used to retrieve the content stored at the given path.
|
||||
// May return an UnsupportedMethodErr in certain StorageDriver implementations.
|
||||
func (d *Driver) URLFor(path string, options map[string]interface{}) (string, error) {
|
||||
if !storagedriver.PathRegexp.MatchString(path) {
|
||||
return "", storagedriver.InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
methodString := "GET"
|
||||
method, ok := options["method"]
|
||||
if ok {
|
||||
|
|
|
@ -98,6 +98,7 @@ func (suite *DriverSuite) SetUpSuite(c *check.C) {
|
|||
}
|
||||
d, err := suite.Constructor()
|
||||
c.Assert(err, check.IsNil)
|
||||
d = storagedriver.Wrap(d)
|
||||
suite.StorageDriver = d
|
||||
}
|
||||
|
||||
|
|
100
storagedriver/wrapper.go
Normal file
100
storagedriver/wrapper.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
package storagedriver
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// wrapper wraps the underlying StorageDriver with common operations like
|
||||
// path checks for each method.
|
||||
type wrapper struct {
|
||||
driver StorageDriver
|
||||
}
|
||||
|
||||
// Wrap creates a wrapper for given storage driver to apply common operations
|
||||
// on each StorageDriver interface methods.
|
||||
func Wrap(d StorageDriver) StorageDriver {
|
||||
return wrapper{driver: d}
|
||||
}
|
||||
|
||||
// GetContent wraps GetContent of underlying storage driver.
|
||||
func (d wrapper) GetContent(path string) ([]byte, error) {
|
||||
if !PathRegexp.MatchString(path) {
|
||||
return nil, InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return d.driver.GetContent(path)
|
||||
}
|
||||
|
||||
// PutContent wraps PutContent of underlying storage driver.
|
||||
func (d wrapper) PutContent(path string, content []byte) error {
|
||||
if !PathRegexp.MatchString(path) {
|
||||
return InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return d.driver.PutContent(path, content)
|
||||
}
|
||||
|
||||
// ReadStream wraps ReadStream of underlying storage driver.
|
||||
func (d wrapper) ReadStream(path string, offset int64) (io.ReadCloser, error) {
|
||||
if !PathRegexp.MatchString(path) {
|
||||
return nil, InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return d.driver.ReadStream(path, offset)
|
||||
}
|
||||
|
||||
// WriteStream wraps WriteStream of underlying storage driver.
|
||||
func (d wrapper) WriteStream(path string, offset int64, reader io.Reader) (nn int64, err error) {
|
||||
if !PathRegexp.MatchString(path) {
|
||||
return 0, InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return d.driver.WriteStream(path, offset, reader)
|
||||
}
|
||||
|
||||
// Stat wraps Stat of underlying storage driver.
|
||||
func (d wrapper) Stat(path string) (FileInfo, error) {
|
||||
if !PathRegexp.MatchString(path) {
|
||||
return nil, InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return d.driver.Stat(path)
|
||||
}
|
||||
|
||||
// List wraps List of underlying storage driver.
|
||||
func (d wrapper) List(path string) ([]string, error) {
|
||||
if !PathRegexp.MatchString(path) && path != "/" {
|
||||
return nil, InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return d.driver.List(path)
|
||||
}
|
||||
|
||||
// Move wraps Move of underlying storage driver.
|
||||
func (d wrapper) Move(sourcePath string, destPath string) error {
|
||||
if !PathRegexp.MatchString(sourcePath) {
|
||||
return InvalidPathError{Path: sourcePath}
|
||||
} else if !PathRegexp.MatchString(destPath) {
|
||||
return InvalidPathError{Path: destPath}
|
||||
}
|
||||
|
||||
return d.driver.Move(sourcePath, destPath)
|
||||
}
|
||||
|
||||
// Delete wraps Delete of underlying storage driver.
|
||||
func (d wrapper) Delete(path string) error {
|
||||
if !PathRegexp.MatchString(path) {
|
||||
return InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return d.driver.Delete(path)
|
||||
}
|
||||
|
||||
// URLFor wraps URLFor of underlying storage driver.
|
||||
func (d wrapper) URLFor(path string, options map[string]interface{}) (string, error) {
|
||||
if !PathRegexp.MatchString(path) {
|
||||
return "", InvalidPathError{Path: path}
|
||||
}
|
||||
|
||||
return d.driver.URLFor(path, options)
|
||||
}
|
Loading…
Reference in a new issue