11local cjson = require " cjson.safe"
2+ local http = require " resty.http"
23
34local _M = {}
45
@@ -18,6 +19,44 @@ function _M.init()
1819 npmConfig :set (' MAXAGE' , _M .MAXAGE )
1920end
2021
22+ function _M .prefetchRelatedPackages (premature , selfHost , pkg )
23+ local httpc = http .new ()
24+ httpc :connect (' 127.0.0.1' , 4873 )
25+ local distTags = pkg [' dist-tags' ] or {}
26+ local versions = pkg .versions or {}
27+ local latestVersion = distTags .latest
28+ local latest = versions [latestVersion ] or {}
29+ local deps = latest .dependencies or {}
30+ local reqs = {}
31+ -- find any deps that we haven't already seen and queue them for fetching
32+ for k , v in pairs (deps ) do
33+ if meta :get (' /' .. k ) == nil then
34+ table.insert (reqs , {
35+ path = ' /' .. k ,
36+ method = ' GET' ,
37+ headers = {
38+ [" Host" ] = selfHost ,
39+ },
40+ })
41+ end
42+ end
43+ -- extract all the tarball URLs and fetch them to force them to be cached
44+ for v ,p in pairs (versions ) do
45+ local scheme , host , port , path , query = unpack (httpc :parse_uri (p .dist .tarball ))
46+ table.insert (reqs , {
47+ path = path ,
48+ method = ' GET' ,
49+ })
50+ end
51+ local responses , err = httpc :request_pipeline (reqs )
52+ for i ,r in ipairs (responses ) do
53+ if r .status then
54+ r :read_body () -- to oblivion!
55+ end
56+ end
57+ httpc :close ()
58+ end
59+
2160function _M .getPackage ()
2261 local uri = ngx .var .uri
2362 local meta = ngx .shared .npmMeta
@@ -37,10 +76,14 @@ function _M.getPackage()
3776 return ngx .redirect (uri , ngx .HTTP_MOVED_TEMPORARILY )
3877 end
3978 meta :set (uri , body , _M .MAXAGE )
79+ -- We rewrite the URLs AFTER caching so that we can be accessed by
80+ -- any hostname that is pointed at us.
81+ body = string.gsub (body , _M .hostPattern , base )
82+ ngx .timer .at (0.1 , _M .prefetchRelatedPackages , ngx .var .http_host , pkgJSON )
4083 else
84+ body = string.gsub (body , _M .hostPattern , base )
4185 ngx .var .ephemeralCacheStatus = ' HIT'
4286 end
43- body = string.gsub (body , _M .hostPattern , base )
4487 ngx .header [" Content-Length" ] = # body
4588 ngx .print (body )
4689end
0 commit comments