Change. Easy ctor and setopt method could use table to set multiple options.

```Lua
c = curl.easy{
  url = 'http://example.com',
  [curl.OPT_VERBOSE] = true,
}
```
This commit is contained in:
Alexey Melnichuk 2014-09-01 13:38:34 +05:00
parent fc7a570060
commit 144ceeb123
5 changed files with 190 additions and 18 deletions

View File

@ -9,7 +9,15 @@ function form() end
--- Create Easy object --- Create Easy object
-- --
-- @tparam[opt] table options
-- @treturn[1] easy new curl easy object -- @treturn[1] easy new curl easy object
--
-- @usage
-- c = curl.easy{
-- url = 'http://example.com',
-- [curl.OPT_VERBOSE] = true,
-- }
--
function easy() end function easy() end
--- Create Multi object --- Create Multi object
@ -187,7 +195,7 @@ function close() end
--- Set options. --- 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 -- @param ... value
-- @treturn easy self -- @treturn easy self
-- --
@ -197,6 +205,10 @@ function close() end
-- function(t, n) return table.remove(t) end, -- function(t, n) return table.remove(t) end,
-- {"1111", "2222"} -- {"1111", "2222"}
-- ) -- )
--c:setopt{
-- url = 'http://example.com',
-- [curl.OPT_VERBOSE] = true,
-- }
function setopt() end function setopt() end
--- Get information. --- Get information.

View File

@ -11,12 +11,92 @@ static const char *LCURL_ERROR_TAG = "LCURL_ERROR_TAG";
#define LCURL_EASY_NAME LCURL_PREFIX" Easy" #define LCURL_EASY_NAME LCURL_PREFIX" Easy"
static const char *LCURL_EASY = LCURL_EASY_NAME; 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
//{ //{
static void lcurl_easy_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);
}
static int lcurl_easy_apply_options(lua_State *L, lcurl_easy_t *p, int opt, int obj, int do_close){
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_easy_pcall_close(L, obj);
lua_settop(L, top);
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, LCURL_E_UNKNOWN_OPTION);
}
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_easy_pcall_close(L, obj);
return lua_error(L);
}
if(lua_isnil(L, -2)){
if(do_close) lcurl_easy_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;
}
int lcurl_easy_create(lua_State *L, int error_mode){ 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; int i;
lua_settop(L, 1); /* options */
p = lutil_newudatap(L, lcurl_easy_t, LCURL_EASY);
p->curl = curl_easy_init(); p->curl = curl_easy_init();
p->err_mode = error_mode; p->err_mode = error_mode;
if(!p->curl) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, CURLE_FAILED_INIT); if(!p->curl) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, CURLE_FAILED_INIT);
p->L = L; p->L = L;
@ -29,6 +109,13 @@ int lcurl_easy_create(lua_State *L, int error_mode){
for(i = 0; i < LCURL_LIST_COUNT; ++i){ for(i = 0; i < LCURL_LIST_COUNT; ++i){
p->lists[i] = LUA_NOREF; p->lists[i] = LUA_NOREF;
} }
if(lua_type(L, 1) == LUA_TTABLE){
int ret = lcurl_easy_apply_options(L, p, 1, 2, 1);
if(ret) return ret;
assert(lua_gettop(L) == 2);
}
return 1; return 1;
} }
@ -642,7 +729,17 @@ static int lcurl_easy_set_PROGRESSFUNCTION(lua_State *L){
static int lcurl_easy_setopt(lua_State *L){ static int lcurl_easy_setopt(lua_State *L){
lcurl_easy_t *p = lcurl_geteasy(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_easy_apply_options(L, p, 2, 1, 0);
if(ret) return ret;
lua_settop(L, 1);
return 1;
}
opt = luaL_checklong(L, 2);
lua_remove(L, 2); lua_remove(L, 2);
#define OPT_ENTRY(l, N, T, S) case CURLOPT_##N: return lcurl_easy_set_##N(L); #define OPT_ENTRY(l, N, T, S) case CURLOPT_##N: return lcurl_easy_set_##N(L);
@ -658,13 +755,7 @@ static int lcurl_easy_setopt(lua_State *L){
} }
#undef OPT_ENTRY #undef OPT_ENTRY
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, LCURL_E_UNKNOWN_OPTION);
#if LCURL_CURL_VER_GE(7,21,5)
CURLE_UNKNOWN_OPTION
#else
CURLE_UNKNOWN_TELNET_OPTION
#endif
);
} }
static int lcurl_easy_getinfo(lua_State *L){ static int lcurl_easy_getinfo(lua_State *L){
@ -678,13 +769,7 @@ static int lcurl_easy_getinfo(lua_State *L){
} }
#undef OPT_ENTRY #undef OPT_ENTRY
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, LCURL_E_UNKNOWN_OPTION);
#if LCURL_CURL_VER_GE(7,21,5)
CURLE_UNKNOWN_OPTION
#else
CURLE_UNKNOWN_TELNET_OPTION
#endif
);
} }
//} //}

View File

@ -126,3 +126,10 @@ int lcurl_util_new_weak_table(lua_State*L, const char *mode){
assert((top+1) == lua_gettop(L)); assert((top+1) == lua_gettop(L));
return 1; 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);
}

View File

@ -40,4 +40,6 @@ 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_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);
#endif #endif

View File

@ -30,10 +30,11 @@ end
local _ENV = TEST_CASE'setopt' do local _ENV = TEST_CASE'setopt' do
local curl = require "lcurl.safe"
local c local c
function setup() function setup()
c = assert(require"lcurl.safe".easy()) c = assert(curl.easy())
end end
function teardown() function teardown()
@ -63,6 +64,13 @@ function test_array()
assert_equal(c, c:setopt_httpheader{"k:v"}) assert_equal(c, c:setopt_httpheader{"k:v"})
end 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 end
local _ENV = TEST_CASE'error_object' do local _ENV = TEST_CASE'error_object' do
@ -85,4 +93,62 @@ end
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_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_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
end
if not HAS_RUNNER then lunit.run() end if not HAS_RUNNER then lunit.run() end