Merge branch 'master' of https://github.com/moteus/lua-lcurl
This commit is contained in:
commit
2870203eec
@ -9,16 +9,26 @@ function form() end
|
||||
|
||||
--- Create Easy object
|
||||
--
|
||||
-- @tparam[opt] table options
|
||||
-- @treturn[1] easy new curl easy object
|
||||
--
|
||||
-- @usage
|
||||
-- c = curl.easy{
|
||||
-- url = 'http://example.com',
|
||||
-- [curl.OPT_VERBOSE] = true,
|
||||
-- }
|
||||
--
|
||||
function easy() end
|
||||
|
||||
--- Create Multi object
|
||||
--
|
||||
-- @tparam[opt] table options
|
||||
-- @treturn[1] multi new curl multi object
|
||||
function multi() end
|
||||
|
||||
--- Create Share object
|
||||
--
|
||||
-- @tparam[opt] table options
|
||||
-- @treturn[1] share new curl share object
|
||||
function share() end
|
||||
|
||||
@ -187,7 +197,7 @@ function close() end
|
||||
|
||||
--- Set options.
|
||||
--
|
||||
-- @tparam number opt one of `curl.OPT_XXX` constant
|
||||
-- @tparam number|table opt one of `curl.OPT_XXX` constant or options table
|
||||
-- @param ... value
|
||||
-- @treturn easy self
|
||||
--
|
||||
@ -197,6 +207,10 @@ function close() end
|
||||
-- function(t, n) return table.remove(t) end,
|
||||
-- {"1111", "2222"}
|
||||
-- )
|
||||
--c:setopt{
|
||||
-- url = 'http://example.com',
|
||||
-- [curl.OPT_VERBOSE] = true,
|
||||
-- }
|
||||
function setopt() end
|
||||
|
||||
--- Get information.
|
||||
@ -214,7 +228,7 @@ function getinfo() end
|
||||
--
|
||||
-- A callback accepting one or two parameters.
|
||||
-- The first is the writer context if any, and the second is a string with the data to be written.
|
||||
-- Function must return `true` or full data length or nothing to continue operation.
|
||||
-- Function must return `true` (any non number true value) or full data length or nothing to continue operation.
|
||||
-- Otherwise the transfer will be aborted with an error.
|
||||
--
|
||||
-- @tparam function writer
|
||||
@ -236,7 +250,7 @@ function setopt_writefunction() end
|
||||
--
|
||||
-- A callback accepting one or two parameters.
|
||||
-- The first is the writer context if any, and the second is a string with the data to be written.
|
||||
-- Function must return `true` or full data length or nothing to continue operation.
|
||||
-- Function must return `true` (any non number true value) or full data length or nothing to continue operation.
|
||||
-- Otherwise the transfer will be aborted with an error.
|
||||
--
|
||||
-- @tparam function writer
|
||||
@ -367,12 +381,13 @@ function info_read() end
|
||||
|
||||
--- Set options.
|
||||
--
|
||||
-- @tparam number opt one of `curl.OPT_MULTI_XXX` constant
|
||||
-- @tparam number|table opt one of `curl.OPT_MULTI_XXX` constant
|
||||
-- @param ... value
|
||||
-- @treturn multi self
|
||||
--
|
||||
-- @usage
|
||||
-- c:setopt(curl.OPT_MULTI_MAXCONNECTS, 10)
|
||||
-- c:setopt{maxconnects = 10}
|
||||
function setopt() end
|
||||
|
||||
--- Set timer callback.
|
||||
@ -418,12 +433,13 @@ do
|
||||
|
||||
--- Set options.
|
||||
--
|
||||
-- @tparam number opt one of `curl.OPT_SHARE_XXX` constant
|
||||
-- @tparam number|table opt one of `curl.OPT_SHARE_XXX` constant
|
||||
-- @param ... value
|
||||
-- @treturn share self
|
||||
--
|
||||
-- @usage
|
||||
-- c:setopt(curl.OPT_SHARE_SHARE, curl.LOCK_DATA_COOKIE)
|
||||
-- c:setopt{share = curl.LOCK_DATA_COOKIE}
|
||||
function setopt() end
|
||||
|
||||
--- End share session.
|
||||
|
63
src/lceasy.c
63
src/lceasy.c
@ -11,12 +11,24 @@ static const char *LCURL_ERROR_TAG = "LCURL_ERROR_TAG";
|
||||
#define LCURL_EASY_NAME LCURL_PREFIX" Easy"
|
||||
static const char *LCURL_EASY = LCURL_EASY_NAME;
|
||||
|
||||
#if LCURL_CURL_VER_GE(7,21,5)
|
||||
# define LCURL_E_UNKNOWN_OPTION CURLE_UNKNOWN_OPTION
|
||||
#else
|
||||
# define LCURL_E_UNKNOWN_OPTION CURLE_UNKNOWN_TELNET_OPTION
|
||||
#endif
|
||||
|
||||
//{
|
||||
|
||||
int lcurl_easy_create(lua_State *L, int error_mode){
|
||||
lcurl_easy_t *p = lutil_newudatap(L, lcurl_easy_t, LCURL_EASY);
|
||||
lcurl_easy_t *p;
|
||||
int i;
|
||||
|
||||
lua_settop(L, 1); /* options */
|
||||
|
||||
p = lutil_newudatap(L, lcurl_easy_t, LCURL_EASY);
|
||||
|
||||
p->curl = curl_easy_init();
|
||||
|
||||
p->err_mode = error_mode;
|
||||
if(!p->curl) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, CURLE_FAILED_INIT);
|
||||
p->L = L;
|
||||
@ -29,6 +41,13 @@ int lcurl_easy_create(lua_State *L, int error_mode){
|
||||
for(i = 0; i < LCURL_LIST_COUNT; ++i){
|
||||
p->lists[i] = LUA_NOREF;
|
||||
}
|
||||
|
||||
if(lua_type(L, 1) == LUA_TTABLE){
|
||||
int ret = lcurl_utils_apply_options(L, 1, 2, 1, p->err_mode, LCURL_ERROR_EASY, LCURL_E_UNKNOWN_OPTION);
|
||||
if(ret) return ret;
|
||||
assert(lua_gettop(L) == 2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -182,7 +201,7 @@ static int lcurl_opt_set_string_(lua_State *L, int opt, int store){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
|
||||
if(store)lcurl_storage_preserve_value(L, p->storage, 2);
|
||||
if(store)lcurl_storage_preserve_iv(L, p->storage, opt, 2);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
@ -245,7 +264,7 @@ static int lcurl_easy_set_POSTFIELDS(lua_State *L){
|
||||
if(code != CURLE_OK){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
lcurl_storage_preserve_value(L, p->storage, 2);
|
||||
lcurl_storage_preserve_iv(L, p->storage, CURLOPT_POSTFIELDS, 2);
|
||||
code = curl_easy_setopt(p->curl, CURLOPT_POSTFIELDSIZE, (long)len);
|
||||
if(code != CURLE_OK){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
@ -266,7 +285,7 @@ static int lcurl_easy_set_HTTPPOST(lua_State *L){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
|
||||
lcurl_storage_preserve_value(L, p->storage, 2);
|
||||
lcurl_storage_preserve_iv(L, p->storage, CURLOPT_HTTPPOST, 2);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
@ -280,7 +299,7 @@ static int lcurl_easy_set_SHARE(lua_State *L){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
|
||||
lcurl_storage_preserve_value(L, p->storage, 2);
|
||||
lcurl_storage_preserve_iv(L, p->storage, CURLOPT_SHARE, 2);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
@ -459,10 +478,12 @@ static int lcurl_write_callback_(lua_State*L,
|
||||
|
||||
if(lua_gettop(L) > top){
|
||||
if(lua_isnil(L, top + 1)) return 0;
|
||||
if(lua_isboolean(L, top + 1)){
|
||||
if(lua_isnumber(L, top + 1)){
|
||||
ret = (size_t)lua_tonumber(L, top + 1);
|
||||
}
|
||||
else{
|
||||
if(!lua_toboolean(L, top + 1)) ret = 0;
|
||||
}
|
||||
else ret = (size_t)lua_tonumber(L, top + 1);
|
||||
}
|
||||
|
||||
lua_settop(L, top);
|
||||
@ -642,7 +663,17 @@ static int lcurl_easy_set_PROGRESSFUNCTION(lua_State *L){
|
||||
|
||||
static int lcurl_easy_setopt(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
int opt = luaL_checklong(L, 2);
|
||||
long opt;
|
||||
|
||||
luaL_checkany(L, 2);
|
||||
if(lua_type(L, 2) == LUA_TTABLE){
|
||||
int ret = lcurl_utils_apply_options(L, 2, 1, 0, p->err_mode, LCURL_ERROR_EASY, LCURL_E_UNKNOWN_OPTION);
|
||||
if(ret) return ret;
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
opt = luaL_checklong(L, 2);
|
||||
lua_remove(L, 2);
|
||||
|
||||
#define OPT_ENTRY(l, N, T, S) case CURLOPT_##N: return lcurl_easy_set_##N(L);
|
||||
@ -658,13 +689,7 @@ static int lcurl_easy_setopt(lua_State *L){
|
||||
}
|
||||
#undef OPT_ENTRY
|
||||
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY,
|
||||
#if LCURL_CURL_VER_GE(7,21,5)
|
||||
CURLE_UNKNOWN_OPTION
|
||||
#else
|
||||
CURLE_UNKNOWN_TELNET_OPTION
|
||||
#endif
|
||||
);
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, LCURL_E_UNKNOWN_OPTION);
|
||||
}
|
||||
|
||||
static int lcurl_easy_getinfo(lua_State *L){
|
||||
@ -678,13 +703,7 @@ static int lcurl_easy_getinfo(lua_State *L){
|
||||
}
|
||||
#undef OPT_ENTRY
|
||||
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY,
|
||||
#if LCURL_CURL_VER_GE(7,21,5)
|
||||
CURLE_UNKNOWN_OPTION
|
||||
#else
|
||||
CURLE_UNKNOWN_TELNET_OPTION
|
||||
#endif
|
||||
);
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, LCURL_E_UNKNOWN_OPTION);
|
||||
}
|
||||
|
||||
//}
|
||||
|
@ -21,15 +21,27 @@ static const char *LCURL_ERROR_TAG = "LCURL_ERROR_TAG";
|
||||
static const char *LCURL_MULTI = LCURL_MULTI_NAME;
|
||||
|
||||
//{
|
||||
|
||||
int lcurl_multi_create(lua_State *L, int error_mode){
|
||||
lcurl_multi_t *p = lutil_newudatap(L, lcurl_multi_t, LCURL_MULTI);
|
||||
lcurl_multi_t *p;
|
||||
|
||||
lua_settop(L, 1);
|
||||
|
||||
p = lutil_newudatap(L, lcurl_multi_t, LCURL_MULTI);
|
||||
p->curl = curl_multi_init();
|
||||
p->err_mode = error_mode;
|
||||
if(!p->curl) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_MULTI, CURLM_INTERNAL_ERROR);
|
||||
p->L = L;
|
||||
p->err_mode = error_mode;
|
||||
lcurl_util_new_weak_table(L, "v");
|
||||
p->h_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||
p->tm.cb_ref = p->tm.ud_ref = LUA_NOREF;
|
||||
|
||||
if(lua_type(L, 1) == LUA_TTABLE){
|
||||
int ret = lcurl_utils_apply_options(L, 1, 2, 1, p->err_mode, LCURL_ERROR_MULTI, CURLM_UNKNOWN_OPTION);
|
||||
if(ret) return ret;
|
||||
assert(lua_gettop(L) == 2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -393,7 +405,18 @@ static int lcurl_multi_set_TIMERFUNCTION(lua_State *L){
|
||||
|
||||
static int lcurl_multi_setopt(lua_State *L){
|
||||
lcurl_multi_t *p = lcurl_getmulti(L);
|
||||
int opt = luaL_checklong(L, 2);
|
||||
int opt;
|
||||
|
||||
luaL_checkany(L, 2);
|
||||
|
||||
if(lua_type(L, 2) == LUA_TTABLE){
|
||||
int ret = lcurl_utils_apply_options(L, 2, 1, 0, p->err_mode, LCURL_ERROR_MULTI, CURLM_UNKNOWN_OPTION);
|
||||
if(ret) return ret;
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
opt = luaL_checklong(L, 2);
|
||||
lua_remove(L, 2);
|
||||
|
||||
#define OPT_ENTRY(l, N, T, S) case CURLMOPT_##N: return lcurl_multi_set_##N(L);
|
||||
|
@ -11,11 +11,21 @@ static const char *LCURL_SHARE = LCURL_SHARE_NAME;
|
||||
|
||||
//{
|
||||
int lcurl_share_create(lua_State *L, int error_mode){
|
||||
lcurl_share_t *p = lutil_newudatap(L, lcurl_share_t, LCURL_SHARE);
|
||||
lcurl_share_t *p;
|
||||
|
||||
lua_settop(L, 1);
|
||||
|
||||
p = lutil_newudatap(L, lcurl_share_t, LCURL_SHARE);
|
||||
p->curl = curl_share_init();
|
||||
p->err_mode = error_mode;
|
||||
if(!p->curl) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_SHARE, CURLSHE_NOMEM);
|
||||
|
||||
if(lua_type(L, 1) == LUA_TTABLE){
|
||||
int ret = lcurl_utils_apply_options(L, 1, 2, 1, p->err_mode, LCURL_ERROR_SHARE, CURLSHE_BAD_OPTION);
|
||||
if(ret) return ret;
|
||||
assert(lua_gettop(L) == 2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -70,7 +80,17 @@ static int lcurl_opt_set_long_(lua_State *L, int opt){
|
||||
|
||||
static int lcurl_share_setopt(lua_State *L){
|
||||
lcurl_share_t *p = lcurl_getshare(L);
|
||||
int opt = luaL_checklong(L, 2);
|
||||
int opt;
|
||||
|
||||
luaL_checkany(L, 2);
|
||||
if(lua_type(L, 2) == LUA_TTABLE){
|
||||
int ret = lcurl_utils_apply_options(L, 2, 1, 0, p->err_mode, LCURL_ERROR_SHARE, CURLSHE_BAD_OPTION);
|
||||
if(ret) return ret;
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
opt = luaL_checklong(L, 2);
|
||||
lua_remove(L, 2);
|
||||
|
||||
#define OPT_ENTRY(l, N, T, S) case CURLSHOPT_##N: return lcurl_share_set_##N(L);
|
||||
|
120
src/lcutils.c
120
src/lcutils.c
@ -2,6 +2,9 @@
|
||||
#include "lcutils.h"
|
||||
#include "lcerror.h"
|
||||
|
||||
#define LCURL_STORAGE_SLIST 1
|
||||
#define LCURL_STORAGE_KV 2
|
||||
|
||||
int lcurl_storage_init(lua_State *L){
|
||||
lua_newtable(L);
|
||||
return luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||
@ -15,38 +18,65 @@ void lcurl_storage_preserve_value(lua_State *L, int storage, int i){
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
int lcurl_storage_preserve_slist(lua_State *L, int storage, struct curl_slist * list){
|
||||
int r;
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||
lua_rawgeti(L, -1, 1); // list storage
|
||||
static void lcurl_storage_ensure_t(lua_State *L, int t){
|
||||
lua_rawgeti(L, -1, t);
|
||||
if(!lua_istable(L, -1)){
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawseti(L, -3, 1);
|
||||
lua_rawseti(L, -3, t);
|
||||
}
|
||||
}
|
||||
|
||||
int lcurl_storage_preserve_slist(lua_State *L, int storage, struct curl_slist * list){
|
||||
int r;
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||
lcurl_storage_ensure_t(L, LCURL_STORAGE_SLIST);
|
||||
lua_pushlightuserdata(L, list);
|
||||
r = luaL_ref(L, -2);
|
||||
lua_pop(L, 2);
|
||||
return r;
|
||||
}
|
||||
|
||||
void lcurl_storage_preserve_iv(lua_State *L, int storage, int i, int v){
|
||||
v = lua_absindex(L, v);
|
||||
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||
lcurl_storage_ensure_t(L, LCURL_STORAGE_KV);
|
||||
lua_pushvalue(L, v);
|
||||
lua_rawseti(L, -2, i);
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
void lcurl_storage_remove_i(lua_State *L, int storage, int i){
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||
lua_rawgeti(L, -1, LCURL_STORAGE_KV);
|
||||
if(lua_istable(L, -1)){
|
||||
lua_pushnil(L);
|
||||
lua_rawseti(L, -3, i);
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
struct curl_slist* lcurl_storage_remove_slist(lua_State *L, int storage, int idx){
|
||||
struct curl_slist* list;
|
||||
assert(idx != LUA_NOREF);
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||
lua_rawgeti(L, -1, 1); // list storage
|
||||
lua_rawgeti(L, -1, LCURL_STORAGE_SLIST); // list storage
|
||||
if(lua_istable(L, -1)){
|
||||
lua_rawgeti(L, -1, idx);
|
||||
list = lua_touserdata(L, -1);
|
||||
assert(list);
|
||||
luaL_unref(L, -2, idx);
|
||||
lua_pop(L, 3);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
return list;
|
||||
}
|
||||
|
||||
int lcurl_storage_free(lua_State *L, int storage){
|
||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||
lua_rawgeti(L, -1, 1); // list storage
|
||||
lua_rawgeti(L, -1, LCURL_STORAGE_SLIST); // list storage
|
||||
if(lua_istable(L, -1)){
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, -2) != 0){
|
||||
@ -126,3 +156,77 @@ int lcurl_util_new_weak_table(lua_State*L, const char *mode){
|
||||
assert((top+1) == lua_gettop(L));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lcurl_util_pcall_method(lua_State *L, const char *name, int nargs, int nresults, int errfunc){
|
||||
int obj_index = -nargs - 1;
|
||||
lua_getfield(L, obj_index, name);
|
||||
lua_insert(L, obj_index - 1);
|
||||
return lua_pcall(L, nargs + 1, nresults, errfunc);
|
||||
}
|
||||
|
||||
static void lcurl_utils_pcall_close(lua_State *L, int obj){
|
||||
int top = lua_gettop(L);
|
||||
lua_pushvalue(L, obj);
|
||||
lcurl_util_pcall_method(L, "close", 0, 0, 0);
|
||||
lua_settop(L, top);
|
||||
}
|
||||
|
||||
int lcurl_utils_apply_options(lua_State *L, int opt, int obj, int do_close,
|
||||
int error_mode, int error_type, int error_code
|
||||
){
|
||||
int top = lua_gettop(L);
|
||||
opt = lua_absindex(L, opt);
|
||||
obj = lua_absindex(L, obj);
|
||||
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, opt) != 0){
|
||||
int n;
|
||||
assert(lua_gettop(L) == (top + 2));
|
||||
|
||||
if(lua_type(L, -2) == LUA_TNUMBER){ /* [curl.OPT_URL] = "http://localhost" */
|
||||
lua_pushvalue(L, -2);
|
||||
lua_insert(L, -2); /*Stack : opt, obj, k, k, v */
|
||||
lua_pushliteral(L, "setopt"); /*Stack : opt, obj, k, k, v, "setopt" */
|
||||
n = 2;
|
||||
}
|
||||
else if(lua_type(L, -2) == LUA_TSTRING){ /* url = "http://localhost" */
|
||||
lua_pushliteral(L, "setopt_"); lua_pushvalue(L, -3); lua_concat(L, 2);
|
||||
/*Stack : opt, obj, k, v, "setopt_XXX" */
|
||||
n = 1;
|
||||
}
|
||||
else{
|
||||
lua_pop(L, 1);
|
||||
continue;
|
||||
}
|
||||
/*Stack : opt, obj, k,[ k,] v, `setoptXXX` */
|
||||
|
||||
lua_gettable(L, obj); /* get e["settop_XXX]*/
|
||||
|
||||
if(lua_isnil(L, -1)){ /* unknown option */
|
||||
if(do_close) lcurl_utils_pcall_close(L, obj);
|
||||
lua_settop(L, top);
|
||||
return lcurl_fail_ex(L, error_mode, error_type, error_code);
|
||||
}
|
||||
|
||||
lua_insert(L, -n-1); /*Stack : opt, obj, k, setoptXXX, [ k,] v */
|
||||
lua_pushvalue(L, obj); /*Stack : opt, obj, k, setoptXXX, [ k,] v, obj */
|
||||
lua_insert(L, -n-1); /*Stack : opt, obj, k, setoptXXX, obj, [ k,] v */
|
||||
|
||||
if(lua_pcall(L, n+1, 2, 0)){
|
||||
if(do_close) lcurl_utils_pcall_close(L, obj);
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
if(lua_isnil(L, -2)){
|
||||
if(do_close) lcurl_utils_pcall_close(L, obj);
|
||||
lua_settop(L, top);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*Stack : opt, obj, k, ok, nil*/
|
||||
lua_pop(L, 2);
|
||||
assert(lua_gettop(L) == (top+1));
|
||||
}
|
||||
assert(lua_gettop(L) == top);
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ int lcurl_storage_preserve_slist(lua_State *L, int storage, struct curl_slist *
|
||||
|
||||
struct curl_slist* lcurl_storage_remove_slist(lua_State *L, int storage, int idx);
|
||||
|
||||
void lcurl_storage_preserve_iv(lua_State *L, int storage, int i, int v);
|
||||
|
||||
void lcurl_storage_remove_i(lua_State *L, int storage, int i);
|
||||
|
||||
int lcurl_storage_free(lua_State *L, int storage);
|
||||
|
||||
struct curl_slist* lcurl_util_array_to_slist(lua_State *L, int t);
|
||||
@ -40,4 +44,9 @@ int lcurl_util_push_cb(lua_State *L, lcurl_callback_t *c);
|
||||
|
||||
int lcurl_util_new_weak_table(lua_State*L, const char *mode);
|
||||
|
||||
int lcurl_util_pcall_method(lua_State *L, const char *name, int nargs, int nresults, int errfunc);
|
||||
|
||||
int lcurl_utils_apply_options(lua_State *L, int opt, int obj, int do_close,
|
||||
int error_mode, int error_type, int error_code
|
||||
);
|
||||
#endif
|
||||
|
@ -12,3 +12,4 @@ print("------------------------------------")
|
||||
print("")
|
||||
|
||||
require "test_safe"
|
||||
require "test_easy"
|
||||
|
106
test/test_easy.lua
Normal file
106
test/test_easy.lua
Normal file
@ -0,0 +1,106 @@
|
||||
local HAS_RUNNER = not not lunit
|
||||
local lunit = require "lunit"
|
||||
local TEST_CASE = assert(lunit.TEST_CASE)
|
||||
local skip = lunit.skip or function() end
|
||||
|
||||
local curl = require "lcurl"
|
||||
local scurl = require "lcurl.safe"
|
||||
local url = "http://example.com"
|
||||
local fname = "./test.download"
|
||||
|
||||
local function weak_ptr(val)
|
||||
return setmetatable({value = val},{__mode = 'v'})
|
||||
end
|
||||
|
||||
local function gc_collect()
|
||||
collectgarbage("collect")
|
||||
collectgarbage("collect")
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'write_callback' do
|
||||
|
||||
local c, f
|
||||
|
||||
function teardown()
|
||||
if f then f:close() end
|
||||
os.remove(fname)
|
||||
if c then c:close() end
|
||||
f, c = nil
|
||||
end
|
||||
|
||||
function test_write_to_file()
|
||||
f = assert(io.open(fname, "w+b"))
|
||||
c = assert(curl.easy{
|
||||
url = url;
|
||||
writefunction = f;
|
||||
})
|
||||
|
||||
assert_equal(c, c:perform())
|
||||
end
|
||||
|
||||
function test_write_to_file_abort()
|
||||
f = assert(io.open(fname, "w+b"))
|
||||
c = assert(scurl.easy{
|
||||
url = url;
|
||||
writefunction = function(str)
|
||||
return #str - 1
|
||||
end;
|
||||
})
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal(e, curl.error(curl.ERROR_EASY, curl.E_WRITE_ERROR))
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'escape' do
|
||||
|
||||
local c
|
||||
|
||||
function teardown()
|
||||
if c then c:close() end
|
||||
f, c = nil
|
||||
end
|
||||
|
||||
function test()
|
||||
local e = "This%2Bis%2Ba%2Bsimple%2B%2526%2Bshort%2Btest."
|
||||
local d = "This+is+a+simple+%26+short+test."
|
||||
c = assert(curl.easy())
|
||||
assert_equal(e, c:escape(d))
|
||||
assert_equal(d, c:unescape(e))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'setopt_form' do
|
||||
|
||||
local c
|
||||
|
||||
function teardown()
|
||||
if c then c:close() end
|
||||
c = nil
|
||||
end
|
||||
|
||||
function test()
|
||||
local pfrom, e
|
||||
do
|
||||
local form = curl.form()
|
||||
e = curl.easy{httppost = form}
|
||||
pfrom = weak_ptr(form)
|
||||
end
|
||||
|
||||
gc_collect()
|
||||
assert(pfrom.value)
|
||||
|
||||
e:setopt_httppost(curl.form())
|
||||
|
||||
gc_collect()
|
||||
assert(not pfrom.value)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
if not HAS_RUNNER then lunit.run() end
|
@ -30,10 +30,11 @@ end
|
||||
|
||||
local _ENV = TEST_CASE'setopt' do
|
||||
|
||||
local curl = require "lcurl.safe"
|
||||
local c
|
||||
|
||||
function setup()
|
||||
c = assert(require"lcurl.safe".easy())
|
||||
c = assert(curl.easy())
|
||||
end
|
||||
|
||||
function teardown()
|
||||
@ -63,6 +64,13 @@ function test_array()
|
||||
assert_equal(c, c:setopt_httpheader{"k:v"})
|
||||
end
|
||||
|
||||
function test_multiple_options()
|
||||
assert_error(function() c:setopt{verbose = "false"} end)
|
||||
assert_error(function() c:setopt{verbose = "1"} end)
|
||||
assert_equal(c, c:setopt{verbose = false})
|
||||
assert_equal(c, c:setopt{[curl.OPT_VERBOSE] = false})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'error_object' do
|
||||
@ -85,4 +93,153 @@ end
|
||||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'ctor' do
|
||||
|
||||
local scurl = require "lcurl.safe"
|
||||
local curl = require "lcurl"
|
||||
local c
|
||||
|
||||
function teardown()
|
||||
if c then c:close() end
|
||||
c = nil
|
||||
end
|
||||
|
||||
function test_easy_error()
|
||||
c = assert(curl.easy())
|
||||
c:close()
|
||||
c = assert(curl.easy{
|
||||
url = "http://example.com",
|
||||
[curl.OPT_VERBOSE] = true,
|
||||
})
|
||||
c:close()
|
||||
|
||||
assert_error(function()
|
||||
c = curl.easy{
|
||||
url_111 = "http://example.com",
|
||||
}
|
||||
end)
|
||||
|
||||
assert_error(function()
|
||||
c = curl.easy{
|
||||
url = 123,
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
function test_easy_safe()
|
||||
c = assert(scurl.easy())
|
||||
c:close()
|
||||
c = assert(scurl.easy{
|
||||
url = "http://example.com",
|
||||
[curl.OPT_VERBOSE] = true,
|
||||
})
|
||||
c:close()
|
||||
|
||||
assert_pass(function()
|
||||
c = scurl.easy{
|
||||
url_111 = "http://example.com",
|
||||
}
|
||||
end)
|
||||
assert_nil(c)
|
||||
|
||||
assert_error(function()
|
||||
c = scurl.easy{
|
||||
url = 123,
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
function test_multi_error()
|
||||
c = assert(curl.multi())
|
||||
c:close()
|
||||
c = assert(curl.multi{
|
||||
maxconnects = 10;
|
||||
[curl.OPT_MULTI_PIPELINING] = true,
|
||||
})
|
||||
c:close()
|
||||
|
||||
assert_error(function()
|
||||
c = curl.multi{
|
||||
url_111 = "http://example.com",
|
||||
}
|
||||
end)
|
||||
|
||||
assert_error(function()
|
||||
c = curl.multi{
|
||||
maxconnects = "hello",
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
function test_multi_safe()
|
||||
c = assert(scurl.multi())
|
||||
c:close()
|
||||
c = assert(scurl.multi{
|
||||
maxconnects = 10;
|
||||
[curl.OPT_MULTI_PIPELINING] = true,
|
||||
})
|
||||
c:close()
|
||||
|
||||
assert_pass(function()
|
||||
c = scurl.multi{
|
||||
url_111 = "http://example.com",
|
||||
}
|
||||
end)
|
||||
assert_nil(c)
|
||||
|
||||
assert_error(function()
|
||||
c = scurl.multi{
|
||||
maxconnects = "hello",
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
function test_share_error()
|
||||
assert(curl.LOCK_DATA_COOKIE)
|
||||
|
||||
c = assert(curl.share())
|
||||
c:close()
|
||||
c = assert(curl.share{
|
||||
share = curl.LOCK_DATA_COOKIE;
|
||||
})
|
||||
c:close()
|
||||
|
||||
assert_error(function()
|
||||
c = curl.share{
|
||||
url_111 = "http://example.com",
|
||||
}
|
||||
end)
|
||||
|
||||
assert_error(function()
|
||||
c = curl.share{
|
||||
share = "hello";
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
function test_share_safe()
|
||||
assert(curl.LOCK_DATA_COOKIE)
|
||||
|
||||
c = assert(scurl.share())
|
||||
c:close()
|
||||
c = assert(curl.share{
|
||||
share = scurl.LOCK_DATA_COOKIE;
|
||||
})
|
||||
c:close()
|
||||
|
||||
assert_pass(function()
|
||||
c = scurl.share{
|
||||
url_111 = "http://example.com",
|
||||
}
|
||||
end)
|
||||
|
||||
assert_error(function()
|
||||
c = scurl.share{
|
||||
share = "hello";
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if not HAS_RUNNER then lunit.run() end
|
||||
|
Loading…
x
Reference in New Issue
Block a user