Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2849 from Shawnpku/master
support Alibaba Cloud CDN storage middleware
- Loading branch information
Showing
9 changed files
with
385 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
registry/storage/driver/middleware/alicdn/middleware.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package alicdn | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/url" | ||
"strings" | ||
"time" | ||
|
||
dcontext "github.com/docker/distribution/context" | ||
storagedriver "github.com/docker/distribution/registry/storage/driver" | ||
storagemiddleware "github.com/docker/distribution/registry/storage/driver/middleware" | ||
|
||
"github.com/denverdino/aliyungo/cdn/auth" | ||
) | ||
|
||
// aliCDNStorageMiddleware provides a simple implementation of layerHandler that | ||
// constructs temporary signed AliCDN URLs from the storagedriver layer URL, | ||
// then issues HTTP Temporary Redirects to this AliCDN content URL. | ||
type aliCDNStorageMiddleware struct { | ||
storagedriver.StorageDriver | ||
baseURL string | ||
urlSigner *auth.URLSigner | ||
duration time.Duration | ||
} | ||
|
||
var _ storagedriver.StorageDriver = &aliCDNStorageMiddleware{} | ||
|
||
// newAliCDNStorageMiddleware constructs and returns a new AliCDN | ||
// StorageDriver implementation. | ||
// Required options: baseurl, authtype, privatekey | ||
// Optional options: duration | ||
func newAliCDNStorageMiddleware(storageDriver storagedriver.StorageDriver, options map[string]interface{}) (storagedriver.StorageDriver, error) { | ||
// parse baseurl | ||
base, ok := options["baseurl"] | ||
if !ok { | ||
return nil, fmt.Errorf("no baseurl provided") | ||
} | ||
baseURL, ok := base.(string) | ||
if !ok { | ||
return nil, fmt.Errorf("baseurl must be a string") | ||
} | ||
if !strings.Contains(baseURL, "://") { | ||
baseURL = "https://" + baseURL | ||
} | ||
if _, err := url.Parse(baseURL); err != nil { | ||
return nil, fmt.Errorf("invalid baseurl: %v", err) | ||
} | ||
|
||
// parse authtype | ||
at, ok := options["authtype"] | ||
if !ok { | ||
return nil, fmt.Errorf("no authtype provided") | ||
} | ||
authType, ok := at.(string) | ||
if !ok { | ||
return nil, fmt.Errorf("authtype must be a string") | ||
} | ||
if authType != "a" && authType != "b" && authType != "c" { | ||
return nil, fmt.Errorf("invalid authentication type") | ||
} | ||
|
||
// parse privatekey | ||
pk, ok := options["privatekey"] | ||
if !ok { | ||
return nil, fmt.Errorf("no privatekey provided") | ||
} | ||
privateKey, ok := pk.(string) | ||
if !ok { | ||
return nil, fmt.Errorf("privatekey must be a string") | ||
} | ||
|
||
urlSigner := auth.NewURLSigner(authType, privateKey) | ||
|
||
// parse duration | ||
duration := 20 * time.Minute | ||
d, ok := options["duration"] | ||
if ok { | ||
switch d := d.(type) { | ||
case time.Duration: | ||
duration = d | ||
case string: | ||
dur, err := time.ParseDuration(d) | ||
if err != nil { | ||
return nil, fmt.Errorf("invalid duration: %s", err) | ||
} | ||
duration = dur | ||
} | ||
} | ||
|
||
return &aliCDNStorageMiddleware{ | ||
StorageDriver: storageDriver, | ||
baseURL: baseURL, | ||
urlSigner: urlSigner, | ||
duration: duration, | ||
}, nil | ||
} | ||
|
||
// URLFor attempts to find a url which may be used to retrieve the file at the given path. | ||
func (ac *aliCDNStorageMiddleware) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) { | ||
|
||
if ac.StorageDriver.Name() != "oss" { | ||
dcontext.GetLogger(ctx).Warn("the AliCDN middleware does not support this backend storage driver") | ||
return ac.StorageDriver.URLFor(ctx, path, options) | ||
} | ||
acURL, err := ac.urlSigner.Sign(ac.baseURL+path, time.Now().Add(ac.duration)) | ||
if err != nil { | ||
return "", err | ||
} | ||
return acURL, nil | ||
} | ||
|
||
// init registers the alicdn layerHandler backend. | ||
func init() { | ||
storagemiddleware.Register("alicdn", storagemiddleware.InitFunc(newAliCDNStorageMiddleware)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
vendor/github.com/denverdino/aliyungo/cdn/auth/random_uuid.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
80 changes: 80 additions & 0 deletions
80
vendor/github.com/denverdino/aliyungo/cdn/auth/sign_url.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.