From 1b88ec42b84c9ef25a5e643cdbb3a25eb7530a9b Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Thu, 11 Sep 2014 14:39:24 +0500 Subject: [PATCH 1/2] Fix. multi:info_read correctly remove easy handle. --- examples/cURLv3/multi2.lua | 35 +++++++++++++++++++++++++++++++++++ src/lua/cURL/impl/cURL.lua | 11 ++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 examples/cURLv3/multi2.lua diff --git a/examples/cURLv3/multi2.lua b/examples/cURLv3/multi2.lua new file mode 100644 index 0000000..49850c2 --- /dev/null +++ b/examples/cURLv3/multi2.lua @@ -0,0 +1,35 @@ +local cURL = require("cURL") + +local f1 = io.open("lua.html", "w+b") +local f2 = io.open("luajit.html", "w+b") + +-- setup easy and url +c1 = cURL.easy{url = "http://www.lua.org/", writefunction = f1} +c2 = cURL.easy{url = "http://luajit.org/", writefunction = f2} +c3 = cURL.easy{url = "****://luajit.org/"} -- UNSUPPORTED_PROTOCOL + +m = cURL.multi() + :add_handle(c1) + :add_handle(c2) + :add_handle(c3) + +local remain = 3 +while remain > 0 do + local last = m:perform() -- do some work + if last < remain then -- we have done some tasks + while true do -- proceed results/errors + local e, ok, err = m:info_read(true) -- get result and remove handle + if e == 0 then break end -- no more finished tasks + if ok then -- succeed + print(e:getinfo_effective_url(), '-', e:getinfo_response_code()) + else -- failure + print(e:getinfo_effective_url(), '-', err) + end + e:close() + end + end + remain = last + + -- wait while libcurl do io select + m:wait() +end diff --git a/src/lua/cURL/impl/cURL.lua b/src/lua/cURL/impl/cURL.lua index 401bae4..066d212 100644 --- a/src/lua/cURL/impl/cURL.lua +++ b/src/lua/cURL/impl/cURL.lua @@ -393,7 +393,16 @@ function Multi:remove_handle(e) return remove_handle(self, h) end ---! @fixme Multi:info_read(true) should also remove easy handle from self._easy +function Multi:info_read(...) + local h, ok, err = self:handle():info_read(...) + if not h then return nil, ok end + if h == 0 then return h end + + if ... and self._easy[h] then + self._easy[h], self._easy.n = nil, self._easy.n - 1 + end + return h, ok, err +end end ------------------------------------------- From fe66e7223b8d7e28089dc583870eaa2c5e33bf5c Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Thu, 11 Sep 2014 17:28:42 +0500 Subject: [PATCH 2/2] Add. `find_ca_bundle` function to `cURL.utils` module to find curl-ca-bundle.crt file --- .travis.yml | 1 + rockspecs/lua-curl-scm-0.rockspec | 1 + src/lua/cURL/utils.lua | 69 +++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 src/lua/cURL/utils.lua diff --git a/.travis.yml b/.travis.yml index 5964e92..99a414e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,7 @@ install: script: - cd test + - lua -e "print(require 'cURL.utils'.find_ca_bundle())" - lunit.sh test_easy.lua - lunit.sh test_safe.lua - lunit.sh test_form.lua diff --git a/rockspecs/lua-curl-scm-0.rockspec b/rockspecs/lua-curl-scm-0.rockspec index b74f0ff..c5fb684 100644 --- a/rockspecs/lua-curl-scm-0.rockspec +++ b/rockspecs/lua-curl-scm-0.rockspec @@ -59,6 +59,7 @@ build = { modules = { ["cURL" ] = "src/lua/cURL.lua", ["cURL.safe" ] = "src/lua/cURL/safe.lua", + ["cURL.utils" ] = "src/lua/cURL/utils.lua", ["cURL.impl.cURL" ] = "src/lua/cURL/impl/cURL.lua", lcurl = { diff --git a/src/lua/cURL/utils.lua b/src/lua/cURL/utils.lua new file mode 100644 index 0000000..438d7b2 --- /dev/null +++ b/src/lua/cURL/utils.lua @@ -0,0 +1,69 @@ +--- Returns path to cURL ca bundle +-- +-- @tparam[opt="curl-ca-bundle.crt"] string name name of bundle +-- @treturn string path to file (CURLOPT_CAINFO) +-- @treturn string path to ssl dir path (CURLOPT_CAPATH) +-- +-- @usage +-- local file, path = find_ca_bundle() +-- if file then e:setopt_cainfo(file) end +-- if path then e:setopt_capath(path) end +-- +local function find_ca_bundle(name) + name = name or "curl-ca-bundle.crt" + + local path = require "path" + local env = setmetatable({},{__index = function(_, name) return os.getenv(name) end}) + + local function split(str, sep, plain) + local b, res = 1, {} + while b <= #str do + local e, e2 = string.find(str, sep, b, plain) + if e then + table.insert(res, (string.sub(str, b, e-1))) + b = e2 + 1 + else + table.insert(res, (string.sub(str, b))) + break + end + end + return res + end + + if env.CURL_CA_BUNDLE and path.isfile(env.CURL_CA_BUNDLE) then + return env.CURL_CA_BUNDLE + end + + if env.SSL_CERT_DIR and path.isdir(env.SSL_CERT_DIR) then + return false, env.SSL_CERT_DIR + end + + if env.SSL_CERT_FILE and path.isfile(env.SSL_CERT_FILE) then + return env.SSL_CERT_FILE + end + + if not path.IS_WINDOWS then return end + + local paths = { + '.', + path.join(env.windir, "System32"), + path.join(env.windir, "SysWOW64"), + env.windir, + } + for _, p in ipairs(split(env.path, ';')) do paths[#paths + 1] = p end + + for _, p in ipairs(paths) do + p = path.fullpath(p) + if path.isdir(p) then + p = path.join(p, name) + if path.isfile(p) then + return p + end + end + end +end + +return { + find_ca_bundle = find_ca_bundle; +} +