@@ -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 ){
@@ -566,6 +576,7 @@ static int lcurl_easy_set_CURLU(lua_State *L) {
566576}
567577
568578#endif
579+
569580//}
570581
571582//{ unset
@@ -953,6 +964,27 @@ static int lcurl_easy_unset_CURLU(lua_State *L) {
953964
954965#endif
955966
967+ #if LCURL_CURL_VER_GE (7 ,64 ,0 )
968+
969+ static int lcurl_easy_unset_TRAILERFUNCTION (lua_State * L ){
970+ lcurl_easy_t * p = lcurl_geteasy (L );
971+
972+ CURLcode code = curl_easy_setopt (p -> curl , CURLOPT_TRAILERFUNCTION , NULL );
973+ if (code != CURLE_OK ){
974+ return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , code );
975+ }
976+ curl_easy_setopt (p -> curl , CURLOPT_TRAILERFUNCTION , NULL );
977+
978+ luaL_unref (L , LCURL_LUA_REGISTRY , p -> trailer .cb_ref );
979+ luaL_unref (L , LCURL_LUA_REGISTRY , p -> trailer .ud_ref );
980+ p -> trailer .cb_ref = p -> trailer .ud_ref = LUA_NOREF ;
981+
982+ lua_settop (L , 1 );
983+ return 1 ;
984+ }
985+
986+ #endif
987+
956988//}
957989
958990//}
@@ -1618,6 +1650,70 @@ static int lcurl_easy_set_CHUNK_END_FUNCTION(lua_State *L){
16181650
16191651//}
16201652
1653+ //{ Trailer
1654+
1655+ #if LCURL_CURL_VER_GE (7 ,64 ,0 )
1656+
1657+ static int lcurl_trailer_callback (struct curl_slist * * list , void * arg ) {
1658+ lcurl_easy_t * p = arg ;
1659+ lua_State * L = p -> L ;
1660+ int top = lua_gettop (L );
1661+ int n = lcurl_util_push_cb (L , & p -> trailer );
1662+
1663+ if (lua_pcall (L , n - 1 , LUA_MULTRET , 0 )) {
1664+ assert (lua_gettop (L ) >= top );
1665+ lua_pushlightuserdata (L , (void * )LCURL_ERROR_TAG );
1666+ lua_insert (L , top + 1 );
1667+ return CURL_TRAILERFUNC_ABORT ;
1668+ }
1669+
1670+ n = lua_gettop (L );
1671+
1672+ if (n == top ) {
1673+ return CURL_TRAILERFUNC_OK ;
1674+ }
1675+
1676+ /* libcurl will free the list */
1677+ * list = lcurl_util_to_slist (L , top + 1 );
1678+ if (* list ) {
1679+ lua_settop (L , top );
1680+ return CURL_TRAILERFUNC_OK ;
1681+ }
1682+
1683+ // empty array or NULL
1684+ if (lua_istable (L , top + 1 ) || lutil_is_null (L , top + 1 )) {
1685+ lua_settop (L , top );
1686+ return CURL_TRAILERFUNC_OK ;
1687+ }
1688+
1689+ // true
1690+ if ((lua_type (L , top + 1 ) == LUA_TBOOLEAN ) && (lua_toboolean (L , top + 1 ))){
1691+ lua_settop (L , top );
1692+ return CURL_TRAILERFUNC_OK ;
1693+ }
1694+
1695+ // single nil
1696+ if ((n == (top + 1 )) && lua_isnil (L , top + 1 )){
1697+ lua_settop (L , top );
1698+ return CURL_TRAILERFUNC_OK ;
1699+ }
1700+
1701+ lua_settop (L , top );
1702+ return CURL_TRAILERFUNC_ABORT ;
1703+ }
1704+
1705+ static int lcurl_easy_set_TRAILERFUNCTION (lua_State * L ){
1706+ lcurl_easy_t * p = lcurl_geteasy (L );
1707+ return lcurl_easy_set_callback (L , p , & p -> trailer ,
1708+ CURLOPT_TRAILERFUNCTION , CURLOPT_TRAILERDATA ,
1709+ "trailer" , lcurl_trailer_callback
1710+ );
1711+ }
1712+
1713+ #endif
1714+
1715+ //}
1716+
16211717//}
16221718
16231719static int lcurl_easy_setopt (lua_State * L ){
@@ -1780,6 +1876,9 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
17801876#if LCURL_CURL_VER_GE (7 ,63 ,0 )
17811877 OPT_ENTRY (curlu , CURLU , TTT , 0 , 0 )
17821878#endif
1879+ #if LCURL_CURL_VER_GE (7 ,64 ,0 )
1880+ OPT_ENTRY (trailerfunction , TRAILERFUNCTION , TTT , 0 , 0 )
1881+ #endif
17831882#undef OPT_ENTRY
17841883
17851884#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[] = {
18081907#if LCURL_CURL_VER_GE (7 ,63 ,0 )
18091908 OPT_ENTRY (curlu , CURLU , TTT , 0 , 0 )
18101909#endif
1910+ #if LCURL_CURL_VER_GE (7 ,64 ,0 )
1911+ OPT_ENTRY (trailerfunction , TRAILERFUNCTION , TTT , 0 , 0 )
1912+ #endif
18111913#undef OPT_ENTRY
18121914
18131915#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[] = {
18681970#if LCURL_CURL_VER_GE (7 ,63 ,0 )
18691971 OPT_ENTRY (curlu , CURLU , TTT , 0 , 0 )
18701972#endif
1973+ #if LCURL_CURL_VER_GE (7 ,64 ,0 )
1974+ OPT_ENTRY (trailerfunction , TRAILERFUNCTION , TTT , 0 , 0 )
1975+ #endif
18711976#undef OPT_ENTRY
18721977#undef FLG_ENTRY
18731978
0 commit comments