Merge pull request #143 from moteus/trailerfunction

Add. Support 7.64.0
Close #144
master
Alexey Melnichuk 2019-04-08 20:49:09 +03:00 committed by GitHub
commit cb29348257
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 224 additions and 5 deletions

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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()