New project LuaCURL v1.0 is up

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

New project LuaCURL v1.0 is up

Alexander Marinov
LuaCURL is CURL 7.14.0 binding to Lua 5.x
Home Page: http://luacurl.luaforge.net
Download: http://luaforge.net/projects/luacurl/

Here is an example how it works:

require("luacurl")

c=curl.new()

c:setopt(curl.OPT_WRITEFUNCTION, function (stream, buffer)
	if stream:write(buffer) then
		return string.len(buffer);
	end
end);

c:setopt(curl.OPT_WRITEDATA, io.open("lua-5.0.2.tar.gz", "wb"));

c:setopt(curl.OPT_PROGRESSFUNCTION, function (_, dltotal, dlnow, uptotal, upnow)
	print(dltotal, dlnow, uptotal, upnow);
end);

c:setopt(curl.OPT_NOPROGRESS, false);

c:setopt(curl.OPT_HTTPHEADER, "Connection: Keep-Alive", "Accept-Language: en-us");

c:setopt(curl.OPT_URL, "http://www.lua.org/ftp/lua-5.0.2.tar.gz";);
c:setopt(curl.OPT_CONNECTTIMEOUT, 15);
c:perform();
c:close();

Please send me feedback with suggestions how to improve it, bug reports etc.

Best Regards,
alek


_____________________________________________________________
Get your free email at http://www.crazyland.com

Reply | Threaded
Open this post in threaded view
|

Re: New project LuaCURL v1.0 is up

Enrico Tassi-3
On Mon, Jun 27, 2005 at 11:57:47AM -0700, Alexander Marinov wrote:
> LuaCURL is CURL 7.14.0 binding to Lua 5.x
> Home Page: http://luacurl.luaforge.net
> Download: http://luaforge.net/projects/luacurl/

I've already binded curl to LUA for FreePOPs http://www.freepops.org

you can find the sources in the modules/src/curl_lua directory of the
freepops tarball.

I've no time to have a look at your work, but at least one thing you
may copy from my work: no c:close() is needed.

my bindings are not really up to date (may miss som new CURL flags),
but they have been used with different old versions, so the bunch of
#ifdefs to make them compile against old CURL versions may help.

ciao
-- 
Enrico Tassi

Reply | Threaded
Open this post in threaded view
|

Re: New project LuaCURL v1.0 is up

Rici Lake-2
In reply to this post by Alexander Marinov

On 27-Jun-05, at 1:57 PM, Alexander Marinov wrote:

LuaCURL is CURL 7.14.0 binding to Lua 5.x
Home Page: http://luacurl.luaforge.net
Download: http://luaforge.net/projects/luacurl/


Cool!

Here is an example how it works:

require("luacurl")

c=curl.new()

c:setopt(curl.OPT_WRITEFUNCTION, function (stream, buffer)
	if stream:write(buffer) then
		return string.len(buffer);
	end
end);


Just off the top of my head, and without even having looked at your
implementation, I would personally recommend a slightly simpler API:

