Go to file
Alexey Melnichuk a50ffe9997 Reorganize examples tree. 2014-09-10 15:32:04 +05:00
.travis Add. Travis files 2014-08-26 12:40:18 +05:00
doc Update doc [ci skip] 2014-09-05 16:23:32 +05:00
examples Reorganize examples tree. 2014-09-10 15:32:04 +05:00
msvc Implement `setopt_proxytype` in Lua-cURL interface. 2014-08-29 15:06:36 +05:00
rockspecs Add. `cURL.safe` module. 2014-09-10 13:13:44 +05:00
src Change. multi iterator returns response code as data for `done` row 2014-09-10 15:20:58 +05:00
test Speedup test. 2014-09-10 13:21:28 +05:00
.config Makefile improvements 2014-09-10 00:35:34 +07:00
.gitignore Update gitignore 2014-08-29 14:02:45 +05:00
.travis.yml Fix. rockspec name in travis file 2014-09-10 12:44:03 +05:00
LICENSE Initial commit 2014-08-25 14:00:15 +05:00
Makefile Makefile improvements 2014-09-10 00:35:34 +07:00
README.md Speedup test. 2014-09-10 13:21:28 +05:00
lakeconfig.lua Add. lakefile 2014-08-28 14:52:46 +05:00
lakefile Change. multi iterator returns response code as data for `done` row 2014-09-10 15:20:58 +05:00

README.md

Lua binding to libcurl

Build Status Coverage Status Licence

##Status

This module include three layer

  1. lcurl module provide low level pure C binding to libcurl.
    Almost ready and needs tests. I have no plans to change this API.

  2. cURL module provide compatibility for Lua-cURLv2 API.
    Almost ready and needs tests.

  3. cURL module provide new high level API.
    In fact for now it provide lcurl API directly and needed to redesign.

Documentation

lcurl API
Lua-cURLv2 API
Lua-cURLv3 API - TODO

Lua-cURLv2 binding has several problems:

  • it can not return error codes but just raise Lua errors
  • it raise Lua error from callback that may result resource leak in libcurl
  • it does not provide building multipart/formdata explicitly
  • it has memory leak when send multipart/formdata
  • it does not save string for curl options that may result crush in libcurl
  • there no way to get result for operations in multi interface (e.g. if one of easy operation fail you can not get result code/error message)
  • you can not use multi interface for upload operation (?)
  • you can not use your own callback function to perform operation with multi interface
  • you can not pass your context to callback functions

Installation

luarocks install lua-curl --server=https://rocks.moonscript.org/dev

Usage

-- HTTP Get
curl.easy()
  :setopt_url('http://httpbin.org/get')
  :setopt_httpheader{
    "X-Test-Header1: Header-Data1",
    "X-Test-Header2: Header-Data2",
  }
  :setopt_writefunction(io.stderr) -- use io.stderr:write()
  :perform()
:close()
-- HTTP Post
curl.easy()
  :setopt_url('http://posttestserver.com/post.php')
  :setopt_writefunction(io.write)
  :setopt_httppost(curl.form() -- lcurl guarantee that form will be alive
    :add_content("test_content", "some data", {
      "MyHeader: SomeValue"
    })
    :add_buffer("test_file", "filename", "text data", "text/plain", {
      "Description: my file description"
    })
    :add_file("test_file2", "BuildLog.htm", "application/octet-stream", {
      "Description: my file description"
    })
  )
  :perform()
:close()
-- FTP Upload
local function get_bin_by(str,n)
  local pos = 1 - n
  return function()
    pos = pos + n
    return (str:sub(pos,pos+n-1))
  end
end

curl.easy()
  :setopt_url("ftp://moteus:123456@127.0.0.1/test.dat")
  :setopt_upload(true)
  :setopt_readfunction(
    get_bin_by(("0123456789"):rep(4), 9)
  )
  :perform()
:close()
-- Multi FTP Upload

-- We get error E_LOGIN_DENIED for this operation
e1 = curl.easy()
  :setopt_url("ftp://moteus:999999@127.0.0.1/test1.dat")
  :setopt_upload(true)
  :setopt_readfunction(
    function(t) return table.remove(t) end, {"1111", "2222"}
  )

e2 = curl.easy()
  :setopt_url("ftp://moteus:123456@127.0.0.1/test2.dat")
  :setopt_upload(true)
  :setopt_readfunction(get_bin_by(("e"):rep(1000), 5))

m = curl.multi()
m:add_handle(e1)
m:add_handle(e2)

while m:perform() > 0 do m:wait() end

while true do
  h, ok, err = m:info_read()
  if h == 0 then break end

  if h == e1 then 
    assert(ok == nil)
    assert(err:name() == "LOGIN_DENIED")
    assert(err:no() == curl.E_LOGIN_DENIED)
  end

  if h == e2 then 
    assert(ok == true)
  end
end