Add. Support CURLOPT_TRAILERFUNCTION
This commit is contained in:
parent
e0b1d2ee3d
commit
e70f6ac9a3
@ -7,7 +7,7 @@ shallow_clone: true
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
LR_EXTERNAL: c:\external
|
LR_EXTERNAL: c:\external
|
||||||
CURL_VER: 7.63.0
|
CURL_VER: 7.64.0
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
- LUA: "lua 5.1"
|
- LUA: "lua 5.1"
|
||||||
|
107
src/lceasy.c
107
src/lceasy.c
@ -97,6 +97,9 @@ int lcurl_easy_create(lua_State *L, int error_mode){
|
|||||||
p->match.cb_ref = p->match.ud_ref = LUA_NOREF;
|
p->match.cb_ref = p->match.ud_ref = LUA_NOREF;
|
||||||
p->chunk_bgn.cb_ref = p->chunk_bgn.ud_ref = LUA_NOREF;
|
p->chunk_bgn.cb_ref = p->chunk_bgn.ud_ref = LUA_NOREF;
|
||||||
p->chunk_end.cb_ref = p->chunk_end.ud_ref = LUA_NOREF;
|
p->chunk_end.cb_ref = p->chunk_end.ud_ref = LUA_NOREF;
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
p->trailer.cb_ref = p->trailer.ud_ref = LUA_NOREF;
|
||||||
|
#endif
|
||||||
p->rbuffer.ref = LUA_NOREF;
|
p->rbuffer.ref = LUA_NOREF;
|
||||||
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;
|
||||||
@ -179,10 +182,14 @@ static int lcurl_easy_cleanup(lua_State *L){
|
|||||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_bgn.ud_ref);
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_bgn.ud_ref);
|
||||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_end.cb_ref);
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_end.cb_ref);
|
||||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_end.ud_ref);
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_end.ud_ref);
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->trailer.cb_ref);
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->trailer.ud_ref);
|
||||||
|
#endif
|
||||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.cb_ref);
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.cb_ref);
|
||||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.ud_ref);
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.ud_ref);
|
||||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->rbuffer.ref);
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->rbuffer.ref);
|
||||||
|
|
||||||
p->wr.cb_ref = p->wr.ud_ref = LUA_NOREF;
|
p->wr.cb_ref = p->wr.ud_ref = LUA_NOREF;
|
||||||
p->rd.cb_ref = p->rd.ud_ref = LUA_NOREF;
|
p->rd.cb_ref = p->rd.ud_ref = LUA_NOREF;
|
||||||
p->hd.cb_ref = p->hd.ud_ref = LUA_NOREF;
|
p->hd.cb_ref = p->hd.ud_ref = LUA_NOREF;
|
||||||
@ -192,6 +199,9 @@ static int lcurl_easy_cleanup(lua_State *L){
|
|||||||
p->match.cb_ref = p->match.ud_ref = LUA_NOREF;
|
p->match.cb_ref = p->match.ud_ref = LUA_NOREF;
|
||||||
p->chunk_bgn.cb_ref = p->chunk_bgn.ud_ref = LUA_NOREF;
|
p->chunk_bgn.cb_ref = p->chunk_bgn.ud_ref = LUA_NOREF;
|
||||||
p->chunk_end.cb_ref = p->chunk_end.ud_ref = LUA_NOREF;
|
p->chunk_end.cb_ref = p->chunk_end.ud_ref = LUA_NOREF;
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
p->trailer.cb_ref = p->trailer.ud_ref = LUA_NOREF;
|
||||||
|
#endif
|
||||||
p->rbuffer.ref = LUA_NOREF;
|
p->rbuffer.ref = LUA_NOREF;
|
||||||
|
|
||||||
for(i = 0; i < LCURL_LIST_COUNT; ++i){
|
for(i = 0; i < LCURL_LIST_COUNT; ++i){
|
||||||
@ -566,6 +576,7 @@ static int lcurl_easy_set_CURLU(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ unset
|
//{ unset
|
||||||
@ -953,6 +964,27 @@ static int lcurl_easy_unset_CURLU(lua_State *L) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
|
||||||
|
static int lcurl_easy_unset_TRAILERFUNCTION(lua_State *L){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
|
||||||
|
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_TRAILERFUNCTION, NULL);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_TRAILERFUNCTION, NULL);
|
||||||
|
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->trailer.cb_ref);
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->trailer.ud_ref);
|
||||||
|
p->trailer.cb_ref = p->trailer.ud_ref = LUA_NOREF;
|
||||||
|
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
@ -1618,6 +1650,70 @@ static int lcurl_easy_set_CHUNK_END_FUNCTION(lua_State *L){
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
//{ Trailer
|
||||||
|
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
|
||||||
|
static int lcurl_trailer_callback(struct curl_slist **list, void *arg) {
|
||||||
|
lcurl_easy_t *p = arg;
|
||||||
|
lua_State *L = p->L;
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
int n = lcurl_util_push_cb(L, &p->trailer);
|
||||||
|
|
||||||
|
if (lua_pcall(L, n - 1, LUA_MULTRET, 0)) {
|
||||||
|
assert(lua_gettop(L) >= top);
|
||||||
|
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||||
|
lua_insert(L, top + 1);
|
||||||
|
return CURL_TRAILERFUNC_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = lua_gettop(L);
|
||||||
|
|
||||||
|
if (n == top) {
|
||||||
|
return CURL_TRAILERFUNC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* libcurl will free the list */
|
||||||
|
*list = lcurl_util_to_slist(L, top + 1);
|
||||||
|
if (*list) {
|
||||||
|
lua_settop(L, top);
|
||||||
|
return CURL_TRAILERFUNC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty array or NULL
|
||||||
|
if (lua_istable(L, top + 1) || lutil_is_null(L, top + 1)) {
|
||||||
|
lua_settop(L, top);
|
||||||
|
return CURL_TRAILERFUNC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// true
|
||||||
|
if((lua_type(L, top + 1) == LUA_TBOOLEAN) && (lua_toboolean(L, top + 1))){
|
||||||
|
lua_settop(L, top);
|
||||||
|
return CURL_TRAILERFUNC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// single nil
|
||||||
|
if((n == (top + 1)) && lua_isnil(L, top + 1)){
|
||||||
|
lua_settop(L, top);
|
||||||
|
return CURL_TRAILERFUNC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, top);
|
||||||
|
return CURL_TRAILERFUNC_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_easy_set_TRAILERFUNCTION (lua_State *L){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
return lcurl_easy_set_callback(L, p, &p->trailer,
|
||||||
|
CURLOPT_TRAILERFUNCTION, CURLOPT_TRAILERDATA,
|
||||||
|
"trailer", lcurl_trailer_callback
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
static int lcurl_easy_setopt(lua_State *L){
|
static int lcurl_easy_setopt(lua_State *L){
|
||||||
@ -1780,6 +1876,9 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
|
|||||||
#if LCURL_CURL_VER_GE(7,63,0)
|
#if LCURL_CURL_VER_GE(7,63,0)
|
||||||
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
||||||
#endif
|
#endif
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
|
||||||
|
#endif
|
||||||
#undef OPT_ENTRY
|
#undef OPT_ENTRY
|
||||||
|
|
||||||
#define OPT_ENTRY(L, N, T, S, D) { "unsetopt_"#L, lcurl_easy_unset_##N },
|
#define OPT_ENTRY(L, N, T, S, D) { "unsetopt_"#L, lcurl_easy_unset_##N },
|
||||||
@ -1808,6 +1907,9 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
|
|||||||
#if LCURL_CURL_VER_GE(7,63,0)
|
#if LCURL_CURL_VER_GE(7,63,0)
|
||||||
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
||||||
#endif
|
#endif
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
|
||||||
|
#endif
|
||||||
#undef OPT_ENTRY
|
#undef OPT_ENTRY
|
||||||
|
|
||||||
#define OPT_ENTRY(L, N, T, S) { "getinfo_"#L, lcurl_easy_get_##N },
|
#define OPT_ENTRY(L, N, T, S) { "getinfo_"#L, lcurl_easy_get_##N },
|
||||||
@ -1868,6 +1970,9 @@ static const lcurl_const_t lcurl_easy_opt[] = {
|
|||||||
#if LCURL_CURL_VER_GE(7,63,0)
|
#if LCURL_CURL_VER_GE(7,63,0)
|
||||||
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
||||||
#endif
|
#endif
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
|
||||||
|
#endif
|
||||||
#undef OPT_ENTRY
|
#undef OPT_ENTRY
|
||||||
#undef FLG_ENTRY
|
#undef FLG_ENTRY
|
||||||
|
|
||||||
|
@ -89,6 +89,9 @@ typedef struct lcurl_easy_tag{
|
|||||||
lcurl_callback_t match;
|
lcurl_callback_t match;
|
||||||
lcurl_callback_t chunk_bgn;
|
lcurl_callback_t chunk_bgn;
|
||||||
lcurl_callback_t chunk_end;
|
lcurl_callback_t chunk_end;
|
||||||
|
#if LCURL_CURL_VER_GE(7,64,0)
|
||||||
|
lcurl_callback_t trailer;
|
||||||
|
#endif
|
||||||
}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);
|
||||||
|
@ -18,7 +18,6 @@ local json = require "dkjson"
|
|||||||
local path = require "path"
|
local path = require "path"
|
||||||
local upath = require "path".new('/')
|
local upath = require "path".new('/')
|
||||||
local utils = require "utils"
|
local utils = require "utils"
|
||||||
-- local url = "http://127.0.0.1:7090/get"
|
|
||||||
local fname = "./test.download"
|
local fname = "./test.download"
|
||||||
|
|
||||||
-- local GET_URL = "http://example.com"
|
-- local GET_URL = "http://example.com"
|
||||||
@ -1164,4 +1163,110 @@ end
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local _ENV = TEST_CASE'trailer_callback' if ENABLE and is_curl_ge(7,64,0) then
|
||||||
|
|
||||||
|
local url = POST_URL
|
||||||
|
|
||||||
|
local m, c, t
|
||||||
|
|
||||||
|
local function json_data()
|
||||||
|
return json.decode(table.concat(t))
|
||||||
|
end
|
||||||
|
|
||||||
|
local treader = function(t)
|
||||||
|
local i = 0
|
||||||
|
return function()
|
||||||
|
i = i + 1
|
||||||
|
return t[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function setup()
|
||||||
|
t = {}
|
||||||
|
c = assert(scurl.easy{
|
||||||
|
url = url,
|
||||||
|
post = true,
|
||||||
|
httpheader = {"Transfer-Encoding: chunked"},
|
||||||
|
readfunction = treader {'a=1&', 'b=2&'},
|
||||||
|
timeout = 60,
|
||||||
|
})
|
||||||
|
assert_equal(c, c:setopt_writefunction(table.insert, t))
|
||||||
|
end
|
||||||
|
|
||||||
|
function teardown()
|
||||||
|
if c then c:close() end
|
||||||
|
if m then m:close() end
|
||||||
|
t, c, m = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local empty_responses = {
|
||||||
|
{'no_response', function() end},
|
||||||
|
{'nil_response', function() return nil end},
|
||||||
|
{'null_response', function() return curl.null end},
|
||||||
|
{'true_response', function() return true end},
|
||||||
|
{'empty_array', function() return {} end},
|
||||||
|
}
|
||||||
|
|
||||||
|
local abort_responses = {
|
||||||
|
{'false_response', function() return false end},
|
||||||
|
{'nil_with_error_response', function() return nil, 'error message' end},
|
||||||
|
{'numeric_response_0', function() return 0 end},
|
||||||
|
{'numeric_response_1', function() return 1 end},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, response in ipairs(empty_responses) do
|
||||||
|
_ENV[ 'test_' .. response[1] ] = function()
|
||||||
|
local trailer_called = 0
|
||||||
|
assert_equal(c, c:setopt_trailerfunction(function()
|
||||||
|
trailer_called = trailer_called + 1
|
||||||
|
return response[2]()
|
||||||
|
end))
|
||||||
|
|
||||||
|
assert_equal(c, c:perform())
|
||||||
|
|
||||||
|
assert_equal(1, trailer_called)
|
||||||
|
|
||||||
|
assert_equal(200, c:getinfo_response_code())
|
||||||
|
local data = assert_table(json_data())
|
||||||
|
|
||||||
|
assert_equal('1', data.form.a)
|
||||||
|
assert_equal('2', data.form.b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, response in ipairs(abort_responses) do
|
||||||
|
_ENV[ 'test_' .. response[1] ] = function()
|
||||||
|
local trailer_called = 0
|
||||||
|
assert_equal(c, c:setopt_trailerfunction(function()
|
||||||
|
trailer_called = trailer_called + 1
|
||||||
|
return response[2]()
|
||||||
|
end))
|
||||||
|
|
||||||
|
local ok, err = assert_nil(c:perform())
|
||||||
|
assert_equal(1, trailer_called)
|
||||||
|
assert_equal(curl.error(curl.ERROR_EASY, curl.E_ABORTED_BY_CALLBACK), err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_send_header()
|
||||||
|
local trailer_called = 0
|
||||||
|
assert_equal(c, c:setopt_trailerfunction(function()
|
||||||
|
trailer_called = trailer_called + 1
|
||||||
|
return {'x-trailer-header: value'}
|
||||||
|
end))
|
||||||
|
|
||||||
|
assert_equal(c, c:perform())
|
||||||
|
|
||||||
|
assert_equal(1, trailer_called)
|
||||||
|
|
||||||
|
assert_equal(200, c:getinfo_response_code())
|
||||||
|
local data = assert_table(json_data())
|
||||||
|
|
||||||
|
assert_equal('1', data.form.a)
|
||||||
|
assert_equal('2', data.form.b)
|
||||||
|
assert_equal('value', data.headers['x-trailer-header'])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
RUN()
|
RUN()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user