c:setopt("writefunction", function...
c:setopt("writedata", ..

There is no real point introducing option objects (which I'll
bet end up being integers); you could implement this with a
simple internal table which used the option names as keys
(and I would be tempted to use some sort of functional as
a value, presumably wrapped in a static structure
wrapped in a lightuserdata, since function pointers are
not coercible to void*'s); the functional would then
do whatever argument coercion was necessary, and then
issue the internal setopt.)

Actually, though, there is a good argument for a different type
of binding for the writefunction/writedata options. A more
Lua-like binding would be similar to LuaLDAP, where the perform
function returns a generator (a "future", if you prefer), and
the caller can do whatever they want with the resulting strings.

Consider an API something like this:

function geturl(url)
  local c = curl.new():setopt("url", url)
                      :setopt("connecttimeout", 15)

  local chunks = {}
  for chunk in c:perform() do
    table.insert(chunks, chunk)
  end
  if c:error() then
    -- handle the error
   else
    c:close()
    return table.concat(chunks)
  end
end

or

function saveurl(url, filename, progfn)
  local c = curl.new():setopt("url", url)
                      :setopt("connecttimeout", 15)
  if progfn then
    c:setopt("progressfunction", progfn)
  end
  c:setopt("noprogress", not progfn)

  local f = io.open(filename, "w")
  for chunk in c:perform() do
    f:write(chunk)
  end
  if c:error() then
    -- handle the error
    -- somehow delete the file
   else
    f:close()
  end
  c:close()
end

(The : trick only requires setopt to return self. I personally
like the style but others may disagree. Another approach to
the multitude of options would be to model them as a pseudo-table,
allowing both read and write access.)

c:perform();
c:close();

I presume the garbage collector would take care of closing?

Please send me feedback with suggestions how to improve it, bug reports etc.

Thanks, again. Looks like it will be very useful.


Reply | Threaded
Open this post in threaded view
|

Re: New project LuaCURL v1.0 is up

Enrico Tassi-3
In reply to this post by Alexander Marinov
forgot to link the doc
http://www.freepops.org/files/html_lua/curl_lua_luadoc.html

ciao
-- 
Enrico Tassi

Reply | Threaded
Open this post in threaded view
|

Re: New project LuaCURL v1.0 is up

Alexander Marinov
In reply to this post by Alexander Marinov
Hi, Rici

I guess you are Lua certified, aren't you :P
just a joke! :)

>c:setopt("writefunction", function...
>c:setopt("writedata", ..

>local c = curl.new():setopt("url", url)
>                       :setopt("connecttimeout", 15)

I got your point, also what do you think about
c["writefunction"]=function..
or the sugar c.writefunction=function..

and guess how could become if c.__newindex returns self!

(((c.writefunction=function...).writedata=...).url=...):perform()

Bad idea : ), also I'm not sure if possible

Anyway, your remark is a good point.

>Actually, though, there is a good argument for a different type
>of binding for the writefunction/writedata options. A more
>Lua-like binding would be similar to LuaLDAP, where the perform
>function returns a generator (a "future", if you prefer), and
>the caller can do whatever they want with the resulting strings.

>   for chunk in c:perform() do
>     table.insert(chunks, chunk)
>   end  


Excellent!
But you know that always when there is a data stream there is a 
problem "who is pushing, who is pulling".
I mean the function returned by c:perform() will "pull" data from curl. But actually curl "push" the data through a callback.

Anyway, this is another good point to think about

> c:perform();
> c:close();
>I presume the garbage collector would take care of closing?
sure

>Thanks, again. Looks like it will be very useful.

I thanks for the good remarks.


_____________________________________________________________
Get your free email at http://www.crazyland.com

Reply | Threaded
Open this post in threaded view
|

Re: New project LuaCURL v1.0 is up

Lloyd Zusman
In reply to this post by Alexander Marinov
Alexander Marinov <alek <at> crazyland.com> writes:

> 
> LuaCURL is CURL 7.14.0 binding to Lua 5.x
>
> [ ... ]
> 
> Here is an example how it works:
>
> [ ... ]
> 
> c:setopt(curl.OPT_PROGRESSFUNCTION, function (_, dltotal, dlnow, uptotal, 
>                                     upnow)
> 	print(dltotal, dlnow, uptotal, upnow);
> end);
> 
> c:setopt(curl.OPT_NOPROGRESS, false);
>
> [ ... ]

This is great!

I have a question, however:  when will OPT_PROGRESSFUNCTION get implemented?
The pertinent section of source code from the latest tarball looks like
this:

        case CURLOPT_PROGRESSFUNCTION:{
                L_error(L,"Not implemented");
	}break;

I could take a stab at it, but before I do, I'm wondering if someone is
already working on adding this.

Thanks in advance.