From 18338eb0d78c9ffbadd2d803b4e0b349b31b1e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A0Ilya=20Atamas?= Date: Tue, 23 Apr 2019 15:36:51 +0300 Subject: [PATCH] feat: add tarballs caching --- cli/list.go | 4 ++-- cli/purge.go | 4 ++-- proxy/cache.go | 23 ++++++++++++----------- proxy/server.go | 24 +++++++++++++++--------- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/cli/list.go b/cli/list.go index 17e765d..d147a3c 100644 --- a/cli/list.go +++ b/cli/list.go @@ -10,7 +10,7 @@ import ( // start a server var listCmd = &cobra.Command{ Use: "list", - Short: "List all cached packages", + Short: "List all cached paths", Run: func(cmd *cobra.Command, args []string) { proxy := getProxy(func() (npmproxy.Options, error) { return npmproxy.Options{ @@ -18,7 +18,7 @@ var listCmd = &cobra.Command{ }, nil }) - metadatas, err := proxy.ListMetadata() + metadatas, err := proxy.ListCachedPaths() if err != nil { panic(err) } diff --git a/cli/purge.go b/cli/purge.go index 9f52f80..f24bfd8 100644 --- a/cli/purge.go +++ b/cli/purge.go @@ -8,7 +8,7 @@ import ( // start a server var purgeCmd = &cobra.Command{ Use: "purge", - Short: "Purge all cached packages", + Short: "Purge all cached paths", Run: func(cmd *cobra.Command, args []string) { proxy := getProxy(func() (npmproxy.Options, error) { return npmproxy.Options{ @@ -16,7 +16,7 @@ var purgeCmd = &cobra.Command{ }, nil }) - err := proxy.PurgeMetadata() + err := proxy.PurgeCachedPaths() if err != nil { panic(err) } diff --git a/proxy/cache.go b/proxy/cache.go index 1848e90..e56de0f 100644 --- a/proxy/cache.go +++ b/proxy/cache.go @@ -5,17 +5,18 @@ import ( "io/ioutil" "log" "net/http" + "regexp" "strings" ) -// GetMetadata returns cached NPM response for a given package path. -func (proxy Proxy) GetMetadata(name string, originalPath string, request *http.Request) ([]byte, error) { +// GetCachedPath returns cached upstream response for a given url path. +func (proxy Proxy) GetCachedPath(path string, request *http.Request) ([]byte, error) { options, err := proxy.GetOptions() if err != nil { return nil, err } - key := options.DatabasePrefix + name + key := options.DatabasePrefix + path // get package from database pkg, err := proxy.Database.Get(key) @@ -31,7 +32,7 @@ func (proxy Proxy) GetMetadata(name string, originalPath string, request *http.R // error is caused by nonexistent package // fetch package - req, err := http.NewRequest("GET", options.UpstreamAddress+originalPath, nil) + req, err := http.NewRequest("GET", options.UpstreamAddress+path, nil) req.Header = request.Header req.Header.Set("Accept-Encoding", "gzip") @@ -66,15 +67,15 @@ func (proxy Proxy) GetMetadata(name string, originalPath string, request *http.R } } - // replace tarball urls - // FIXME: unmarshall and replace only necessary fields - // convertedPkg := strings.ReplaceAll(string(pkg), options.ReplaceAddress, options.StaticServerAddress) + // TODO: avoid calling MustCompile every time + // find "dist": "https?://.*/ and replace to "dist": "{localurl}/ + pkg = regexp.MustCompile(`(?U)"tarball":"https?://.*/`).ReplaceAllString(pkg, `"dist": "http://localhost:8080/`) return []byte(pkg), nil } -// ListMetadata returns list of all cached packages -func (proxy Proxy) ListMetadata() ([]string, error) { +// ListCachedPaths returns list of all cached url paths. +func (proxy Proxy) ListCachedPaths() ([]string, error) { options, err := proxy.GetOptions() if err != nil { return nil, err @@ -93,8 +94,8 @@ func (proxy Proxy) ListMetadata() ([]string, error) { return deprefixedMetadata, nil } -// PurgeMetadata deletes all cached packages. -func (proxy Proxy) PurgeMetadata() error { +// PurgeCachedPaths deletes all cached url paths. +func (proxy Proxy) PurgeCachedPaths() error { options, err := proxy.GetOptions() if err != nil { return err diff --git a/proxy/server.go b/proxy/server.go index fc917c3..2f98b67 100644 --- a/proxy/server.go +++ b/proxy/server.go @@ -2,6 +2,7 @@ package proxy import ( "net/http" + "strings" "time" ginzap "github.com/gin-contrib/zap" @@ -32,14 +33,7 @@ func (proxy Proxy) Server(options ServerOptions) *http.Server { } func (proxy Proxy) getPackageHandler(c *gin.Context) { - var name string - if c.Param("name") != "" { - name = c.Param("scope") + "/" + c.Param("name") - } else { - name = c.Param("scope") - } - - pkg, err := proxy.GetMetadata(name, c.Request.URL.Path, c.Request) + pkg, err := proxy.GetCachedPath(c.Request.URL.Path, c.Request) if err != nil { c.AbortWithError(500, err) @@ -49,8 +43,20 @@ func (proxy Proxy) getPackageHandler(c *gin.Context) { } } +func (proxy Proxy) getTarballHabdler(c *gin.Context) { + pkg, err := proxy.GetCachedPath(c.Request.URL.Path, c.Request) + + if err != nil { + c.AbortWithError(500, err) + } else { + c.Data(200, "application/json", pkg) + } +} + func (proxy Proxy) noRouteHandler(c *gin.Context) { - if c.Request.URL.Path == "/" { + if strings.Contains(c.Request.URL.Path, ".tgz") { + proxy.getTarballHabdler(c) + } else if c.Request.URL.Path == "/" { err := proxy.Database.Health() if err != nil {