Skip to content

Commit 6e42dec

Browse files
committed
Merge remote-tracking branch 'upstream/master'
# Conflicts: # appveyor.yml # src/lcopteasy.h
2 parents 6facbae + cb29348 commit 6e42dec

File tree

4 files changed

+226
-4
lines changed

4 files changed

+226
-4
lines changed

src/lceasy.c

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ int lcurl_easy_create(lua_State *L, int error_mode){
9797
p->match.cb_ref = p->match.ud_ref = LUA_NOREF;
9898
p->chunk_bgn.cb_ref = p->chunk_bgn.ud_ref = LUA_NOREF;
9999
p->chunk_end.cb_ref = p->chunk_end.ud_ref = LUA_NOREF;
100+
#if LCURL_CURL_VER_GE(7,64,0)
101+
p->trailer.cb_ref = p->trailer.ud_ref = LUA_NOREF;
102+
#endif
100103
p->rbuffer.ref = LUA_NOREF;
101104
for(i = 0; i < LCURL_LIST_COUNT; ++i){
102105
p->lists[i] = LUA_NOREF;
@@ -179,10 +182,14 @@ static int lcurl_easy_cleanup(lua_State *L){
179182
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_bgn.ud_ref);
180183
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_end.cb_ref);
181184
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_end.ud_ref);
185+
#if LCURL_CURL_VER_GE(7,64,0)
186+
luaL_unref(L, LCURL_LUA_REGISTRY, p->trailer.cb_ref);
187+
luaL_unref(L, LCURL_LUA_REGISTRY, p->trailer.ud_ref);
188+
#endif
182189
luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.cb_ref);
183190
luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.ud_ref);
184191
luaL_unref(L, LCURL_LUA_REGISTRY, p->rbuffer.ref);
185-
192+
186193
p->wr.cb_ref = p->wr.ud_ref = LUA_NOREF;
187194
p->rd.cb_ref = p->rd.ud_ref = LUA_NOREF;
188195
p->hd.cb_ref = p->hd.ud_ref = LUA_NOREF;
@@ -192,6 +199,9 @@ static int lcurl_easy_cleanup(lua_State *L){
192199
p->match.cb_ref = p->match.ud_ref = LUA_NOREF;
193200
p->chunk_bgn.cb_ref = p->chunk_bgn.ud_ref = LUA_NOREF;
194201
p->chunk_end.cb_ref = p->chunk_end.ud_ref = LUA_NOREF;
202+
#if LCURL_CURL_VER_GE(7,64,0)
203+
p->trailer.cb_ref = p->trailer.ud_ref = LUA_NOREF;
204+
#endif
195205
p->rbuffer.ref = LUA_NOREF;
196206

197207
for(i = 0; i < LCURL_LIST_COUNT; ++i){
@@ -324,10 +334,12 @@ static int lcurl_opt_set_long_(lua_State *L, int opt){
324334
if(lua_isboolean(L, 2)){
325335
val = lua_toboolean(L, 2);
326336
if( val
327-
&& (opt == CURLOPT_SSL_VERIFYHOST)
337+
&& (
338+
(opt == CURLOPT_SSL_VERIFYHOST)
328339
#if LCURL_CURL_VER_GE(7,52,0)
329-
&& (opt == CURLOPT_PROXY_SSL_VERIFYHOST)
340+
|| (opt == CURLOPT_PROXY_SSL_VERIFYHOST)
330341
#endif
342+
)
331343
){
332344
val = 2;
333345
}
@@ -566,6 +578,7 @@ static int lcurl_easy_set_CURLU(lua_State *L) {
566578
}
567579

568580
#endif
581+
569582
//}
570583

571584
//{ unset
@@ -953,6 +966,27 @@ static int lcurl_easy_unset_CURLU(lua_State *L) {
953966

954967
#endif
955968

969+
#if LCURL_CURL_VER_GE(7,64,0)
970+
971+
static int lcurl_easy_unset_TRAILERFUNCTION(lua_State *L){
972+
lcurl_easy_t *p = lcurl_geteasy(L);
973+
974+
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_TRAILERFUNCTION, NULL);
975+
if(code != CURLE_OK){
976+
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
977+
}
978+
curl_easy_setopt(p->curl, CURLOPT_TRAILERDATA, NULL);
979+
980+
luaL_unref(L, LCURL_LUA_REGISTRY, p->trailer.cb_ref);
981+
luaL_unref(L, LCURL_LUA_REGISTRY, p->trailer.ud_ref);
982+
p->trailer.cb_ref = p->trailer.ud_ref = LUA_NOREF;
983+
984+
lua_settop(L, 1);
985+
return 1;
986+
}
987+
988+
#endif
989+
956990
//}
957991

958992
//}
@@ -1618,6 +1652,70 @@ static int lcurl_easy_set_CHUNK_END_FUNCTION(lua_State *L){
16181652

16191653
//}
16201654

1655+
//{ Trailer
1656+
1657+
#if LCURL_CURL_VER_GE(7,64,0)
1658+
1659+
static int lcurl_trailer_callback(struct curl_slist **list, void *arg) {
1660+
lcurl_easy_t *p = arg;
1661+
lua_State *L = p->L;
1662+
int top = lua_gettop(L);
1663+
int n = lcurl_util_push_cb(L, &p->trailer);
1664+
1665+
if (lua_pcall(L, n - 1, LUA_MULTRET, 0)) {
1666+
assert(lua_gettop(L) >= top);
1667+
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
1668+
lua_insert(L, top + 1);
1669+
return CURL_TRAILERFUNC_ABORT;
1670+
}
1671+
1672+
n = lua_gettop(L);
1673+
1674+
if (n == top) {
1675+
return CURL_TRAILERFUNC_OK;
1676+
}
1677+
1678+
/* libcurl will free the list */
1679+
*list = lcurl_util_to_slist(L, top + 1);
1680+
if (*list) {
1681+
lua_settop(L, top);
1682+
return CURL_TRAILERFUNC_OK;
1683+
}
1684+
1685+
// empty array or NULL
1686+
if (lua_istable(L, top + 1) || lutil_is_null(L, top + 1)) {
1687+
lua_settop(L, top);
1688+
return CURL_TRAILERFUNC_OK;
1689+
}
1690+
1691+
// true
1692+
if((lua_type(L, top + 1) == LUA_TBOOLEAN) && (lua_toboolean(L, top + 1))){
1693+
lua_settop(L, top);
1694+
return CURL_TRAILERFUNC_OK;
1695+
}
1696+
1697+
// single nil
1698+
if((n == (top + 1)) && lua_isnil(L, top + 1)){
1699+
lua_settop(L, top);
1700+
return CURL_TRAILERFUNC_OK;
1701+
}
1702+
1703+
lua_settop(L, top);
1704+
return CURL_TRAILERFUNC_ABORT;
1705+
}
1706+
1707+
static int lcurl_easy_set_TRAILERFUNCTION (lua_State *L){
1708+
lcurl_easy_t *p = lcurl_geteasy(L);
1709+
return lcurl_easy_set_callback(L, p, &p->trailer,
1710+
CURLOPT_TRAILERFUNCTION, CURLOPT_TRAILERDATA,
1711+
"trailer", lcurl_trailer_callback
1712+
);
1713+
}
1714+
1715+
#endif
1716+
1717+
//}
1718+
16211719
//}
16221720

16231721
static int lcurl_easy_setopt(lua_State *L){
@@ -1780,6 +1878,9 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
17801878
#if LCURL_CURL_VER_GE(7,63,0)
17811879
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
17821880
#endif
1881+
#if LCURL_CURL_VER_GE(7,64,0)
1882+
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
1883+
#endif
17831884
#undef OPT_ENTRY
17841885

17851886
#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[] = {
18081909
#if LCURL_CURL_VER_GE(7,63,0)
18091910
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
18101911
#endif
1912+
#if LCURL_CURL_VER_GE(7,64,0)
1913+
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
1914+
#endif
18111915
#undef OPT_ENTRY
18121916

18131917
#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[] = {
18681972
#if LCURL_CURL_VER_GE(7,63,0)
18691973
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
18701974
#endif
1975+
#if LCURL_CURL_VER_GE(7,64,0)
1976+
OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0)
1977+
#endif
18711978
#undef OPT_ENTRY
18721979
#undef FLG_ENTRY
18731980

src/lceasy.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ typedef struct lcurl_easy_tag{
8989
lcurl_callback_t match;
9090
lcurl_callback_t chunk_bgn;
9191
lcurl_callback_t chunk_end;
92+
#if LCURL_CURL_VER_GE(7,64,0)
93+
lcurl_callback_t trailer;
94+
#endif
9295
}lcurl_easy_t;
9396

9497
int lcurl_easy_create(lua_State *L, int error_mode);
@@ -111,6 +114,9 @@ size_t lcurl_read_callback(lua_State *L,
111114
#ifdef lcurl_mime_t
112115
#undef lcurl_mime_t
113116
#endif
117+
#ifdef lcurl_url_t
118+
#undef lcurl_url_t
119+
#endif
114120
#endif
115121

116122
#endif

src/lcopteasy.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,10 @@ OPT_ENTRY(doh_url, DOH_URL, STR, 0, LCURL_DEFA
461461
OPT_ENTRY(upload_buffersize, UPLOAD_BUFFERSIZE, LNG, 0, 64 * 1024)
462462
#endif
463463

464+
#if LCURL_CURL_VER_GE(7,64,0)
465+
OPT_ENTRY(http09_allowed, HTTP09_ALLOWED, LNG, 0, 0)
466+
#endif
467+
464468
#if LCURL_CURL_VER_GE(7,65,0)
465469
OPT_ENTRY(maxage_conn, MAXAGE_CONN, LNG, 0, LCURL_DEFAULT_VALUE)
466470
#endif

test/test_easy.lua

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ local json = require "dkjson"
1818
local path = require "path"
1919
local upath = require "path".new('/')
2020
local utils = require "utils"
21-
-- local url = "http://127.0.0.1:7090/get"
2221
local fname = "./test.download"
2322

2423
-- local GET_URL = "http://example.com"
@@ -1164,4 +1163,110 @@ end
11641163

11651164
end
11661165

1166+
local _ENV = TEST_CASE'trailer_callback' if ENABLE and is_curl_ge(7,64,0) then
1167+
1168+
local url = POST_URL
1169+
1170+
local m, c, t
1171+
1172+
local function json_data()
1173+
return json.decode(table.concat(t))
1174+
end
1175+
1176+
local treader = function(t)
1177+
local i = 0
1178+
return function()
1179+
i = i + 1
1180+
return t[i]
1181+
end
1182+
end
1183+
1184+
function setup()
1185+
t = {}
1186+
c = assert(scurl.easy{
1187+
url = url,
1188+
post = true,
1189+
httpheader = {"Transfer-Encoding: chunked"},
1190+
readfunction = treader {'a=1&', 'b=2&'},
1191+
timeout = 60,
1192+
})
1193+
assert_equal(c, c:setopt_writefunction(table.insert, t))
1194+
end
1195+
1196+
function teardown()
1197+
if c then c:close() end
1198+
if m then m:close() end
1199+
t, c, m = nil
1200+
end
1201+
1202+
local empty_responses = {
1203+
{'no_response', function() end},
1204+
{'nil_response', function() return nil end},
1205+
{'null_response', function() return curl.null end},
1206+
{'true_response', function() return true end},
1207+
{'empty_array', function() return {} end},
1208+
}
1209+
1210+
local abort_responses = {
1211+
{'false_response', function() return false end},
1212+
{'nil_with_error_response', function() return nil, 'error message' end},
1213+
{'numeric_response_0', function() return 0 end},
1214+
{'numeric_response_1', function() return 1 end},
1215+
}
1216+
1217+
for _, response in ipairs(empty_responses) do
1218+
_ENV[ 'test_' .. response[1] ] = function()
1219+
local trailer_called = 0
1220+
assert_equal(c, c:setopt_trailerfunction(function()
1221+
trailer_called = trailer_called + 1
1222+
return response[2]()
1223+
end))
1224+
1225+
assert_equal(c, c:perform())
1226+
1227+
assert_equal(1, trailer_called)
1228+
1229+
assert_equal(200, c:getinfo_response_code())
1230+
local data = assert_table(json_data())
1231+
1232+
assert_equal('1', data.form.a)
1233+
assert_equal('2', data.form.b)
1234+
end
1235+
end
1236+
1237+
for _, response in ipairs(abort_responses) do
1238+
_ENV[ 'test_' .. response[1] ] = function()
1239+
local trailer_called = 0
1240+
assert_equal(c, c:setopt_trailerfunction(function()
1241+
trailer_called = trailer_called + 1
1242+
return response[2]()
1243+
end))
1244+
1245+
local ok, err = assert_nil(c:perform())
1246+
assert_equal(1, trailer_called)
1247+
assert_equal(curl.error(curl.ERROR_EASY, curl.E_ABORTED_BY_CALLBACK), err)
1248+
end
1249+
end
1250+
1251+
function test_send_header()
1252+
local trailer_called = 0
1253+
assert_equal(c, c:setopt_trailerfunction(function()
1254+
trailer_called = trailer_called + 1
1255+
return {'x-trailer-header: value'}
1256+
end))
1257+
1258+
assert_equal(c, c:perform())
1259+
1260+
assert_equal(1, trailer_called)
1261+
1262+
assert_equal(200, c:getinfo_response_code())
1263+
local data = assert_table(json_data())
1264+
1265+
assert_equal('1', data.form.a)
1266+
assert_equal('2', data.form.b)
1267+
assert_equal('value', data.headers['x-trailer-header'])
1268+
end
1269+
1270+
end
1271+
11671272
RUN()

0 commit comments

Comments
 (0)