forked from TrueCloudLab/distribution
Add the URLFor optional method to the storagedriver api
We now also have a storagedriver error variable for identifying api calls that are not implemented by drivers (the URLFor method is not implemented by either the filesystem or inmemory drivers)
This commit is contained in:
parent
fadd5dfcfb
commit
a2b294f444
5 changed files with 57 additions and 0 deletions
|
@ -265,6 +265,12 @@ func (d *Driver) Delete(subPath string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) (string, error) {
|
||||||
|
return "", storagedriver.ErrUnsupportedMethod
|
||||||
|
}
|
||||||
|
|
||||||
// fullPath returns the absolute path of a key within the Driver's storage.
|
// fullPath returns the absolute path of a key within the Driver's storage.
|
||||||
func (d *Driver) fullPath(subPath string) string {
|
func (d *Driver) fullPath(subPath string) string {
|
||||||
return path.Join(d.rootDirectory, subPath)
|
return path.Join(d.rootDirectory, subPath)
|
||||||
|
|
|
@ -251,3 +251,9 @@ func (d *Driver) Delete(path string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) (string, error) {
|
||||||
|
return "", storagedriver.ErrUnsupportedMethod
|
||||||
|
}
|
||||||
|
|
|
@ -580,6 +580,16 @@ func (d *Driver) Delete(path string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) (string, error) {
|
||||||
|
if !storagedriver.PathRegexp.MatchString(path) {
|
||||||
|
return "", storagedriver.InvalidPathError{Path: path}
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.Bucket.SignedURL(d.s3Path(path), time.Now().Add(24*time.Hour)), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Driver) s3Path(path string) string {
|
func (d *Driver) s3Path(path string) string {
|
||||||
return strings.TrimLeft(strings.TrimRight(d.rootDirectory, "/")+path, "/")
|
return strings.TrimLeft(strings.TrimRight(d.rootDirectory, "/")+path, "/")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package storagedriver
|
package storagedriver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -69,6 +70,10 @@ type StorageDriver interface {
|
||||||
|
|
||||||
// Delete recursively deletes all objects stored at "path" and its subpaths.
|
// Delete recursively deletes all objects stored at "path" and its subpaths.
|
||||||
Delete(path string) error
|
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.
|
||||||
|
URLFor(path string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PathRegexp is the regular expression which each file path must match.
|
// PathRegexp is the regular expression which each file path must match.
|
||||||
|
@ -78,6 +83,9 @@ type StorageDriver interface {
|
||||||
// a period, underscore, or hyphen.
|
// a period, underscore, or hyphen.
|
||||||
var PathRegexp = regexp.MustCompile(`^(/[a-z0-9]+([._-][a-z0-9]+)*)+$`)
|
var PathRegexp = regexp.MustCompile(`^(/[a-z0-9]+([._-][a-z0-9]+)*)+$`)
|
||||||
|
|
||||||
|
// UnsupportedMethodErr may be returned in the case where a StorageDriver implementation does not support an optional method.
|
||||||
|
var ErrUnsupportedMethod = errors.New("Unsupported method")
|
||||||
|
|
||||||
// PathNotFoundError is returned when operating on a nonexistent path.
|
// PathNotFoundError is returned when operating on a nonexistent path.
|
||||||
type PathNotFoundError struct {
|
type PathNotFoundError struct {
|
||||||
Path string
|
Path string
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -580,6 +581,32 @@ func (suite *DriverSuite) TestDelete(c *check.C) {
|
||||||
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
c.Assert(err, check.FitsTypeOf, storagedriver.PathNotFoundError{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestURLFor checks that the URLFor method functions properly, but only if it
|
||||||
|
// is implemented
|
||||||
|
func (suite *DriverSuite) TestURLFor(c *check.C) {
|
||||||
|
filename := randomPath(32)
|
||||||
|
contents := randomContents(32)
|
||||||
|
|
||||||
|
defer suite.StorageDriver.Delete(firstPart(filename))
|
||||||
|
|
||||||
|
err := suite.StorageDriver.PutContent(filename, contents)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
url, err := suite.StorageDriver.URLFor(filename)
|
||||||
|
if err == storagedriver.ErrUnsupportedMethod {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
response, err := http.Get(url)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
defer response.Body.Close()
|
||||||
|
|
||||||
|
read, err := ioutil.ReadAll(response.Body)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
c.Assert(read, check.DeepEquals, contents)
|
||||||
|
}
|
||||||
|
|
||||||
// TestDeleteNonexistent checks that removing a nonexistent key fails.
|
// TestDeleteNonexistent checks that removing a nonexistent key fails.
|
||||||
func (suite *DriverSuite) TestDeleteNonexistent(c *check.C) {
|
func (suite *DriverSuite) TestDeleteNonexistent(c *check.C) {
|
||||||
filename := randomPath(32)
|
filename := randomPath(32)
|
||||||
|
|
Loading…
Reference in a new issue