diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/luarocks/fetch.lua | 76 | ||||
-rw-r--r-- | src/luarocks/manif.lua | 2 |
2 files changed, 73 insertions, 5 deletions
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua index 1882c348..c7f2d549 100644 --- a/src/luarocks/fetch.lua +++ b/src/luarocks/fetch.lua | |||
@@ -10,7 +10,25 @@ local persist = require("luarocks.persist") | |||
10 | local util = require("luarocks.util") | 10 | local util = require("luarocks.util") |
11 | local cfg = require("luarocks.core.cfg") | 11 | local cfg = require("luarocks.core.cfg") |
12 | 12 | ||
13 | function fetch.fetch_caching(url) | 13 | |
14 | --- Fetch a local or remote file, using a local cache directory. | ||
15 | -- Make a remote or local URL/pathname local, fetching the file if necessary. | ||
16 | -- Other "fetch" and "load" functions use this function to obtain files. | ||
17 | -- If a local pathname is given, it is returned as a result. | ||
18 | -- @param url string: a local pathname or a remote URL. | ||
19 | -- @param mirroring string: mirroring mode. | ||
20 | -- If set to "no_mirror", then rocks_servers mirror configuration is not used. | ||
21 | -- @return (string, nil, nil, boolean) or (nil, string, [string]): | ||
22 | -- in case of success: | ||
23 | -- * the absolute local pathname for the fetched file | ||
24 | -- * nil | ||
25 | -- * nil | ||
26 | -- * `true` if the file was fetched from cache | ||
27 | -- in case of failure: | ||
28 | -- * nil | ||
29 | -- * an error message | ||
30 | -- * an optional error code. | ||
31 | function fetch.fetch_caching(url, mirroring) | ||
14 | local repo_url, filename = url:match("^(.*)/([^/]+)$") | 32 | local repo_url, filename = url:match("^(.*)/([^/]+)$") |
15 | local name = repo_url:gsub("[/:]","_") | 33 | local name = repo_url:gsub("[/:]","_") |
16 | local cache_dir = dir.path(cfg.local_cache, name) | 34 | local cache_dir = dir.path(cfg.local_cache, name) |
@@ -29,13 +47,56 @@ function fetch.fetch_caching(url) | |||
29 | return cachefile, nil, nil, true | 47 | return cachefile, nil, nil, true |
30 | end | 48 | end |
31 | 49 | ||
32 | local file, err, errcode, from_cache = fetch.fetch_url(url, cachefile, true) | 50 | local file, err, errcode, from_cache = fetch.fetch_url(url, cachefile, true, mirroring) |
33 | if not file then | 51 | if not file then |
34 | return nil, err or "Failed downloading "..url, errcode | 52 | return nil, err or "Failed downloading "..url, errcode |
35 | end | 53 | end |
36 | return file, nil, nil, from_cache | 54 | return file, nil, nil, from_cache |
37 | end | 55 | end |
38 | 56 | ||
57 | local function ensure_trailing_slash(url) | ||
58 | return (url:gsub("/*$", "/")) | ||
59 | end | ||
60 | |||
61 | local function is_url_relative_to_rocks_servers(url, servers) | ||
62 | for _, item in ipairs(servers) do | ||
63 | if type(item) == "table" then | ||
64 | for i, s in ipairs(item) do | ||
65 | local base = ensure_trailing_slash(s) | ||
66 | if string.find(url, base, 1, true) == 1 then | ||
67 | return i, url:sub(#base + 1), item | ||
68 | end | ||
69 | end | ||
70 | end | ||
71 | end | ||
72 | end | ||
73 | |||
74 | local function download_with_mirrors(url, filename, cache, servers) | ||
75 | local idx, rest, mirrors = is_url_relative_to_rocks_servers(url, servers) | ||
76 | |||
77 | if not idx then | ||
78 | -- URL is not from a rock server | ||
79 | return fs.download(url, filename, cache) | ||
80 | end | ||
81 | |||
82 | -- URL is from a rock server: try to download it falling back to mirrors. | ||
83 | local err = "\n" | ||
84 | for i = idx, #mirrors do | ||
85 | local try_url = ensure_trailing_slash(mirrors[i]) .. rest | ||
86 | if i > idx then | ||
87 | util.warning("Failed downloading. Attempting mirror at " .. try_url) | ||
88 | end | ||
89 | local ok, name, from_cache = fs.download(try_url, filename, cache) | ||
90 | if ok then | ||
91 | return ok, name, from_cache | ||
92 | else | ||
93 | err = err .. name .. "\n" | ||
94 | end | ||
95 | end | ||
96 | |||
97 | return nil, err | ||
98 | end | ||
99 | |||
39 | --- Fetch a local or remote file. | 100 | --- Fetch a local or remote file. |
40 | -- Make a remote or local URL/pathname local, fetching the file if necessary. | 101 | -- Make a remote or local URL/pathname local, fetching the file if necessary. |
41 | -- Other "fetch" and "load" functions use this function to obtain files. | 102 | -- Other "fetch" and "load" functions use this function to obtain files. |
@@ -47,6 +108,8 @@ end | |||
47 | -- filename can be given explicitly as this second argument. | 108 | -- filename can be given explicitly as this second argument. |
48 | -- @param cache boolean: compare remote timestamps via HTTP HEAD prior to | 109 | -- @param cache boolean: compare remote timestamps via HTTP HEAD prior to |
49 | -- re-downloading the file. | 110 | -- re-downloading the file. |
111 | -- @param mirroring string: mirroring mode. | ||
112 | -- If set to "no_mirror", then rocks_servers mirror configuration is not used. | ||
50 | -- @return (string, nil, nil, boolean) or (nil, string, [string]): | 113 | -- @return (string, nil, nil, boolean) or (nil, string, [string]): |
51 | -- in case of success: | 114 | -- in case of success: |
52 | -- * the absolute local pathname for the fetched file | 115 | -- * the absolute local pathname for the fetched file |
@@ -57,7 +120,7 @@ end | |||
57 | -- * nil | 120 | -- * nil |
58 | -- * an error message | 121 | -- * an error message |
59 | -- * an optional error code. | 122 | -- * an optional error code. |
60 | function fetch.fetch_url(url, filename, cache) | 123 | function fetch.fetch_url(url, filename, cache, mirroring) |
61 | assert(type(url) == "string") | 124 | assert(type(url) == "string") |
62 | assert(type(filename) == "string" or not filename) | 125 | assert(type(filename) == "string" or not filename) |
63 | 126 | ||
@@ -84,7 +147,12 @@ function fetch.fetch_url(url, filename, cache) | |||
84 | return nil, "Failed copying local file " .. fullname .. " to " .. dstname .. ": " .. err | 147 | return nil, "Failed copying local file " .. fullname .. " to " .. dstname .. ": " .. err |
85 | end | 148 | end |
86 | elseif dir.is_basic_protocol(protocol) then | 149 | elseif dir.is_basic_protocol(protocol) then |
87 | local ok, name, from_cache = fs.download(url, filename, cache) | 150 | local ok, name, from_cache |
151 | if mirroring ~= "no_mirror" then | ||
152 | ok, name, from_cache = download_with_mirrors(url, filename, cache, cfg.rocks_servers) | ||
153 | else | ||
154 | ok, name, from_cache = fs.download(url, filename, cache) | ||
155 | end | ||
88 | if not ok then | 156 | if not ok then |
89 | return nil, "Failed downloading "..url..(name and " - "..name or ""), "network" | 157 | return nil, "Failed downloading "..url..(name and " - "..name or ""), "network" |
90 | end | 158 | end |
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua index 5790ef18..a4ddda11 100644 --- a/src/luarocks/manif.lua +++ b/src/luarocks/manif.lua | |||
@@ -105,7 +105,7 @@ function manif.load_manifest(repo_url, lua_version, versioned_only) | |||
105 | else | 105 | else |
106 | local err, errcode | 106 | local err, errcode |
107 | for _, filename in ipairs(filenames) do | 107 | for _, filename in ipairs(filenames) do |
108 | pathname, err, errcode, from_cache = fetch.fetch_caching(dir.path(repo_url, filename)) | 108 | pathname, err, errcode, from_cache = fetch.fetch_caching(dir.path(repo_url, filename), "no_mirror") |
109 | if pathname then | 109 | if pathname then |
110 | break | 110 | break |
111 | end | 111 | end |