From 0eb599329a15422797f1926853d9303ff53837ed Mon Sep 17 00:00:00 2001 From: Josh Hawn Date: Mon, 6 Apr 2015 16:23:31 -0700 Subject: [PATCH] Handle cloudFront bucket prefix issue Docker-DCO-1.1-Signed-off-by: Josh Hawn (github: jlhawn) --- .../middleware/cloudfront/middleware.go | 24 +++++++++---------- registry/storage/driver/s3/s3.go | 5 ++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/registry/storage/driver/middleware/cloudfront/middleware.go b/registry/storage/driver/middleware/cloudfront/middleware.go index 2d1553122..aee068a5e 100644 --- a/registry/storage/driver/middleware/cloudfront/middleware.go +++ b/registry/storage/driver/middleware/cloudfront/middleware.go @@ -8,10 +8,10 @@ import ( "encoding/pem" "fmt" "io/ioutil" - "net/url" "time" "github.com/AdRoll/goamz/cloudfront" + "github.com/docker/distribution/context" storagedriver "github.com/docker/distribution/registry/storage/driver" storagemiddleware "github.com/docker/distribution/registry/storage/driver/middleware" ) @@ -90,23 +90,23 @@ func newCloudFrontStorageMiddleware(storageDriver storagedriver.StorageDriver, o return &cloudFrontStorageMiddleware{StorageDriver: storageDriver, cloudfront: cf, duration: duration}, nil } +// S3BucketKeyer is any type that is capable of returning the S3 bucket key +// which should be cached by AWS CloudFront. +type S3BucketKeyer interface { + S3BucketKey(path string) string +} + // Resolve returns an http.Handler which can serve the contents of the given // Layer, or an error if not supported by the storagedriver. func (lh *cloudFrontStorageMiddleware) URLFor(path string, options map[string]interface{}) (string, error) { // TODO(endophage): currently only supports S3 - options["expiry"] = time.Now().Add(lh.duration) - - layerURLStr, err := lh.StorageDriver.URLFor(path, options) - if err != nil { - return "", err + keyer, ok := lh.StorageDriver.(S3BucketKeyer) + if !ok { + context.GetLogger(context.Background()).Warn("the CloudFront middleware does not support this backend storage driver") + return lh.StorageDriver.URLFor(path, options) } - layerURL, err := url.Parse(layerURLStr) - if err != nil { - return "", err - } - - cfURL, err := lh.cloudfront.CannedSignedURL(layerURL.Path, "", time.Now().Add(lh.duration)) + cfURL, err := lh.cloudfront.CannedSignedURL(keyer.S3BucketKey(path), "", time.Now().Add(lh.duration)) if err != nil { return "", err } diff --git a/registry/storage/driver/s3/s3.go b/registry/storage/driver/s3/s3.go index d240c9018..402f2eaac 100644 --- a/registry/storage/driver/s3/s3.go +++ b/registry/storage/driver/s3/s3.go @@ -695,6 +695,11 @@ func (d *driver) s3Path(path string) string { return strings.TrimLeft(strings.TrimRight(d.RootDirectory, "/")+path, "/") } +// S3BucketKey returns the s3 bucket key for the given storage driver path. +func (d *Driver) S3BucketKey(path string) string { + return d.StorageDriver.(*driver).s3Path(path) +} + func parseError(path string, err error) error { if s3Err, ok := err.(*s3.Error); ok && s3Err.Code == "NoSuchKey" { return storagedriver.PathNotFoundError{Path: path}