commit
cb29348257
|
@ -7,7 +7,7 @@ shallow_clone: true
|
|||
|
||||
environment:
|
||||
LR_EXTERNAL: c:\external
|
||||
CURL_VER: 7.63.0
|
||||
CURL_VER: 7.64.0
|
||||
|
||||
matrix:
|
||||
- LUA: "lua 5.1"
|
||||
|
|
113
src/lceasy.c
113
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->chunk_bgn.cb_ref = p->chunk_bgn.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;
|
||||
for(i = 0; i < LCURL_LIST_COUNT; ++i){
|
||||
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_end.cb_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.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->rbuffer.ref);
|
||||
|
||||
|
||||
p->wr.cb_ref = p->wr.ud_ref = LUA_NOREF;
|
||||
p->rd.cb_ref = p->rd.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->chunk_bgn.cb_ref = p->chunk_bgn.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;
|
||||
|
||||
for(i = 0; i < LCURL_LIST_COUNT; ++i){
|
||||
|
@ -324,10 +334,12 @@ static int lcurl_opt_set_long_(lua_State *L, int opt){
|
|||
if(lua_isboolean(L, 2)){
|
||||
val = lua_toboolean(L, 2);
|
||||
if( val
|
||||
&& (opt == CURLOPT_SSL_VERIFYHOST)
|
||||
&& (
|
||||
(opt == CURLOPT_SSL_VERIFYHOST)
|
||||
#if LCURL_CURL_VER_GE(7,52,0)
|
||||
&& (opt == CURLOPT_PROXY_SSL_VERIFYHOST)
|
||||
|| (opt == CURLOPT_PROXY_SSL_VERIFYHOST)
|
||||
#endif
|
||||
)
|
||||
){
|
||||
val = 2;
|
||||
}
|
||||
|
@ -566,6 +578,7 @@ static int lcurl_easy_set_CURLU(lua_State *L) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
//}
|
||||
|
||||
//{ unset
|
||||
|
@ -953,6 +966,27 @@ static int lcurl_easy_unset_CURLU(lua_State *L) {
|
|||
|
||||
#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_TRAILERDATA, 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 +1652,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){
|
||||
|
@ -1780,6 +1878,9 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
|
|||
#if LCURL_CURL_VER_GE(7,63,0)
|
||||
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
||||
#endif
|
||||
#if LCURL_CURL_VER_GE(7,64,0)
|
||||
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
|
||||
#endif
|
||||
#undef OPT_ENTRY
|
||||
|
||||
#define OPT_ENTRY(L, N, T, S, D) { "unsetopt_"#L, lcurl_easy_unset_##N },
|
||||
|
@ -1808,6 +1909,9 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
|
|||
#if LCURL_CURL_VER_GE(7,63,0)
|
||||
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
||||
#endif
|
||||
#if LCURL_CURL_VER_GE(7,64,0)
|
||||
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
|
||||
#endif
|
||||
#undef OPT_ENTRY
|
||||
|
||||
#define OPT_ENTRY(L, N, T, S) { "getinfo_"#L, lcurl_easy_get_##N },
|
||||
|
@ -1868,6 +1972,9 @@ static const lcurl_const_t lcurl_easy_opt[] = {
|
|||
#if LCURL_CURL_VER_GE(7,63,0)
|
||||
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
|
||||
#endif
|
||||
#if LCURL_CURL_VER_GE(7,64,0)
|
||||
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
|
||||
#endif
|
||||
#undef OPT_ENTRY
|
||||
#undef FLG_ENTRY
|
||||
|
||||
|
|
|
@ -89,6 +89,9 @@ typedef struct lcurl_easy_tag{
|
|||
lcurl_callback_t match;
|
||||
lcurl_callback_t chunk_bgn;
|
||||
lcurl_callback_t chunk_end;
|
||||
#if LCURL_CURL_VER_GE(7,64,0)
|
||||
lcurl_callback_t trailer;
|
||||
#endif
|
||||
}lcurl_easy_t;
|
||||
|
||||
int lcurl_easy_create(lua_State *L, int error_mode);
|
||||
|
|
|
@ -457,6 +457,10 @@ OPT_ENTRY(doh_url, DOH_URL, STR, 0, LCURL_DEFA
|
|||
OPT_ENTRY(upload_buffersize, UPLOAD_BUFFERSIZE, LNG, 0, 64 * 1024)
|
||||
#endif
|
||||
|
||||
#if LCURL_CURL_VER_GE(7,64,0)
|
||||
OPT_ENTRY(http09_allowed, HTTP09_ALLOWED, LNG, 0, 0)
|
||||
#endif
|
||||
|
||||
//{ Restore system macros
|
||||
|
||||
#ifdef LCURL__TCP_FASTOPEN
|
||||
|
|
|
@ -18,7 +18,6 @@ local json = require "dkjson"
|
|||
local path = require "path"
|
||||
local upath = require "path".new('/')
|
||||
local utils = require "utils"
|
||||
-- local url = "http://127.0.0.1:7090/get"
|
||||
local fname = "./test.download"
|
||||
|
||||
-- local GET_URL = "http://example.com"
|
||||
|
@ -1164,4 +1163,110 @@ 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()
|
||||
|
|
Loading…
Reference in New Issue