Implement basic multi iterface.
This commit is contained in:
parent
bf72021579
commit
d18fb3adca
39
README.md
39
README.md
@ -56,6 +56,43 @@ curl:easy()
|
||||
)
|
||||
:perform()
|
||||
:close()
|
||||
|
||||
```
|
||||
|
||||
```Lua
|
||||
-- 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 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
|
||||
```
|
||||
|
||||
|
@ -183,7 +183,7 @@ function setopt_writefunction() end
|
||||
|
||||
--- Set writer function.
|
||||
--
|
||||
-- This call same as easy:set_writefunction(writer.write, writer)
|
||||
-- This call same as easy:setopt_writefunction(writer.write, writer)
|
||||
--
|
||||
-- @tparam object writer
|
||||
-- @return[1] self
|
||||
@ -205,7 +205,7 @@ function setopt_headerfunction() end
|
||||
|
||||
--- Set header function.
|
||||
--
|
||||
-- This call same as easy:set_headerfunction(writer.header, writer)
|
||||
-- This call same as easy:setopt_headerfunction(writer.header, writer)
|
||||
--
|
||||
-- @tparam object writer
|
||||
-- @return[1] self
|
||||
@ -228,7 +228,7 @@ function setopt_readfunction() end
|
||||
|
||||
--- Set reader function.
|
||||
--
|
||||
-- This call same as easy:set_readfunction(reader.read, reader)
|
||||
-- This call same as easy:setopt_readfunction(reader.read, reader)
|
||||
--
|
||||
-- @tparam object reader
|
||||
-- @return[1] self
|
||||
@ -252,17 +252,19 @@ function setopt_readfunction() end
|
||||
--
|
||||
function setopt_progressfunction() end
|
||||
|
||||
--- Set reader function.
|
||||
--- Set progress function.
|
||||
--
|
||||
-- This call same as easy:set_readfunction(reader.read, reader)
|
||||
-- This call same as easy:setopt_progressfunction(progress.progress, progress)
|
||||
--
|
||||
-- @tparam object reader
|
||||
-- @tparam object progress
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_readfunction() end
|
||||
function setopt_progressfunction() end
|
||||
|
||||
--- Set HTTP multipart/formdata
|
||||
--
|
||||
-- Caller does not have to save data.
|
||||
--
|
||||
-- @tparam httpform data
|
||||
-- @return[1] self
|
||||
function setopt_httpform() end
|
||||
@ -281,8 +283,37 @@ end
|
||||
--
|
||||
do
|
||||
|
||||
--- End multi session
|
||||
--
|
||||
--- Add Easy object.
|
||||
--
|
||||
-- Caller must ensure that easy object is alive until end of operation.
|
||||
--
|
||||
-- @treturn multi self
|
||||
-- @tparam easy handle
|
||||
function add_handle() end
|
||||
|
||||
--- Remove Easy object.
|
||||
--
|
||||
-- @tparam easy handle
|
||||
-- @treturn multi self
|
||||
function remove_handle() end
|
||||
|
||||
--- reads/writes available data from each easy handle.
|
||||
--
|
||||
-- @treturn number handles number of active easy handles
|
||||
function perfom() end
|
||||
|
||||
--- Read multi stack informationals.
|
||||
--
|
||||
-- @treturn[1] number 0 there no informationals
|
||||
-- @treturn[2] easy handle
|
||||
-- @treturn[2] boolean true
|
||||
-- @treturn[3] easy handle
|
||||
-- @treturn[3] nil
|
||||
-- @treturn[3] error error code
|
||||
function info_read() end
|
||||
|
||||
--- End multi session.
|
||||
--
|
||||
function close() end
|
||||
|
||||
end
|
||||
|
@ -15,6 +15,9 @@ int lcurl_multi_create(lua_State *L, int error_mode){
|
||||
lcurl_multi_t *p = lutil_newudatap(L, lcurl_multi_t, LCURL_MULTI);
|
||||
p->curl = curl_multi_init();
|
||||
if(!p->curl) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_MULTI, CURLM_INTERNAL_ERROR);
|
||||
p->err_mode = error_mode;
|
||||
lcurl_util_new_weak_table(L, "v");
|
||||
p->h_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -32,15 +35,89 @@ static int lcurl_multi_cleanup(lua_State *L){
|
||||
p->curl = NULL;
|
||||
}
|
||||
|
||||
if(p->h_ref != LUA_NOREF){
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->h_ref);
|
||||
p->h_ref = LUA_NOREF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcurl_multi_add_handle(lua_State *L){
|
||||
lcurl_multi_t *p = lcurl_getmulti(L);
|
||||
lcurl_easy_t *e = lcurl_geteasy_at(L, 2);
|
||||
CURLMcode code = curl_multi_add_handle(p->curl, e->curl);
|
||||
if(code != CURLM_OK){
|
||||
lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_MULTI, code);
|
||||
}
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->h_ref);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_rawsetp(L, -2, e->curl);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lcurl_multi_remove_handle(lua_State *L){
|
||||
lcurl_multi_t *p = lcurl_getmulti(L);
|
||||
lcurl_easy_t *e = lcurl_geteasy_at(L, 2);
|
||||
CURLMcode code = curl_multi_remove_handle(p->curl, e->curl);
|
||||
if(code != CURLM_OK){
|
||||
lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_MULTI, code);
|
||||
}
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->h_ref);
|
||||
lua_pushnil(L);
|
||||
lua_rawsetp(L, -2, e->curl);
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lcurl_multi_perform(lua_State *L){
|
||||
lcurl_multi_t *p = lcurl_getmulti(L);
|
||||
int running_handles = 0;
|
||||
CURLMcode code = curl_multi_perform(p->curl, &running_handles);
|
||||
if(code != CURLM_OK){
|
||||
lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_MULTI, code);
|
||||
}
|
||||
lua_pushnumber(L, running_handles);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lcurl_multi_info_read(lua_State *L){
|
||||
lcurl_multi_t *p = lcurl_getmulti(L);
|
||||
int msgs_in_queue = 0;
|
||||
CURLMsg *msg = curl_multi_info_read(p->curl, &msgs_in_queue);
|
||||
lcurl_easy_t *e;
|
||||
if(!msg){
|
||||
lua_pushnumber(L, msgs_in_queue);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(msg->msg == CURLMSG_DONE){
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->h_ref);
|
||||
lua_rawgetp(L, -1, msg->easy_handle);
|
||||
e = lcurl_geteasy_at(L, -1);
|
||||
if(msg->data.result == CURLE_OK){
|
||||
lua_pushboolean(L, 1);
|
||||
return 2;
|
||||
}
|
||||
return 1 + lcurl_fail_ex(L, LCURL_ERROR_RETURN, LCURL_ERROR_EASY, msg->data.result);
|
||||
}
|
||||
|
||||
// @todo handle unknown message
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//}
|
||||
|
||||
static const struct luaL_Reg lcurl_multi_methods[] = {
|
||||
{"close", lcurl_multi_cleanup },
|
||||
{"__gc", lcurl_multi_cleanup },
|
||||
{"add_handle", lcurl_multi_add_handle },
|
||||
{"remove_handle", lcurl_multi_remove_handle },
|
||||
{"perform", lcurl_multi_perform },
|
||||
{"info_read", lcurl_multi_info_read },
|
||||
|
||||
{"close", lcurl_multi_cleanup },
|
||||
{"__gc", lcurl_multi_cleanup },
|
||||
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
@ -7,6 +7,7 @@
|
||||
typedef struct lcurl_multi_tag{
|
||||
CURLM *curl;
|
||||
int err_mode;
|
||||
int h_ref;
|
||||
}lcurl_multi_t;
|
||||
|
||||
int lcurl_multi_create(lua_State *L, int error_mode);
|
||||
|
@ -116,3 +116,13 @@ int lcurl_util_push_cb(lua_State *L, lcurl_callback_t *c){
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lcurl_util_new_weak_table(lua_State*L, const char *mode){
|
||||
int top = lua_gettop(L);
|
||||
lua_newtable(L);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, mode);
|
||||
lua_setfield(L, -2, "__mode");
|
||||
lua_setmetatable(L,-2);
|
||||
assert((top+1) == lua_gettop(L));
|
||||
return 1;
|
||||
}
|
||||
|
@ -38,4 +38,6 @@ void lcurl_util_set_const(lua_State *L, const lcurl_const_t *reg);
|
||||
|
||||
int lcurl_util_push_cb(lua_State *L, lcurl_callback_t *c);
|
||||
|
||||
int lcurl_util_new_weak_table(lua_State*L, const char *mode);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user