Skip to content

Commit

Permalink
Add --manifest-cache-duration
Browse files Browse the repository at this point in the history
  • Loading branch information
wzshiming committed Sep 10, 2024
1 parent 8407b58 commit 8848dac
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
8 changes: 8 additions & 0 deletions cmd/crproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ var (
readmeURL string

allowHeadMethod bool

manifestCacheDuration time.Duration
)

func init() {
Expand Down Expand Up @@ -117,6 +119,8 @@ func init() {

pflag.StringVar(&readmeURL, "readme-url", "", "redirect readme url when not found")
pflag.BoolVar(&allowHeadMethod, "allow-head-method", false, "allow head method")

pflag.DurationVar(&manifestCacheDuration, "manifest-cache-duration", 0, "manifest cache duration")
pflag.Parse()
}

Expand Down Expand Up @@ -447,6 +451,10 @@ func main() {
opts = append(opts, crproxy.WithAllowHeadMethod(allowHeadMethod))
}

if manifestCacheDuration != 0 {
opts = append(opts, crproxy.WithManifestCacheDuration(manifestCacheDuration))
}

crp, err := crproxy.NewCRProxy(opts...)
if err != nil {
logger.Println("failed to NewCRProxy:", err)
Expand Down
9 changes: 9 additions & 0 deletions crproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,19 @@ type CRProxy struct {
privilegedFunc func(r *http.Request, info *ImageInfo) bool
redirectToOriginBlobFunc func(r *http.Request, info *ImageInfo) bool
allowHeadMethod bool

manifestCache maps.SyncMap[string, time.Time]
manifestCacheDuration time.Duration
}

type Option func(c *CRProxy)

func WithManifestCacheDuration(d time.Duration) Option {
return func(c *CRProxy) {
c.manifestCacheDuration = d
}
}

func WithPrivilegedFunc(f func(r *http.Request, info *ImageInfo) bool) Option {
return func(c *CRProxy) {
c.privilegedFunc = f
Expand Down
31 changes: 27 additions & 4 deletions crproxy_manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"path"
"strconv"
"strings"
"time"

"github.com/distribution/distribution/v3/registry/api/errcode"
)
Expand All @@ -25,10 +26,14 @@ func manifestTagCachePath(host, image, tagOrBlob string) string {
}

func (c *CRProxy) cacheManifestResponse(rw http.ResponseWriter, r *http.Request, info *PathInfo) {
if c.cachedManifest(rw, r, info, true) {
return
}

cli := c.getClientset(info.Host, info.Image)
resp, err := c.doWithAuth(cli, r, info.Host)
if err != nil {
if c.cachedManifest(rw, r, info) {
if c.cachedManifest(rw, r, info, false) {
return
}
if c.logger != nil {
Expand All @@ -43,15 +48,15 @@ func (c *CRProxy) cacheManifestResponse(rw http.ResponseWriter, r *http.Request,

switch resp.StatusCode {
case http.StatusUnauthorized, http.StatusForbidden:
if c.cachedManifest(rw, r, info) {
if c.cachedManifest(rw, r, info, false) {
return
}
errcode.ServeJSON(rw, errcode.ErrorCodeDenied)
return
}

if resp.StatusCode >= http.StatusInternalServerError {
if c.cachedManifest(rw, r, info) {
if c.cachedManifest(rw, r, info, false) {
return
}
}
Expand Down Expand Up @@ -112,10 +117,17 @@ func (c *CRProxy) cacheManifestContent(ctx context.Context, info *PathInfo, cont
return err
}

if c.manifestCacheDuration > 0 {
c.manifestCache.Store(manifestLinkPath, time.Now())
}
return nil
}

func (c *CRProxy) cachedManifest(rw http.ResponseWriter, r *http.Request, info *PathInfo) bool {
func (c *CRProxy) cachedManifest(rw http.ResponseWriter, r *http.Request, info *PathInfo, try bool) bool {
if try && c.manifestCacheDuration == 0 {
return false
}

ctx := r.Context()
var manifestLinkPath string
if strings.HasPrefix(info.Manifests, "sha256:") {
Expand All @@ -124,6 +136,17 @@ func (c *CRProxy) cachedManifest(rw http.ResponseWriter, r *http.Request, info *
manifestLinkPath = manifestTagCachePath(info.Host, info.Image, info.Manifests)
}

if try {
last, ok := c.manifestCache.Load(manifestLinkPath)
if !ok {
return false
}

if time.Since(last) > c.manifestCacheDuration {
return false
}
}

content, err := c.storageDriver.GetContent(ctx, manifestLinkPath)
if err == nil {
digest := string(content)
Expand Down

0 comments on commit 8848dac

Please sign in to comment.