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
|
const char *method, void *func
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
CURLcode code;
|
||||||
lcurl_set_callback(L, c, 2, method);
|
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);
|
curl_easy_setopt(p->curl, OPT_UD, (c->cb_ref == LUA_NOREF)?0:p);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -605,7 +612,6 @@ static size_t lcurl_write_callback_(lua_State*L,
|
||||||
lcurl_easy_t *p, lcurl_callback_t *c,
|
lcurl_easy_t *p, lcurl_callback_t *c,
|
||||||
char *ptr, size_t size, size_t nmemb
|
char *ptr, size_t size, size_t nmemb
|
||||||
){
|
){
|
||||||
|
|
||||||
size_t ret = size * nmemb;
|
size_t ret = size * nmemb;
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
int n = lcurl_util_push_cb(L, c);
|
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){
|
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))
|
if(!lutil_createmetap(L, LCURL_EASY, lcurl_easy_methods, nup))
|
||||||
lua_pop(L, nup);
|
lua_pop(L, nup);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
|
@ -24,16 +24,16 @@ enum {
|
||||||
|
|
||||||
typedef struct lcurl_easy_tag{
|
typedef struct lcurl_easy_tag{
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
|
lcurl_callback_t rd;
|
||||||
|
lcurl_read_buffer_t rbuffer;
|
||||||
|
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
int storage;
|
int storage;
|
||||||
int lists[LCURL_LIST_COUNT];
|
int lists[LCURL_LIST_COUNT];
|
||||||
int err_mode;
|
int err_mode;
|
||||||
lcurl_callback_t wr;
|
lcurl_callback_t wr;
|
||||||
lcurl_callback_t rd;
|
|
||||||
lcurl_callback_t hd;
|
lcurl_callback_t hd;
|
||||||
lcurl_callback_t pr;
|
lcurl_callback_t pr;
|
||||||
lcurl_read_buffer_t rbuffer;
|
|
||||||
|
|
||||||
}lcurl_easy_t;
|
}lcurl_easy_t;
|
||||||
|
|
||||||
int lcurl_easy_create(lua_State *L, int error_mode);
|
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(!fname) fname = luaL_checkstring(L, i);
|
||||||
else if(!type) type = luaL_checkstring(L, i);
|
else if(!type) type = luaL_checkstring(L, i);
|
||||||
else{
|
else{
|
||||||
|
if(lua_isnil(L, i) && (!ilist)){
|
||||||
|
++i; // empty headers
|
||||||
|
break;
|
||||||
|
}
|
||||||
lua_pushliteral(L, "stream size required");
|
lua_pushliteral(L, "stream size required");
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#define LCURL_MAKE_VERSION(MIN, MAJ, PAT) ((MIN<<16) + (MAJ<<8) + PAT)
|
#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_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{
|
typedef struct lcurl_const_tag{
|
||||||
const char *name;
|
const char *name;
|
||||||
int value;
|
int value;
|
||||||
|
|
|
@ -52,29 +52,57 @@ end
|
||||||
|
|
||||||
local perform = wrap_function("perform")
|
local perform = wrap_function("perform")
|
||||||
local setopt_share = wrap_function("setopt_share")
|
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)
|
function Easy:perform(opt)
|
||||||
local e = self:handle()
|
|
||||||
|
|
||||||
local oerror = opt.errorfunction or function(err) return nil, err end
|
local oerror = opt.errorfunction or function(err) return nil, err end
|
||||||
|
|
||||||
if opt.readfunction then
|
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
|
if not ok then return oerror(err) end
|
||||||
end
|
end
|
||||||
|
|
||||||
if opt.writefunction then
|
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
|
if not ok then return oerror(err) end
|
||||||
end
|
end
|
||||||
|
|
||||||
if opt.headerfunction then
|
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
|
if not ok then return oerror(err) end
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok, err = perform(self)
|
local ok, err = perform(self)
|
||||||
if ok then return oerror(err) end
|
if not ok then return oerror(err) end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
@ -89,13 +117,17 @@ function Easy:post(data)
|
||||||
else
|
else
|
||||||
assert(type(v) == "table")
|
assert(type(v) == "table")
|
||||||
if v.stream_length then
|
if v.stream_length then
|
||||||
form:free()
|
local len = assert(tonumber(v.stream_length))
|
||||||
error("Stream does not support")
|
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
|
end
|
||||||
if v.data then
|
elseif v.data then
|
||||||
ok, err = form:add_buffer(k, v.file, v.data, v.type, v.headers)
|
ok, err = form:add_buffer(k, v.file, v.data, v.type, v.headers)
|
||||||
else
|
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
|
||||||
end
|
end
|
||||||
if not ok then break end
|
if not ok then break end
|
||||||
|
@ -106,7 +138,7 @@ function Easy:post(data)
|
||||||
return nil, err
|
return nil, err
|
||||||
end
|
end
|
||||||
|
|
||||||
ok, err = e:setopt_httppost(form)
|
ok, err = self:setopt_httppost(form)
|
||||||
if not ok then
|
if not ok then
|
||||||
form:free()
|
form:free()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue