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 |
