diff options
-rw-r--r-- | src/luarocks/fs/lua.lua | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index 54da4afd..db5c675d 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua | |||
@@ -606,34 +606,58 @@ local function request(url, method, http, loop_control) | |||
606 | end | 606 | end |
607 | end | 607 | end |
608 | 608 | ||
609 | local function http_request(url, http, cached) | 609 | -- @param url string: URL to fetch. |
610 | if cached then | 610 | -- @param filename string: local filename of the file to fetch. |
611 | local tsfd = io.open(cached..".timestamp", "r") | 611 | -- @param http table: The library to use (http from LuaSocket or LuaSec) |
612 | -- @param cache boolean: Whether to use a `.timestamp` file to check | ||
613 | -- via the HTTP Last-Modified header if the full download is needed. | ||
614 | -- @return (boolean | (nil, string, string?)): True if successful, or | ||
615 | -- nil, error message and optionally HTTPS error in case of errors. | ||
616 | local function http_request(url, filename, http, cache) | ||
617 | if cache then | ||
618 | local tsfd = io.open(filename..".timestamp", "r") | ||
612 | if tsfd then | 619 | if tsfd then |
613 | local timestamp = tsfd:read("*a") | 620 | local timestamp = tsfd:read("*a") |
614 | tsfd:close() | 621 | tsfd:close() |
615 | local result, status, headers, err = request(url, "HEAD", http) | 622 | local result, status, headers, err = request(url, "HEAD", http) |
616 | if status == 200 and headers["last-modified"] == timestamp then | ||
617 | return true | ||
618 | end | ||
619 | if not result then | 623 | if not result then |
620 | return nil, status, headers | 624 | return nil, status, headers |
621 | end | 625 | end |
626 | if status == 200 and headers["last-modified"] == timestamp then | ||
627 | return true | ||
628 | end | ||
622 | end | 629 | end |
623 | end | 630 | end |
624 | local result, status, headers, err = request(url, "GET", http) | 631 | local result, status, headers, err = request(url, "GET", http) |
625 | if result then | 632 | if not result then |
626 | if cached and headers["last-modified"] then | ||
627 | local tsfd = io.open(cached..".timestamp", "w") | ||
628 | if tsfd then | ||
629 | tsfd:write(headers["last-modified"]) | ||
630 | tsfd:close() | ||
631 | end | ||
632 | end | ||
633 | return table.concat(result) | ||
634 | else | ||
635 | return nil, status, headers | 633 | return nil, status, headers |
636 | end | 634 | end |
635 | if cache and headers["last-modified"] then | ||
636 | local tsfd = io.open(filename..".timestamp", "w") | ||
637 | if tsfd then | ||
638 | tsfd:write(headers["last-modified"]) | ||
639 | tsfd:close() | ||
640 | end | ||
641 | end | ||
642 | local file = io.open(filename, "wb") | ||
643 | if not file then return nil, 0, {} end | ||
644 | for _, data in ipairs(result) do | ||
645 | file:write(data) | ||
646 | end | ||
647 | file:close() | ||
648 | return true | ||
649 | end | ||
650 | |||
651 | local function ftp_request(url, filename) | ||
652 | local content, err = ftp.get(url) | ||
653 | if not content then | ||
654 | return false, err | ||
655 | end | ||
656 | local file = io.open(filename, "wb") | ||
657 | if not file then return false, err end | ||
658 | file:write(content) | ||
659 | file:close() | ||
660 | return true | ||
637 | end | 661 | end |
638 | 662 | ||
639 | local downloader_warning = false | 663 | local downloader_warning = false |
@@ -656,16 +680,16 @@ function fs_lua.download(url, filename, cache) | |||
656 | if cfg.no_proxy then | 680 | if cfg.no_proxy then |
657 | return fs.use_downloader(url, filename, cache) | 681 | return fs.use_downloader(url, filename, cache) |
658 | end | 682 | end |
659 | 683 | ||
660 | local content, err, https_err | 684 | local ok, err, https_err |
661 | if util.starts_with(url, "http:") then | 685 | if util.starts_with(url, "http:") then |
662 | content, err, https_err = http_request(url, http, cache and filename) | 686 | ok, err, https_err = http_request(url, filename, http, cache) |
663 | elseif util.starts_with(url, "ftp:") then | 687 | elseif util.starts_with(url, "ftp:") then |
664 | content, err = ftp.get(url) | 688 | ok, err = ftp_request(url, filename) |
665 | elseif util.starts_with(url, "https:") then | 689 | elseif util.starts_with(url, "https:") then |
666 | -- skip LuaSec when proxy is enabled since it is not supported | 690 | -- skip LuaSec when proxy is enabled since it is not supported |
667 | if luasec_ok and not cfg.https_proxy then | 691 | if luasec_ok and not cfg.https_proxy then |
668 | content, err = http_request(url, https, cache and filename) | 692 | ok, err = http_request(url, filename, https, cache) |
669 | else | 693 | else |
670 | https_err = true | 694 | https_err = true |
671 | end | 695 | end |
@@ -678,17 +702,9 @@ function fs_lua.download(url, filename, cache) | |||
678 | downloader_warning = true | 702 | downloader_warning = true |
679 | end | 703 | end |
680 | return fs.use_downloader(url, filename, cache) | 704 | return fs.use_downloader(url, filename, cache) |
705 | elseif not ok then | ||
706 | return nil, err | ||
681 | end | 707 | end |
682 | if cache and content == true then | ||
683 | return true, filename | ||
684 | end | ||
685 | if not content then | ||
686 | return false, tostring(err) | ||
687 | end | ||
688 | local file = io.open(filename, "wb") | ||
689 | if not file then return false end | ||
690 | file:write(content) | ||
691 | file:close() | ||
692 | return true, filename | 708 | return true, filename |
693 | end | 709 | end |
694 | 710 | ||