Add. Support streams to Lua-cURL interface. (See #1)
parent
bb4ed6d1fc
commit
955e6b7ece
|
@ -0,0 +1,47 @@
|
|||
local cURL = require("lcurl.cURL")
|
||||
|
||||
c = cURL.easy_init()
|
||||
|
||||
c:setopt_url("http://posttestserver.com/post.php")
|
||||
|
||||
c:setopt_post(true)
|
||||
|
||||
c:post{-- post file from private read function
|
||||
-- Lua-cURL compatiable
|
||||
-- allows only one stream
|
||||
name = {
|
||||
file="stream.txt",
|
||||
stream_length="5",
|
||||
type="text/plain",
|
||||
}
|
||||
}
|
||||
|
||||
count = 0
|
||||
c:perform{readfunction = function(n)
|
||||
if count < 5 then
|
||||
count = 5
|
||||
return "stream"
|
||||
end
|
||||
return nil
|
||||
end}
|
||||
|
||||
c:post{-- post file from private read function
|
||||
-- define stream callback
|
||||
name = {
|
||||
file = "stream.txt",
|
||||
type = "text/plain",
|
||||
stream_length = 5,
|
||||
stream = function()
|
||||
if count < 5 then
|
||||
count = 5
|
||||
return "STREAM"
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
}
|
||||
}
|
||||
|
||||
count = 0
|
||||
c:perform{}
|
||||
|
||||
print("Done")
|
18
src/lceasy.c
18
src/lceasy.c
|
@ -593,9 +593,16 @@ static int lcurl_easy_set_callback(lua_State *L,
|
|||
const char *method, void *func
|
||||
)
|
||||
{
|
||||
CURLcode code;
|
||||
lcurl_set_callback(L, c, 2, method);
|
||||
|
||||
curl_easy_setopt(p->curl, OPT_CB, (c->cb_ref == LUA_NOREF)?0:func);
|
||||
code = curl_easy_setopt(p->curl, OPT_CB, (c->cb_ref == LUA_NOREF)?0:func);
|
||||
if((code != CURLE_OK)&&(c->cb_ref != LUA_NOREF)){
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, c->cb_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, c->ud_ref);
|
||||
c->cb_ref = c->ud_ref = LUA_NOREF;
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
curl_easy_setopt(p->curl, OPT_UD, (c->cb_ref == LUA_NOREF)?0:p);
|
||||
|
||||
return 1;
|
||||
|
@ -605,7 +612,6 @@ static size_t lcurl_write_callback_(lua_State*L,
|
|||
lcurl_easy_t *p, lcurl_callback_t *c,
|
||||
char *ptr, size_t size, size_t nmemb
|
||||
){
|
||||
|
||||
size_t ret = size * nmemb;
|
||||
int top = lua_gettop(L);
|
||||
int n = lcurl_util_push_cb(L, c);
|
||||
|
@ -946,6 +952,14 @@ static const lcurl_const_t lcurl_easy_opt[] = {
|
|||
};
|
||||
|
||||
void lcurl_easy_initlib(lua_State *L, int nup){
|
||||
|
||||
/* Hack. We ensure that lcurl_easy_t and lcurl_hpost_stream_t
|
||||
compatiable for readfunction
|
||||
*/
|
||||
LCURL_STATIC_ASSERT(offsetof(lcurl_easy_t, L) == offsetof(lcurl_hpost_stream_t, L));
|
||||
LCURL_STATIC_ASSERT(offsetof(lcurl_easy_t, rd) == offsetof(lcurl_hpost_stream_t, rd));
|
||||
LCURL_STATIC_ASSERT(offsetof(lcurl_easy_t, rbuffer) == offsetof(lcurl_hpost_stream_t, rbuffer));
|
||||
|
||||
if(!lutil_createmetap(L, LCURL_EASY, lcurl_easy_methods, nup))
|
||||
lua_pop(L, nup);
|
||||
lua_pop(L, 1);
|
||||
|
|
|
@ -24,16 +24,16 @@ enum {
|
|||
|
||||
typedef struct lcurl_easy_tag{
|
||||
lua_State *L;
|
||||
lcurl_callback_t rd;
|
||||
lcurl_read_buffer_t rbuffer;
|
||||
|
||||
CURL *curl;
|
||||
int storage;
|
||||
int lists[LCURL_LIST_COUNT];
|
||||
int err_mode;
|
||||
lcurl_callback_t wr;
|
||||
lcurl_callback_t rd;
|
||||
lcurl_callback_t hd;
|
||||
lcurl_callback_t pr;
|
||||
lcurl_read_buffer_t rbuffer;
|
||||
|
||||
}lcurl_easy_t;
|
||||
|
||||
int lcurl_easy_create(lua_State *L, int error_mode);
|
||||
|
|
|
@ -237,6 +237,10 @@ static int lcurl_hpost_add_stream(lua_State *L){
|
|||
else if(!fname) fname = luaL_checkstring(L, i);
|
||||
else if(!type) type = luaL_checkstring(L, i);
|
||||
else{
|
||||
if(lua_isnil(L, i) && (!ilist)){
|
||||
++i; // empty headers
|
||||
break;
|
||||
}
|
||||
lua_pushliteral(L, "stream size required");
|
||||
lua_error(L);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#define LCURL_MAKE_VERSION(MIN, MAJ, PAT) ((MIN<<16) + (MAJ<<8) + PAT)
|
||||
#define LCURL_CURL_VER_GE(MIN, MAJ, PAT) (LIBCURL_VERSION_NUM >= LCURL_MAKE_VERSION(MIN, MAJ, PAT))
|
||||
|
||||
#define LCURL_STATIC_ASSERT(A) {(int(*)[(A)?1:0])0;}
|
||||
|
||||
typedef struct lcurl_const_tag{
|
||||
const char *name;
|
||||
int value;
|
||||
|
|
|
@ -52,29 +52,57 @@ end
|
|||
|
||||
local perform = wrap_function("perform")
|
||||
local setopt_share = wrap_function("setopt_share")
|
||||
local setopt_readfunction = wrap_function("setopt_readfunction")
|
||||
|
||||
local NONE = {}
|
||||
|
||||
function Easy:_call_readfunction(...)
|
||||
if self._rd_ud == NONE then
|
||||
return self._rd_fn(...)
|
||||
end
|
||||
return self._rd_fn(self._rd_ud, ...)
|
||||
end
|
||||
|
||||
function Easy:setopt_readfunction(fn, ...)
|
||||
assert(fn)
|
||||
|
||||
if select('#', ...) == 0 then
|
||||
if type(fn) == "function" then
|
||||
self._rd_fn = fn
|
||||
self._rd_ud = NONE
|
||||
else
|
||||
self._rd_fn = assert(fn.read)
|
||||
self._rd_ud = fn
|
||||
end
|
||||
else
|
||||
self._rd_fn = fn
|
||||
self._ud_fn = ...
|
||||
end
|
||||
|
||||
return setopt_readfunction(self, fn, ...)
|
||||
end
|
||||
|
||||
function Easy:perform(opt)
|
||||
local e = self:handle()
|
||||
|
||||
local oerror = opt.errorfunction or function(err) return nil, err end
|
||||
|
||||
if opt.readfunction then
|
||||
local ok, err = e:setopt_readfunction(opt.readfunction)
|
||||
local ok, err = self:setopt_readfunction(opt.readfunction)
|
||||
if not ok then return oerror(err) end
|
||||
end
|
||||
|
||||
if opt.writefunction then
|
||||
local ok, err = e:setopt_writefunction(opt.writefunction)
|
||||
local ok, err = self:setopt_writefunction(opt.writefunction)
|
||||
if not ok then return oerror(err) end
|
||||
end
|
||||
|
||||
if opt.headerfunction then
|
||||
local ok, err = e:setopt_headerfunction(opt.headerfunction)
|
||||
local ok, err = self:setopt_headerfunction(opt.headerfunction)
|
||||
if not ok then return oerror(err) end
|
||||
end
|
||||
|
||||
local ok, err = perform(self)
|
||||
if ok then return oerror(err) end
|
||||
if not ok then return oerror(err) end
|
||||
|
||||
return self
|
||||
end
|
||||
|
@ -89,13 +117,17 @@ function Easy:post(data)
|
|||
else
|
||||
assert(type(v) == "table")
|
||||
if v.stream_length then
|
||||
form:free()
|
||||
error("Stream does not support")
|
||||
end
|
||||
if v.data then
|
||||
local len = assert(tonumber(v.stream_length))
|
||||
assert(v.file)
|
||||
if v.stream then
|
||||
ok, err = form:add_stream(k, v.file, v.type, v.headers, len, v.stream)
|
||||
else
|
||||
ok, err = form:add_stream(k, v.file, v.type, v.headers, len, self._call_readfunction, self)
|
||||
end
|
||||
elseif v.data then
|
||||
ok, err = form:add_buffer(k, v.file, v.data, v.type, v.headers)
|
||||
else
|
||||
ok, err = form:add_file(k, v.file, v.data, v.type, v.filename, v.headers)
|
||||
ok, err = form:add_file(k, v.file, v.type, v.filename, v.headers)
|
||||
end
|
||||
end
|
||||
if not ok then break end
|
||||
|
@ -106,7 +138,7 @@ function Easy:post(data)
|
|||
return nil, err
|
||||
end
|
||||
|
||||
ok, err = e:setopt_httppost(form)
|
||||
ok, err = self:setopt_httppost(form)
|
||||
if not ok then
|
||||
form:free()
|
||||
return nil, err
|
||||
|
|
Loading…
Reference in New Issue