diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2014-06-26 21:43:14 -0300 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2014-06-26 21:43:14 -0300 |
commit | c318a9a6a55ad0c50dc9ec99dbf3aa750ad5021b (patch) | |
tree | b11a596a8d17b5239e68aac02d42dcd059b64cbf /src | |
parent | ee69f76118b6c834e2217a0d178e9dee263bfaf1 (diff) | |
download | luarocks-c318a9a6a55ad0c50dc9ec99dbf3aa750ad5021b.tar.gz luarocks-c318a9a6a55ad0c50dc9ec99dbf3aa750ad5021b.tar.bz2 luarocks-c318a9a6a55ad0c50dc9ec99dbf3aa750ad5021b.zip |
HTTPS support for downloading and uploading rocks.
HTTPS is set as default for uploading.
HTTP is still default for downloading to keep dependencies low and because the
HTTPS code is new; might be changed in the future.
See #273 and #240.
Diffstat (limited to 'src')
-rwxr-xr-x | src/bin/luarocks | 4 | ||||
-rwxr-xr-x | src/bin/luarocks-admin | 4 | ||||
-rw-r--r-- | src/luarocks/cfg.lua | 42 | ||||
-rw-r--r-- | src/luarocks/fs/lua.lua | 27 | ||||
-rw-r--r-- | src/luarocks/fs/unix/tools.lua | 2 | ||||
-rw-r--r-- | src/luarocks/fs/win32/tools.lua | 2 | ||||
-rw-r--r-- | src/luarocks/loader.lua | 22 | ||||
-rw-r--r-- | src/luarocks/upload/api.lua | 110 | ||||
-rw-r--r-- | src/luarocks/upload/multipart.lua | 11 | ||||
-rw-r--r-- | src/luarocks/util.lua | 2 |
10 files changed, 180 insertions, 46 deletions
diff --git a/src/bin/luarocks b/src/bin/luarocks index 3c9e1b74..9101e675 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks | |||
@@ -1,5 +1,9 @@ | |||
1 | #!/usr/bin/env lua | 1 | #!/usr/bin/env lua |
2 | 2 | ||
3 | -- this should be loaded first. | ||
4 | local cfg = require("luarocks.cfg") | ||
5 | cfg.init_package_paths() | ||
6 | |||
3 | local loader = require("luarocks.loader") | 7 | local loader = require("luarocks.loader") |
4 | local command_line = require("luarocks.command_line") | 8 | local command_line = require("luarocks.command_line") |
5 | 9 | ||
diff --git a/src/bin/luarocks-admin b/src/bin/luarocks-admin index e7f49c25..f49db920 100755 --- a/src/bin/luarocks-admin +++ b/src/bin/luarocks-admin | |||
@@ -1,5 +1,9 @@ | |||
1 | #!/usr/bin/env lua | 1 | #!/usr/bin/env lua |
2 | 2 | ||
3 | -- this should be loaded first. | ||
4 | local cfg = require("luarocks.cfg") | ||
5 | cfg.init_package_paths() | ||
6 | |||
3 | local loader = require("luarocks.loader") | 7 | local loader = require("luarocks.loader") |
4 | local command_line = require("luarocks.command_line") | 8 | local command_line = require("luarocks.command_line") |
5 | 9 | ||
diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua index 2e86c3ca..8b5984ef 100644 --- a/src/luarocks/cfg.lua +++ b/src/luarocks/cfg.lua | |||
@@ -17,6 +17,8 @@ local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, | |||
17 | local cfg = {} | 17 | local cfg = {} |
18 | package.loaded["luarocks.cfg"] = cfg | 18 | package.loaded["luarocks.cfg"] = cfg |
19 | 19 | ||
20 | local util = require("luarocks.util") | ||
21 | |||
20 | cfg.lua_version = _VERSION:sub(5) | 22 | cfg.lua_version = _VERSION:sub(5) |
21 | local version_suffix = cfg.lua_version:gsub("%.", "_") | 23 | local version_suffix = cfg.lua_version:gsub("%.", "_") |
22 | 24 | ||
@@ -167,7 +169,6 @@ if not site_config.LUAROCKS_FORCE_CONFIG then | |||
167 | end | 169 | end |
168 | if home_overrides then | 170 | if home_overrides then |
169 | home_config_ok = true | 171 | home_config_ok = true |
170 | local util = require("luarocks.util") | ||
171 | if home_overrides.rocks_trees then | 172 | if home_overrides.rocks_trees then |
172 | cfg.rocks_trees = nil | 173 | cfg.rocks_trees = nil |
173 | end | 174 | end |
@@ -217,12 +218,13 @@ local defaults = { | |||
217 | "http://rocks.moonscript.org", | 218 | "http://rocks.moonscript.org", |
218 | "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/", | 219 | "https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/", |
219 | "http://luafr.org/moonrocks/", | 220 | "http://luafr.org/moonrocks/", |
221 | "http://luarocks.logiceditor.com/rocks", | ||
220 | } | 222 | } |
221 | }, | 223 | }, |
222 | disabled_servers = {}, | 224 | disabled_servers = {}, |
223 | 225 | ||
224 | upload = { | 226 | upload = { |
225 | server = "rocks.moonscript.org", | 227 | server = "https://rocks.moonscript.org", |
226 | tool_version = "0.0.1", | 228 | tool_version = "0.0.1", |
227 | api_version = "1", | 229 | api_version = "1", |
228 | }, | 230 | }, |
@@ -527,20 +529,28 @@ local cfg_mt = { | |||
527 | } | 529 | } |
528 | setmetatable(cfg, cfg_mt) | 530 | setmetatable(cfg, cfg_mt) |
529 | 531 | ||
532 | function cfg.make_paths_from_tree(tree) | ||
533 | local lua_path, lib_path, bin_path | ||
534 | if type(tree) == "string" then | ||
535 | lua_path = tree..cfg.lua_modules_path | ||
536 | lib_path = tree..cfg.lib_modules_path | ||
537 | bin_path = tree.."/bin" | ||
538 | else | ||
539 | lua_path = tree.lua_dir or tree.root..cfg.lua_modules_path | ||
540 | lib_path = tree.lib_dir or tree.root..cfg.lib_modules_path | ||
541 | bin_path = tree.bin_dir or tree.root.."/bin" | ||
542 | end | ||
543 | return lua_path, lib_path, bin_path | ||
544 | end | ||
545 | |||
530 | function cfg.package_paths() | 546 | function cfg.package_paths() |
531 | local new_path, new_cpath, new_bin = {}, {}, {} | 547 | local new_path, new_cpath, new_bin = {}, {}, {} |
532 | for _,tree in ipairs(cfg.rocks_trees) do | 548 | for _,tree in ipairs(cfg.rocks_trees) do |
533 | if type(tree) == "string" then | 549 | local lua_path, lib_path, bin_path = cfg.make_paths_from_tree(tree) |
534 | table.insert(new_path, tree..cfg.lua_modules_path.."/?.lua") | 550 | table.insert(new_path, lua_path.."/?.lua") |
535 | table.insert(new_path, tree..cfg.lua_modules_path.."/?/init.lua") | 551 | table.insert(new_path, lua_path.."/?/init.lua") |
536 | table.insert(new_cpath, tree..cfg.lib_modules_path.."/?."..cfg.lib_extension) | 552 | table.insert(new_cpath, lib_path.."/?."..cfg.lib_extension) |
537 | table.insert(new_bin, tree.."/bin") | 553 | table.insert(new_bin, bin_path) |
538 | else | ||
539 | table.insert(new_path, (tree.lua_dir or tree.root..cfg.lua_modules_path).."/?.lua") | ||
540 | table.insert(new_path, (tree.lua_dir or tree.root..cfg.lua_modules_path).."/?/init.lua") | ||
541 | table.insert(new_cpath, (tree.lib_dir or tree.root..cfg.lib_modules_path).."/?."..cfg.lib_extension) | ||
542 | table.insert(new_bin, (tree.bin_dir or tree.root.."/bin")) | ||
543 | end | ||
544 | end | 554 | end |
545 | if extra_luarocks_module_dir then | 555 | if extra_luarocks_module_dir then |
546 | table.insert(new_path, extra_luarocks_module_dir) | 556 | table.insert(new_path, extra_luarocks_module_dir) |
@@ -548,6 +558,12 @@ function cfg.package_paths() | |||
548 | return table.concat(new_path, ";"), table.concat(new_cpath, ";"), table.concat(new_bin, cfg.export_path_separator) | 558 | return table.concat(new_path, ";"), table.concat(new_cpath, ";"), table.concat(new_bin, cfg.export_path_separator) |
549 | end | 559 | end |
550 | 560 | ||
561 | function cfg.init_package_paths() | ||
562 | local lr_path, lr_cpath, lr_bin = cfg.package_paths() | ||
563 | package.path = util.remove_path_dupes(package.path .. ";" .. lr_path, ";") | ||
564 | package.cpath = util.remove_path_dupes(package.cpath .. ";" .. lr_cpath, ";") | ||
565 | end | ||
566 | |||
551 | function cfg.which_config() | 567 | function cfg.which_config() |
552 | return sys_config_file, sys_config_ok, home_config_file, home_config_ok | 568 | return sys_config_file, sys_config_ok, home_config_file, home_config_ok |
553 | end | 569 | end |
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index f18deac3..b2619051 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua | |||
@@ -592,7 +592,7 @@ local function request(url, method, http, loop_control) | |||
592 | loop_control[url] = true | 592 | loop_control[url] = true |
593 | return request(location, method, redirect_protocols[protocol], loop_control) | 593 | return request(location, method, redirect_protocols[protocol], loop_control) |
594 | else | 594 | else |
595 | return nil, "URL redirected to unsupported protocol - install luasec to get HTTPS support." | 595 | return nil, "URL redirected to unsupported protocol - install luasec to get HTTPS support.", "https" |
596 | end | 596 | end |
597 | end | 597 | end |
598 | return nil, err | 598 | return nil, err |
@@ -614,7 +614,7 @@ local function http_request(url, http, cached) | |||
614 | return true | 614 | return true |
615 | end | 615 | end |
616 | if not result then | 616 | if not result then |
617 | return nil, status | 617 | return nil, status, headers |
618 | end | 618 | end |
619 | end | 619 | end |
620 | end | 620 | end |
@@ -629,10 +629,12 @@ local function http_request(url, http, cached) | |||
629 | end | 629 | end |
630 | return table.concat(result) | 630 | return table.concat(result) |
631 | else | 631 | else |
632 | return nil, status | 632 | return nil, status, headers |
633 | end | 633 | end |
634 | end | 634 | end |
635 | 635 | ||
636 | local downloader_warning = false | ||
637 | |||
636 | --- Download a remote file. | 638 | --- Download a remote file. |
637 | -- @param url string: URL to be fetched. | 639 | -- @param url string: URL to be fetched. |
638 | -- @param filename string or nil: this function attempts to detect the | 640 | -- @param filename string or nil: this function attempts to detect the |
@@ -647,20 +649,27 @@ function fs_lua.download(url, filename, cache) | |||
647 | 649 | ||
648 | filename = fs.absolute_name(filename or dir.base_name(url)) | 650 | filename = fs.absolute_name(filename or dir.base_name(url)) |
649 | 651 | ||
650 | local content, err | 652 | local content, err, https_err |
651 | if util.starts_with(url, "http:") then | 653 | if util.starts_with(url, "http:") then |
652 | content, err = http_request(url, http, cache and filename) | 654 | content, err, https_err = http_request(url, http, cache and filename) |
653 | elseif util.starts_with(url, "ftp:") then | 655 | elseif util.starts_with(url, "ftp:") then |
654 | content, err = ftp.get(url) | 656 | content, err = ftp.get(url) |
655 | elseif util.starts_with(url, "https:") then | 657 | elseif util.starts_with(url, "https:") then |
656 | if luasec_ok then | 658 | if luasec_ok then |
657 | content, err = http_request(url, https, cache and filename) | 659 | content, err = http_request(url, https, cache and filename) |
658 | else | 660 | else |
659 | err = "Unsupported protocol - install luasec to get HTTPS support." | 661 | https_err = true |
660 | end | 662 | end |
661 | else | 663 | else |
662 | err = "Unsupported protocol" | 664 | err = "Unsupported protocol" |
663 | end | 665 | end |
666 | if https_err then | ||
667 | if not downloader_warning then | ||
668 | util.printerr("Warning: falling back to "..cfg.downloader.." - install luasec to get native HTTPS support") | ||
669 | downloader_warning = true | ||
670 | end | ||
671 | return fs.use_downloader(url, filename, cache) | ||
672 | end | ||
664 | if cache and content == true then | 673 | if cache and content == true then |
665 | return true, filename | 674 | return true, filename |
666 | end | 675 | end |
@@ -674,6 +683,12 @@ function fs_lua.download(url, filename, cache) | |||
674 | return true, filename | 683 | return true, filename |
675 | end | 684 | end |
676 | 685 | ||
686 | else --...if socket_ok == false then | ||
687 | |||
688 | function fs_lua.download(url, filename, cache) | ||
689 | return fs.use_downloader(url, filename, cache) | ||
690 | end | ||
691 | |||
677 | end | 692 | end |
678 | --------------------------------------------------------------------- | 693 | --------------------------------------------------------------------- |
679 | -- MD5 functions | 694 | -- MD5 functions |
diff --git a/src/luarocks/fs/unix/tools.lua b/src/luarocks/fs/unix/tools.lua index 69466931..f36e815a 100644 --- a/src/luarocks/fs/unix/tools.lua +++ b/src/luarocks/fs/unix/tools.lua | |||
@@ -238,7 +238,7 @@ end | |||
238 | -- filename can be given explicitly as this second argument. | 238 | -- filename can be given explicitly as this second argument. |
239 | -- @return (boolean, string): true and the filename on success, | 239 | -- @return (boolean, string): true and the filename on success, |
240 | -- false and the error message on failure. | 240 | -- false and the error message on failure. |
241 | function tools.download(url, filename, cache) | 241 | function tools.use_downloader(url, filename, cache) |
242 | assert(type(url) == "string") | 242 | assert(type(url) == "string") |
243 | assert(type(filename) == "string" or not filename) | 243 | assert(type(filename) == "string" or not filename) |
244 | 244 | ||
diff --git a/src/luarocks/fs/win32/tools.lua b/src/luarocks/fs/win32/tools.lua index a8b2a1db..f970f36a 100644 --- a/src/luarocks/fs/win32/tools.lua +++ b/src/luarocks/fs/win32/tools.lua | |||
@@ -248,7 +248,7 @@ end | |||
248 | -- filename can be given explicitly as this second argument. | 248 | -- filename can be given explicitly as this second argument. |
249 | -- @return (boolean, string): true and the filename on success, | 249 | -- @return (boolean, string): true and the filename on success, |
250 | -- false and the error message on failure. | 250 | -- false and the error message on failure. |
251 | function tools.download(url, filename, cache) | 251 | function tools.use_downloader(url, filename, cache) |
252 | assert(type(url) == "string") | 252 | assert(type(url) == "string") |
253 | assert(type(filename) == "string" or not filename) | 253 | assert(type(filename) == "string" or not filename) |
254 | 254 | ||
diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua index 3d36723f..c200d5ec 100644 --- a/src/luarocks/loader.lua +++ b/src/luarocks/loader.lua | |||
@@ -128,10 +128,11 @@ end | |||
128 | -- (eg "luasocket"), the version (eg "2.0.2-1"), the path of the rocks tree | 128 | -- (eg "luasocket"), the version (eg "2.0.2-1"), the path of the rocks tree |
129 | -- (eg "/usr/local"), and the numeric index of the matching entry, so the | 129 | -- (eg "/usr/local"), and the numeric index of the matching entry, so the |
130 | -- filter function can know if the matching module was the first entry or not. | 130 | -- filter function can know if the matching module was the first entry or not. |
131 | -- @return string, string, string: name of the rock containing the module | 131 | -- @return string, string, string, (string or table): |
132 | -- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"), | 132 | -- * name of the rock containing the module (eg. "luasocket") |
133 | -- name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is | 133 | -- * version of the rock (eg. "2.0.2-1") |
134 | -- stored versioned). | 134 | -- * name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is stored versioned). |
135 | -- * tree of the module (string or table in `rocks_trees` format) | ||
135 | local function select_module(module, filter_module_name) | 136 | local function select_module(module, filter_module_name) |
136 | --assert(type(module) == "string") | 137 | --assert(type(module) == "string") |
137 | --assert(type(filter_module_name) == "function") | 138 | --assert(type(filter_module_name) == "function") |
@@ -155,7 +156,7 @@ local function select_module(module, filter_module_name) | |||
155 | return name, version, module_name | 156 | return name, version, module_name |
156 | end | 157 | end |
157 | version = deps.parse_version(version) | 158 | version = deps.parse_version(version) |
158 | table.insert(providers, {name = name, version = version, module_name = module_name}) | 159 | table.insert(providers, {name = name, version = version, module_name = module_name, tree = tree}) |
159 | end | 160 | end |
160 | end | 161 | end |
161 | end | 162 | end |
@@ -163,16 +164,17 @@ local function select_module(module, filter_module_name) | |||
163 | if next(providers) then | 164 | if next(providers) then |
164 | table.sort(providers, sort_versions) | 165 | table.sort(providers, sort_versions) |
165 | local first = providers[1] | 166 | local first = providers[1] |
166 | return first.name, first.version.string, first.module_name | 167 | return first.name, first.version.string, first.module_name, first.tree |
167 | end | 168 | end |
168 | end | 169 | end |
169 | 170 | ||
170 | --- Search for a module | 171 | --- Search for a module |
171 | -- @param module string: module name (eg. "socket.core") | 172 | -- @param module string: module name (eg. "socket.core") |
172 | -- @return string, string, string: name of the rock containing the module | 173 | -- @return string, string, string, (string or table): |
173 | -- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"), | 174 | -- * name of the rock containing the module (eg. "luasocket") |
174 | -- name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is | 175 | -- * version of the rock (eg. "2.0.2-1") |
175 | -- stored versioned). | 176 | -- * name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is stored versioned). |
177 | -- * tree of the module (string or table in `rocks_trees` format) | ||
176 | local function pick_module(module) | 178 | local function pick_module(module) |
177 | return | 179 | return |
178 | select_module(module, function(module_name, name, version, tree, i) | 180 | select_module(module, function(module_name, name, version, tree, i) |
diff --git a/src/luarocks/upload/api.lua b/src/luarocks/upload/api.lua index 818d293e..4ab311f2 100644 --- a/src/luarocks/upload/api.lua +++ b/src/luarocks/upload/api.lua | |||
@@ -5,6 +5,7 @@ local cfg = require("luarocks.cfg") | |||
5 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
6 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
7 | local persist = require("luarocks.persist") | 7 | local persist = require("luarocks.persist") |
8 | local multipart = require("luarocks.upload.multipart") | ||
8 | 9 | ||
9 | local Api = {} | 10 | local Api = {} |
10 | 11 | ||
@@ -43,7 +44,7 @@ end | |||
43 | function Api:check_version() | 44 | function Api:check_version() |
44 | if not self._server_tool_version then | 45 | if not self._server_tool_version then |
45 | local tool_version = cfg.upload.tool_version | 46 | local tool_version = cfg.upload.tool_version |
46 | local res, err = self:request("http://" .. tostring(self.config.server) .. "/api/tool_version", { | 47 | local res, err = self:request(tostring(self.config.server) .. "/api/tool_version", { |
47 | current = tool_version | 48 | current = tool_version |
48 | }) | 49 | }) |
49 | if not res then | 50 | if not res then |
@@ -80,12 +81,11 @@ end | |||
80 | 81 | ||
81 | function Api:raw_method(path, ...) | 82 | function Api:raw_method(path, ...) |
82 | self:check_version() | 83 | self:check_version() |
83 | local url = "http://" .. tostring(self.config.server) .. "/api/" .. tostring(cfg.upload.api_version) .. "/" .. tostring(self.config.key) .. "/" .. tostring(path) | 84 | local url = tostring(self.config.server) .. "/api/" .. tostring(cfg.upload.api_version) .. "/" .. tostring(self.config.key) .. "/" .. tostring(path) |
84 | return self:request(url, ...) | 85 | return self:request(url, ...) |
85 | end | 86 | end |
86 | 87 | ||
87 | local function encode_query_string(t, sep) | 88 | local function encode_query_string(t, sep) |
88 | local url = require("socket.url") | ||
89 | if sep == nil then | 89 | if sep == nil then |
90 | sep = "&" | 90 | sep = "&" |
91 | end | 91 | end |
@@ -95,9 +95,9 @@ local function encode_query_string(t, sep) | |||
95 | if type(k) == "number" and type(v) == "table" then | 95 | if type(k) == "number" and type(v) == "table" then |
96 | k, v = v[1], v[2] | 96 | k, v = v[1], v[2] |
97 | end | 97 | end |
98 | buf[i + 1] = url.escape(k) | 98 | buf[i + 1] = multipart.url_escape(k) |
99 | buf[i + 2] = "=" | 99 | buf[i + 2] = "=" |
100 | buf[i + 3] = url.escape(v) | 100 | buf[i + 3] = multipart.url_escape(v) |
101 | buf[i + 4] = sep | 101 | buf[i + 4] = sep |
102 | i = i + 4 | 102 | i = i + 4 |
103 | end | 103 | end |
@@ -116,12 +116,99 @@ local function require_json() | |||
116 | return nil | 116 | return nil |
117 | end | 117 | end |
118 | 118 | ||
119 | local ltn12_ok, ltn12 = pcall(require, "ltn12") | ||
120 | if not ltn12_ok then -- If not using LuaSocket and/or LuaSec... | ||
121 | |||
122 | function Api:request(url, params, post_params) | ||
123 | local vars = cfg.variables | ||
124 | local json_ok, json = require_json() | ||
125 | if not json_ok then return nil, "A JSON library is required for this command." end | ||
126 | |||
127 | if cfg.downloader == "wget" then | ||
128 | local curl_ok = fs.execute_quiet(vars.CURL, "--version") | ||
129 | if not curl_ok then | ||
130 | return nil, "Missing network helper program 'curl'.\nMake sure 'curl' is installed and available from your path." | ||
131 | end | ||
132 | end | ||
133 | |||
134 | if not self.config.key then | ||
135 | return nil, "Must have API key before performing any actions." | ||
136 | end | ||
137 | local body | ||
138 | local headers = {} | ||
139 | if params and next(params) then | ||
140 | url = url .. ("?" .. encode_query_string(params)) | ||
141 | end | ||
142 | local method = "GET" | ||
143 | local out | ||
144 | local tmpfile = os.tmpname() | ||
145 | if post_params then | ||
146 | method = "POST" | ||
147 | local curl_cmd = fs.Q(vars.CURL).." -f -k -L --user-agent '"..cfg.user_agent.." via curl' " | ||
148 | for k,v in pairs(post_params) do | ||
149 | local var = v | ||
150 | if type(v) == "table" then | ||
151 | var = "@"..v.fname | ||
152 | end | ||
153 | curl_cmd = curl_cmd .. "--form '"..k.."="..var.."' " | ||
154 | end | ||
155 | if cfg.connection_timeout and cfg.connection_timeout > 0 then | ||
156 | curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." " | ||
157 | end | ||
158 | ok = fs.execute_string(curl_cmd..fs.Q(url).." 2> /dev/null 1> "..fs.Q(tmpfile)) | ||
159 | else | ||
160 | local ok, err = fs.download(url, tmpfile) | ||
161 | if not ok then | ||
162 | return nil, "API failure: " .. tostring(err) .. " - " .. tostring(url) | ||
163 | end | ||
164 | end | ||
165 | |||
166 | local tmpfd = io.open(tmpfile) | ||
167 | if not tmpfd then | ||
168 | os.remove(tmpfile) | ||
169 | return nil, "API failure reading temporary file - " .. tostring(url) | ||
170 | end | ||
171 | out = tmpfd:read("*a") | ||
172 | tmpfd:close() | ||
173 | os.remove(tmpfile) | ||
174 | |||
175 | if self.debug then | ||
176 | util.printout("[" .. tostring(method) .. " via curl] " .. tostring(url) .. " ... ") | ||
177 | end | ||
178 | |||
179 | return json.decode(out) | ||
180 | end | ||
181 | |||
182 | else -- use LuaSocket and LuaSec | ||
183 | |||
184 | local warned_luasec = false | ||
185 | |||
119 | function Api:request(url, params, post_params) | 186 | function Api:request(url, params, post_params) |
120 | local http_ok, http = pcall(require, "socket.http") | ||
121 | local ltn12_ok, ltn12 = pcall(require, "ltn12") | ||
122 | local json_ok, json = require_json() | 187 | local json_ok, json = require_json() |
123 | if not http_ok then return nil, "LuaSocket is required for this command." end | ||
124 | if not json_ok then return nil, "A JSON library is required for this command." end | 188 | if not json_ok then return nil, "A JSON library is required for this command." end |
189 | local server = tostring(self.config.server) | ||
190 | local http_ok, http | ||
191 | local via = "luasocket" | ||
192 | if server:match("^https://") then | ||
193 | http_ok, http = pcall(require, "ssl.https") | ||
194 | if http_ok then | ||
195 | via = "luasec" | ||
196 | else | ||
197 | if not warned_luasec then | ||
198 | util.printerr("LuaSec is not available; using plain HTTP. Install 'luasec' to enable HTTPS.") | ||
199 | warned_luasec = true | ||
200 | end | ||
201 | http_ok, http = pcall(require, "socket.http") | ||
202 | server = server:gsub("^https", "http") | ||
203 | url = url:gsub("^https", "http") | ||
204 | via = "luasocket" | ||
205 | end | ||
206 | else | ||
207 | http_ok, http = pcall(require, "socket.http") | ||
208 | end | ||
209 | if not http_ok then | ||
210 | return nil, "Failed loading socket library!" | ||
211 | end | ||
125 | 212 | ||
126 | if not self.config.key then | 213 | if not self.config.key then |
127 | return nil, "Must have API key before performing any actions." | 214 | return nil, "Must have API key before performing any actions." |
@@ -132,7 +219,6 @@ function Api:request(url, params, post_params) | |||
132 | url = url .. ("?" .. encode_query_string(params)) | 219 | url = url .. ("?" .. encode_query_string(params)) |
133 | end | 220 | end |
134 | if post_params then | 221 | if post_params then |
135 | local multipart = require("luarocks.upload.multipart") | ||
136 | local boundary | 222 | local boundary |
137 | body, boundary = multipart.encode(post_params) | 223 | body, boundary = multipart.encode(post_params) |
138 | headers["Content-length"] = #body | 224 | headers["Content-length"] = #body |
@@ -140,7 +226,7 @@ function Api:request(url, params, post_params) | |||
140 | end | 226 | end |
141 | local method = post_params and "POST" or "GET" | 227 | local method = post_params and "POST" or "GET" |
142 | if self.debug then | 228 | if self.debug then |
143 | util.printout("[" .. tostring(method) .. "] " .. tostring(url) .. " ... ") | 229 | util.printout("[" .. tostring(method) .. " via "..via.."] " .. tostring(url) .. " ... ") |
144 | end | 230 | end |
145 | local out = {} | 231 | local out = {} |
146 | local _, status = http.request({ | 232 | local _, status = http.request({ |
@@ -159,6 +245,8 @@ function Api:request(url, params, post_params) | |||
159 | return json.decode(table.concat(out)) | 245 | return json.decode(table.concat(out)) |
160 | end | 246 | end |
161 | 247 | ||
248 | end | ||
249 | |||
162 | function api.new(flags, name) | 250 | function api.new(flags, name) |
163 | local self = {} | 251 | local self = {} |
164 | setmetatable(self, { __index = Api }) | 252 | setmetatable(self, { __index = Api }) |
@@ -169,7 +257,7 @@ function api.new(flags, name) | |||
169 | self.debug = flags["debug"] | 257 | self.debug = flags["debug"] |
170 | if not self.config.key then | 258 | if not self.config.key then |
171 | return nil, "You need an API key to upload rocks.\n" .. | 259 | return nil, "You need an API key to upload rocks.\n" .. |
172 | "Navigate to http://"..self.config.server.."/settings to get a key\n" .. | 260 | "Navigate to "..self.config.server.."/settings to get a key\n" .. |
173 | "and then pass it through the --api-key=<key> flag." | 261 | "and then pass it through the --api-key=<key> flag." |
174 | end | 262 | end |
175 | if flags["api-key"] then | 263 | if flags["api-key"] then |
diff --git a/src/luarocks/upload/multipart.lua b/src/luarocks/upload/multipart.lua index 95afe1b3..56776570 100644 --- a/src/luarocks/upload/multipart.lua +++ b/src/luarocks/upload/multipart.lua | |||
@@ -1,14 +1,19 @@ | |||
1 | 1 | ||
2 | local multipart = {} | 2 | local multipart = {} |
3 | 3 | ||
4 | local url = require("socket.url") | ||
5 | |||
6 | local File = {} | 4 | local File = {} |
7 | 5 | ||
8 | local unpack = unpack or table.unpack | 6 | local unpack = unpack or table.unpack |
9 | 7 | ||
10 | math.randomseed(os.time()) | 8 | math.randomseed(os.time()) |
11 | 9 | ||
10 | -- socket.url.escape(s) from LuaSocket 3.0rc1 | ||
11 | function multipart.url_escape(s) | ||
12 | return (string.gsub(s, "([^A-Za-z0-9_])", function(c) | ||
13 | return string.format("%%%02x", string.byte(c)) | ||
14 | end)) | ||
15 | end | ||
16 | |||
12 | function File:mime() | 17 | function File:mime() |
13 | if not self.mimetype then | 18 | if not self.mimetype then |
14 | local mimetypes_ok, mimetypes = pcall(require, "mimetypes") | 19 | local mimetypes_ok, mimetypes = pcall(require, "mimetypes") |
@@ -64,7 +69,7 @@ function multipart.encode(params) | |||
64 | local chunks = {} | 69 | local chunks = {} |
65 | for _, tuple in ipairs(tuples) do | 70 | for _, tuple in ipairs(tuples) do |
66 | local k,v = unpack(tuple) | 71 | local k,v = unpack(tuple) |
67 | k = url.escape(k) | 72 | k = multipart.url_escape(k) |
68 | local buffer = { 'Content-Disposition: form-data; name="' .. k .. '"' } | 73 | local buffer = { 'Content-Disposition: form-data; name="' .. k .. '"' } |
69 | local content | 74 | local content |
70 | if type(v) == "table" and v.__class == File then | 75 | if type(v) == "table" and v.__class == File then |
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 1bf6533b..8772883b 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua | |||
@@ -392,7 +392,7 @@ function util.deps_mode_help(program) | |||
392 | end | 392 | end |
393 | 393 | ||
394 | function util.see_help(command, program) | 394 | function util.see_help(command, program) |
395 | return "See '"..util.this_program(program or "luarocks")..' help '..command.."'." | 395 | return "See '"..util.this_program(program or "luarocks")..' help'..(command and " "..command or "").."'." |
396 | end | 396 | end |
397 | 397 | ||
398 | -- from http://lua-users.org/wiki/SplitJoin | 398 | -- from http://lua-users.org/wiki/SplitJoin |