diff --git a/appveyor.yml b/appveyor.yml index 19aac24..2f9035e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ shallow_clone: true environment: LR_EXTERNAL: c:\external - CURL_VER: 7.65.1 + CURL_VER: 7.74.0 matrix: - LUA: "lua 5.1" diff --git a/src/l52util.c b/src/l52util.c index b2dc8f0..07238e5 100644 --- a/src/l52util.c +++ b/src/l52util.c @@ -141,6 +141,14 @@ void lutil_pushint64(lua_State *L, int64_t v){ lua_pushnumber(L, (lua_Number)v); } +void lutil_pushuint(lua_State *L, unsigned int v){ +#if LUA_VERSION_NUM >= 503 + lua_pushinteger(L, (lua_Integer)v); +#else + lua_pushnumber(L, (lua_Number)v); +#endif +} + int64_t lutil_checkint64(lua_State *L, int idx){ if(sizeof(lua_Integer) >= sizeof(int64_t)) return luaL_checkinteger(L, idx); diff --git a/src/l52util.h b/src/l52util.h index 70845b5..4f6254f 100644 --- a/src/l52util.h +++ b/src/l52util.h @@ -80,6 +80,8 @@ int lutil_createmetap (lua_State *L, const void *p, const luaL_Reg *methods, void *lutil_newudatap_impl (lua_State *L, size_t size, const void *p); +void lutil_pushuint(lua_State *L, unsigned int v); + void lutil_pushint64(lua_State *L, int64_t v); int64_t lutil_checkint64(lua_State *L, int idx); diff --git a/src/lceasy.c b/src/lceasy.c index e543675..d7e9ca2 100644 --- a/src/lceasy.c +++ b/src/lceasy.c @@ -99,6 +99,10 @@ int lcurl_easy_create(lua_State *L, int error_mode){ 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 +#if LCURL_CURL_VER_GE(7,74,0) + p->hstsread.cb_ref = p->hstsread.ud_ref = LUA_NOREF; + p->hstswrite.cb_ref = p->hstswrite.ud_ref = LUA_NOREF; #endif p->rbuffer.ref = LUA_NOREF; for(i = 0; i < LCURL_LIST_COUNT; ++i){ @@ -185,6 +189,12 @@ static int lcurl_easy_cleanup(lua_State *L){ #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 +#if LCURL_CURL_VER_GE(7,74,0) + luaL_unref(L, LCURL_LUA_REGISTRY, p->hstsread.cb_ref); + luaL_unref(L, LCURL_LUA_REGISTRY, p->hstsread.ud_ref); + luaL_unref(L, LCURL_LUA_REGISTRY, p->hstswrite.cb_ref); + luaL_unref(L, LCURL_LUA_REGISTRY, p->hstswrite.ud_ref); #endif luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.cb_ref); luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.ud_ref); @@ -201,6 +211,10 @@ static int lcurl_easy_cleanup(lua_State *L){ 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 +#if LCURL_CURL_VER_GE(7,74,0) + p->hstsread.cb_ref = p->hstsread.ud_ref = LUA_NOREF; + p->hstswrite.cb_ref = p->hstswrite.ud_ref = LUA_NOREF; #endif p->rbuffer.ref = LUA_NOREF; @@ -428,6 +442,33 @@ static int lcurl_opt_set_slist_(lua_State *L, int opt, int list_no){ return 1; } +#if LCURL_CURL_VER_GE(7,73,0) + +static int lcurl_opt_set_blob_(lua_State *L, int opt){ + lcurl_easy_t *p = lcurl_geteasy(L); + CURLcode code; const char *value; size_t len; + struct curl_blob blob; + + luaL_argcheck(L, lua_type(L, 2) == LUA_TSTRING || lutil_is_null(L, 2), 2, "string expected"); + + value = lua_tolstring(L, 2, &len); + + blob.data = (void*)value; + blob.len = len; + blob.flags = CURL_BLOB_COPY; + + code = curl_easy_setopt(p->curl, opt, value); + + if(code != CURLE_OK){ + return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code); + } + + lua_settop(L, 1); + return 1; +} + +#endif + #define LCURL_STR_OPT(N, S) static int lcurl_easy_set_##N(lua_State *L){\ return lcurl_opt_set_string_(L, CURLOPT_##N, (S)); \ } @@ -444,6 +485,10 @@ static int lcurl_opt_set_slist_(lua_State *L, int opt, int list_no){ return lcurl_opt_set_off_(L, CURLOPT_##N);\ } +#define LCURL_BLB_OPT(N, S) static int lcurl_easy_set_##N(lua_State *L){\ + return lcurl_opt_set_blob_(L, CURLOPT_##N); \ +} + #define OPT_ENTRY(L, N, T, S, D) LCURL_##T##_OPT(N, S) #include "lcopteasy.h" @@ -476,6 +521,7 @@ static int lcurl_easy_set_POSTFIELDS(lua_State *L){ #undef LCURL_LST_OPT #undef LCURL_LNG_OPT #undef LCURL_OFF_OPT +#undef LCURL_BLB_OPT static size_t lcurl_hpost_read_callback(char *buffer, size_t size, size_t nitems, void *arg); @@ -647,6 +693,23 @@ static int lcurl_opt_unset_slist_(lua_State *L, int opt, int list_no){ return 1; } +#if LCURL_CURL_VER_GE(7,73,0) + +static int lcurl_opt_unset_blob_(lua_State *L, int opt){ + lcurl_easy_t *p = lcurl_geteasy(L); + CURLcode code; + + code = curl_easy_setopt(p->curl, opt, 0); + if(code != CURLE_OK){ + return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code); + } + + lua_settop(L, 1); + return 1; +} + +#endif + #define LCURL_STR_OPT(N, S, D) static int lcurl_easy_unset_##N(lua_State *L){\ return lcurl_opt_unset_string_(L, CURLOPT_##N, (D)); \ } @@ -663,6 +726,10 @@ static int lcurl_opt_unset_slist_(lua_State *L, int opt, int list_no){ return lcurl_opt_unset_off_(L, CURLOPT_##N, (D));\ } +#define LCURL_BLB_OPT(N, S, D) static int lcurl_easy_unset_##N(lua_State *L){\ + return lcurl_opt_unset_blob_(L, CURLOPT_##N);\ +} + #define OPT_ENTRY(L, N, T, S, D) LCURL_##T##_OPT(N, S, D) #include "lcopteasy.h" @@ -673,6 +740,7 @@ static int lcurl_opt_unset_slist_(lua_State *L, int opt, int list_no){ #undef LCURL_LST_OPT #undef LCURL_LNG_OPT #undef LCURL_OFF_OPT +#undef LCURL_BLB_OPT static int lcurl_easy_unset_HTTPPOST(lua_State *L){ lcurl_easy_t *p = lcurl_geteasy(L); @@ -987,6 +1055,44 @@ static int lcurl_easy_unset_TRAILERFUNCTION(lua_State *L){ #endif +#if LCURL_CURL_VER_GE(7,74,0) + +static int lcurl_easy_unset_HSTSREADFUNCTION (lua_State *L){ + lcurl_easy_t *p = lcurl_geteasy(L); + + CURLcode code = curl_easy_setopt(p->curl, CURLOPT_HSTSREADFUNCTION, NULL); + if(code != CURLE_OK){ + return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code); + } + curl_easy_setopt(p->curl, CURLOPT_HSTSREADDATA, NULL); + + luaL_unref(L, LCURL_LUA_REGISTRY, p->hstsread.cb_ref); + luaL_unref(L, LCURL_LUA_REGISTRY, p->hstsread.ud_ref); + p->hstsread.cb_ref = p->hstsread.ud_ref = LUA_NOREF; + + lua_settop(L, 1); + return 1; +} + +static int lcurl_easy_unset_HSTSWRITEFUNCTION (lua_State *L){ + lcurl_easy_t *p = lcurl_geteasy(L); + + CURLcode code = curl_easy_setopt(p->curl, CURLOPT_HSTSWRITEFUNCTION, NULL); + if(code != CURLE_OK){ + return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code); + } + curl_easy_setopt(p->curl, CURLOPT_HSTSWRITEDATA, NULL); + + luaL_unref(L, LCURL_LUA_REGISTRY, p->hstswrite.cb_ref); + luaL_unref(L, LCURL_LUA_REGISTRY, p->hstswrite.ud_ref); + p->hstswrite.cb_ref = p->hstswrite.ud_ref = LUA_NOREF; + + lua_settop(L, 1); + return 1; +} + +#endif + //} //} @@ -1275,7 +1381,7 @@ size_t lcurl_read_callback(lua_State *L, } else{ if(lua_type(L, top + 1) == LUA_TNUMBER){ - size_t ret = lua_tonumber(L, top + 1); + size_t ret = lua_tointeger(L, top + 1); if(ret == (size_t)CURL_READFUNC_PAUSE){ lua_settop(L, top); return CURL_READFUNC_PAUSE; @@ -1376,8 +1482,11 @@ static int lcurl_xferinfo_callback(void *arg, curl_off_t dltotal, curl_off_t dln if(lua_isboolean(L, top + 1)) ret = lua_toboolean(L, top + 1)?0:1; else{ - ret = lua_tointeger(L, top + 1); - if(ret == 0) ret = 1; else ret = 0; + ret = lua_tonumber(L, top + 1); + #if LCURL_CURL_VER_GE(7,68,0) + if(ret != (size_t)CURL_PROGRESSFUNC_CONTINUE) + #endif + if(ret == 0) ret = 1; else ret = 0; } } @@ -1716,6 +1825,184 @@ static int lcurl_easy_set_TRAILERFUNCTION (lua_State *L){ //} +//{ HSTS Reader + +#if LCURL_CURL_VER_GE(7,74,0) + +#define LCURL_HSTS_EXPIRE_LEN 18 + +static int lcurl_hstsread_callback(CURL *easy, struct curl_hstsentry *sts, 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->hstsread); + const char *name; size_t namelen; + const char *expire; size_t expirelen; + int type; + + assert(NULL != p->L); + + lua_pushinteger(L, sts->namelen); + if (lua_pcall(L, n, LUA_MULTRET, 0)) { + assert(lua_gettop(L) >= top); + lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG); + lua_insert(L, top + 1); + return CURLSTS_FAIL; + } + + if (lua_gettop(L) == top) { + return CURLSTS_DONE; + } + + assert(lua_gettop(L) >= top); + + type = lua_type(L, top + 1); + if (type == LUA_TNIL) { + lua_settop(L, top); + return CURLSTS_DONE; + } + + if (type != LUA_TSTRING) { + lua_settop(L, top); + return CURLSTS_FAIL; + } + + name = lua_tolstring(L, top + 1, &namelen); + + if(namelen > sts->namelen) { + lua_settop(L, top); + return CURLSTS_FAIL; + } + + memcpy(sts->name, name, namelen + 1); + + type = lua_type(L, top + 2); + if (type == LUA_TNONE) { + lua_settop(L, top); + return CURLSTS_OK; + } + + if ((type != LUA_TBOOLEAN) && (type != LUA_TNIL)) { + lua_settop(L, top); + return CURLSTS_FAIL; + } + + if (type == LUA_TBOOLEAN) { + sts->includeSubDomains = lua_toboolean(L, top + 2) ? 0 : 1; + } + else if (type != LUA_TNIL) { + lua_settop(L, top); + return CURLSTS_FAIL; + } + + type = lua_type(L, top + 3); + if ((type == LUA_TNONE) || (type == LUA_TNIL)) { + lua_settop(L, top); + return CURLSTS_OK; + } + + if(type != LUA_TSTRING) { + lua_settop(L, top); + return CURLSTS_FAIL; + } + + expire = lua_tolstring(L, top + 3, &expirelen); + + if (expirelen != LCURL_HSTS_EXPIRE_LEN - 1) { + lua_settop(L, top); + return CURLSTS_FAIL; + } + + memcpy(sts->expire, expire, expirelen + 1); + + lua_settop(L, top); + return CURLSTS_OK; +} + +static int lcurl_easy_set_HSTSREADFUNCTION(lua_State *L){ + lcurl_easy_t *p = lcurl_geteasy(L); + return lcurl_easy_set_callback(L, p, &p->hstsread, + CURLOPT_HSTSREADFUNCTION, CURLOPT_HSTSREADDATA, + "hstsread", lcurl_hstsread_callback + ); +} + +#endif + +//} + +//{ HSTS Writer + +#if LCURL_CURL_VER_GE(7,74,0) + +static int lcurl_hstswrite_callback(CURL *easy, struct curl_hstsentry *sts, struct curl_index *count, 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->hstswrite); + int type; + + assert(NULL != p->L); + + lua_pushstring(L, sts->name); + lua_pushboolean(L, sts->includeSubDomains ? 1 : 0); + if (sts->expire[0]) { + lua_pushstring(L, sts->expire); + } else { + lua_pushnil(L); + } + lua_pushinteger(L, count->index); + lua_pushinteger(L, count->total); + + if (lua_pcall(L, n + 4, LUA_MULTRET, 0)) { + assert(lua_gettop(L) >= top); + lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG); + lua_insert(L, top + 1); + return CURLSTS_FAIL; + } + + if (lua_gettop(L) == top) { + return CURLSTS_OK; + } + + assert(lua_gettop(L) >= top); + + type = lua_type(L, top + 1); + if (type == LUA_TNIL) { + type = lua_type(L, top + 2); + lua_settop(L, top); + if(type == LUA_TNONE){ + return CURLSTS_OK; + } + return CURLSTS_FAIL; + } + + if (type == LUA_TNUMBER) { + int ret = lua_tointeger(L, top + 1); + lua_settop(L, top); + return ret; + } + + if (type == LUA_TBOOLEAN) { + int ret = lua_toboolean(L, top + 1); + lua_settop(L, top); + return ret ? CURLSTS_OK : CURLSTS_DONE; + } + + lua_settop(L, top); + return CURLSTS_FAIL; +} + +static int lcurl_easy_set_HSTSWRITEFUNCTION(lua_State *L){ + lcurl_easy_t *p = lcurl_geteasy(L); + return lcurl_easy_set_callback(L, p, &p->hstswrite, + CURLOPT_HSTSWRITEFUNCTION, CURLOPT_HSTSWRITEDATA, + "hstswrite", lcurl_hstswrite_callback + ); +} + +#endif + //} static int lcurl_easy_setopt(lua_State *L){ @@ -1881,6 +2168,10 @@ static const struct luaL_Reg lcurl_easy_methods[] = { #if LCURL_CURL_VER_GE(7,64,0) OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0) #endif +#if LCURL_CURL_VER_GE(7,74,0) + OPT_ENTRY(hstsreadfunction, HSTSREADFUNCTION, TTT, 0, 0) + OPT_ENTRY(hstswritefunction, HSTSWRITEFUNCTION,TTT, 0, 0) +#endif #undef OPT_ENTRY #define OPT_ENTRY(L, N, T, S, D) { "unsetopt_"#L, lcurl_easy_unset_##N }, @@ -1912,6 +2203,10 @@ static const struct luaL_Reg lcurl_easy_methods[] = { #if LCURL_CURL_VER_GE(7,64,0) OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0) #endif +#if LCURL_CURL_VER_GE(7,74,0) + OPT_ENTRY(hstsreadfunction, HSTSREADFUNCTION, TTT, 0, 0) + OPT_ENTRY(hstswritefunction, HSTSWRITEFUNCTION,TTT, 0, 0) +#endif #undef OPT_ENTRY #define OPT_ENTRY(L, N, T, S) { "getinfo_"#L, lcurl_easy_get_##N }, @@ -1975,6 +2270,10 @@ static const lcurl_const_t lcurl_easy_opt[] = { #if LCURL_CURL_VER_GE(7,64,0) OPT_ENTRY(trailerfunction, TRAILERFUNCTION, TTT, 0, 0) #endif +#if LCURL_CURL_VER_GE(7,74,0) + OPT_ENTRY(hstsreadfunction, HSTSREADFUNCTION, TTT, 0, 0) + OPT_ENTRY(hstswritefunction, HSTSWRITEFUNCTION,TTT, 0, 0) +#endif #undef OPT_ENTRY #undef FLG_ENTRY @@ -2026,4 +2325,6 @@ void lcurl_easy_initlib(lua_State *L, int nup){ lua_pop(L, 1); lcurl_util_set_const(L, lcurl_easy_opt); -} \ No newline at end of file +} + +//} diff --git a/src/lceasy.h b/src/lceasy.h index 9050add..f4518d9 100644 --- a/src/lceasy.h +++ b/src/lceasy.h @@ -19,6 +19,7 @@ #define LCURL_STR_INDEX(N) #define LCURL_LNG_INDEX(N) #define LCURL_OFF_INDEX(N) +#define LCURL_BLB_INDEX(N) #define OPT_ENTRY(L, N, T, S, D) LCURL_##T##_INDEX(N) enum { @@ -29,6 +30,7 @@ enum { LCURL_LIST_COUNT, }; +#undef LCURL_BLB_INDEX #undef LCURL_OFF_INDEX #undef LCURL_LST_INDEX #undef LCURL_STR_INDEX @@ -92,6 +94,10 @@ typedef struct lcurl_easy_tag{ #if LCURL_CURL_VER_GE(7,64,0) lcurl_callback_t trailer; #endif +#if LCURL_CURL_VER_GE(7,74,0) + lcurl_callback_t hstsread; + lcurl_callback_t hstswrite; +#endif }lcurl_easy_t; int lcurl_easy_create(lua_State *L, int error_mode); diff --git a/src/lcerr_easy.h b/src/lcerr_easy.h index d294e6b..986026a 100644 --- a/src/lcerr_easy.h +++ b/src/lcerr_easy.h @@ -132,3 +132,15 @@ ERR_ENTRY ( HTTP2_STREAM ) #if LCURL_CURL_VER_GE(7,59,0) ERR_ENTRY ( RECURSIVE_API_CALL ) #endif +#if LCURL_CURL_VER_GE(7,66,0) +ERR_ENTRY ( AUTH_ERROR ) +#endif +#if LCURL_CURL_VER_GE(7,68,0) +ERR_ENTRY ( HTTP3 ) +#endif +#if LCURL_CURL_VER_GE(7,69,0) +ERR_ENTRY ( QUIC_CONNECT_ERROR ) +#endif +#if LCURL_CURL_VER_GE(7,73,0) +ERR_ENTRY ( PROXY ) +#endif diff --git a/src/lcflags.h b/src/lcflags.h index aba9bc9..83c43fe 100644 --- a/src/lcflags.h +++ b/src/lcflags.h @@ -76,6 +76,15 @@ FLG_ENTRY(SSLOPT_ALLOW_BEAST ) #ifdef CURLSSLOPT_NO_REVOKE FLG_ENTRY(SSLOPT_NO_REVOKE ) #endif +#ifdef CURLSSLOPT_NO_PARTIALCHAIN +FLG_ENTRY(SSLOPT_NO_PARTIALCHAIN ) +#endif +#ifdef CURLSSLOPT_REVOKE_BEST_EFFORT +FLG_ENTRY(SSLOPT_REVOKE_BEST_EFFORT ) +#endif +#ifdef CURLSSLOPT_NATIVE_CA +FLG_ENTRY(SSLOPT_NATIVE_CA ) +#endif /* parameter for the CURLOPT_FTP_SSL_CCC option */ FLG_ENTRY(FTPSSL_CCC_NONE ) @@ -166,6 +175,9 @@ FLG_ENTRY(PROTO_SMB ) #ifdef CURLPROTO_SMBS FLG_ENTRY(PROTO_SMBS ) #endif +#ifdef CURLPROTO_MQTT +FLG_ENTRY(PROTO_MQTT ) +#endif FLG_ENTRY(PROTO_ALL ) FLG_ENTRY(PROXY_HTTP ) /* added in 7.10.0 */ @@ -184,3 +196,68 @@ FLG_ENTRY(PAUSE_RECV ) /* added in 7.18.0 */ FLG_ENTRY(PAUSE_RECV_CONT ) /* added in 7.18.0 */ FLG_ENTRY(PAUSE_SEND ) /* added in 7.18.0 */ FLG_ENTRY(PAUSE_SEND_CONT ) /* added in 7.18.0 */ + +#if LCURL_CURL_VER_GE(7,64,1) +FLG_ENTRY(ALTSVC_H1) +FLG_ENTRY(ALTSVC_H2) +FLG_ENTRY(ALTSVC_H3) +FLG_ENTRY(ALTSVC_READONLYFILE) +#endif + +#if LCURL_CURL_VER_GE(7,73,0) +FLG_ENTRY(PX_OK) +FLG_ENTRY(PX_BAD_ADDRESS_TYPE) +FLG_ENTRY(PX_BAD_VERSION) +FLG_ENTRY(PX_CLOSED) +FLG_ENTRY(PX_GSSAPI) +FLG_ENTRY(PX_GSSAPI_PERMSG) +FLG_ENTRY(PX_GSSAPI_PROTECTION) +FLG_ENTRY(PX_IDENTD) +FLG_ENTRY(PX_IDENTD_DIFFER) +FLG_ENTRY(PX_LONG_HOSTNAME) +FLG_ENTRY(PX_LONG_PASSWD) +FLG_ENTRY(PX_LONG_USER) +FLG_ENTRY(PX_NO_AUTH) +FLG_ENTRY(PX_RECV_ADDRESS) +FLG_ENTRY(PX_RECV_AUTH) +FLG_ENTRY(PX_RECV_CONNECT) +FLG_ENTRY(PX_RECV_REQACK) +FLG_ENTRY(PX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED) +FLG_ENTRY(PX_REPLY_COMMAND_NOT_SUPPORTED) +FLG_ENTRY(PX_REPLY_CONNECTION_REFUSED) +FLG_ENTRY(PX_REPLY_GENERAL_SERVER_FAILURE) +FLG_ENTRY(PX_REPLY_HOST_UNREACHABLE) +FLG_ENTRY(PX_REPLY_NETWORK_UNREACHABLE) +FLG_ENTRY(PX_REPLY_NOT_ALLOWED) +FLG_ENTRY(PX_REPLY_TTL_EXPIRED) +FLG_ENTRY(PX_REPLY_UNASSIGNED) +FLG_ENTRY(PX_REQUEST_FAILED) +FLG_ENTRY(PX_RESOLVE_HOST) +FLG_ENTRY(PX_SEND_AUTH) +FLG_ENTRY(PX_SEND_CONNECT) +FLG_ENTRY(PX_SEND_REQUEST) +FLG_ENTRY(PX_UNKNOWN_FAIL) +FLG_ENTRY(PX_UNKNOWN_MODE) +FLG_ENTRY(PX_USER_REJECTED) +#endif + +#if LCURL_CURL_VER_GE(7,73,0) +FLG_ENTRY(OT_LONG) +FLG_ENTRY(OT_VALUES) +FLG_ENTRY(OT_OFF_T) +FLG_ENTRY(OT_OBJECT) +FLG_ENTRY(OT_STRING) +FLG_ENTRY(OT_SLIST) +FLG_ENTRY(OT_CBPTR) +FLG_ENTRY(OT_BLOB) +FLG_ENTRY(OT_FUNCTION) +FLG_ENTRY(OT_FLAG_ALIAS) +#endif + +#if LCURL_CURL_VER_GE(7,74,0) +FLG_ENTRY(HSTS_ENABLE) +FLG_ENTRY(HSTS_READONLYFILE) +FLG_ENTRY(STS_OK) +FLG_ENTRY(STS_DONE) +FLG_ENTRY(STS_FAIL) +#endif diff --git a/src/lcinfoeasy.h b/src/lcinfoeasy.h index d6374d7..ab4bef3 100644 --- a/src/lcinfoeasy.h +++ b/src/lcinfoeasy.h @@ -77,6 +77,15 @@ OPT_ENTRY(starttransfer_time_t, STARTTRANSFER_TIME_T, OFF, 0) OPT_ENTRY(total_time_t, TOTAL_TIME_T, OFF, 0) #endif +#if LCURL_CURL_VER_GE(7,66,0) +OPT_ENTRY(retry_after, RETRY_AFTER, OFF, 0) +OPT_ENTRY(effective_method, EFFECTIVE_METHOD, STR, 0) +#endif + +#if LCURL_CURL_VER_GE(7,73,0) +OPT_ENTRY(proxy_error, PROXY_ERROR, LNG, 0) +#endif + // OPT_ENTRY( PRIVATE, void ) // OPT_ENTRY( TLS_SSL_PTR, struct curl_tlssessioninfo ** // OPT_ENTRY( TLS_SESSION, struct curl_tlssessioninfo * diff --git a/src/lcopteasy.h b/src/lcopteasy.h index 9d6282f..a48bf03 100644 --- a/src/lcopteasy.h +++ b/src/lcopteasy.h @@ -332,6 +332,9 @@ FLG_ENTRY( HTTP_VERSION_2TLS ) #if LCURL_CURL_VER_GE(7,49,0) FLG_ENTRY( HTTP_VERSION_2_PRIOR_KNOWLEDGE ) #endif +#if LCURL_CURL_VER_GE(7,66,0) +FLG_ENTRY( HTTP_VERSION_3 ) +#endif FLG_ENTRY( READFUNC_PAUSE ) /*7.18.0*/ FLG_ENTRY( WRITEFUNC_PAUSE ) /*7.18.0*/ @@ -465,10 +468,47 @@ OPT_ENTRY(upload_buffersize, UPLOAD_BUFFERSIZE, LNG, 0, 64 * 1024) OPT_ENTRY(http09_allowed, HTTP09_ALLOWED, LNG, 0, 0) #endif +#if LCURL_CURL_VER_GE(7,64,1) +OPT_ENTRY(altsvc, ALTSVC, STR, 0, LCURL_DEFAULT_VALUE) +OPT_ENTRY(altsvc_ctrl, ALTSVC_CTRL, LNG, 0, 0) +#endif + #if LCURL_CURL_VER_GE(7,65,0) OPT_ENTRY(maxage_conn, MAXAGE_CONN, LNG, 0, LCURL_DEFAULT_VALUE) #endif +#if LCURL_CURL_VER_GE(7,66,0) +OPT_ENTRY(sasl_authzid, SASL_AUTHZID, STR, 0, LCURL_DEFAULT_VALUE) +#endif + +#if LCURL_CURL_VER_GE(7,68,0) +FLG_ENTRY( PROGRESSFUNC_CONTINUE ) +#endif + +#if LCURL_CURL_VER_GE(7,69,0) +OPT_ENTRY(mail_rcpt_alllowfails, MAIL_RCPT_ALLLOWFAILS, LNG, 0, 1) +#endif + +#if LCURL_CURL_VER_GE(7,71,0) +OPT_ENTRY(sslcert_blob, SSLCERT_BLOB, BLB, 0, 0) +OPT_ENTRY(sslkey_blob, SSLKEY_BLOB, BLB, 0, 0) +OPT_ENTRY(proxy_sslcert_blob, PROXY_SSLCERT_BLOB, BLB, 0, 0) +OPT_ENTRY(proxy_sslkey_blob, PROXY_SSLKEY_BLOB, BLB, 0, 0) +OPT_ENTRY(issuercert_blob, ISSUERCERT_BLOB, BLB, 0, 0) + +OPT_ENTRY(proxy_issuercert, PROXY_ISSUERCERT, STR, 0, LCURL_DEFAULT_VALUE) +OPT_ENTRY(proxy_issuercert_blob, PROXY_ISSUERCERT_BLOB, BLB, 0, 0) +#endif + +#if LCURL_CURL_VER_GE(7,73,0) +OPT_ENTRY(ssl_ec_curves, SSL_EC_CURVES, STR, 0, LCURL_DEFAULT_VALUE) +#endif + +#if LCURL_CURL_VER_GE(7,74,0) +OPT_ENTRY(hsts_ctrl, HSTS_CTRL, LNG, 0, 0) +OPT_ENTRY(hsts, HSTS, STR, 0, LCURL_DEFAULT_VALUE) +#endif + //{ Restore system macros #ifdef LCURL__TCP_FASTOPEN diff --git a/src/lcoptmulti.h b/src/lcoptmulti.h index 654f07e..8f7fd71 100644 --- a/src/lcoptmulti.h +++ b/src/lcoptmulti.h @@ -1,6 +1,7 @@ OPT_ENTRY(pipelining, PIPELINING, LNG, 0 ) OPT_ENTRY(maxconnects, MAXCONNECTS, LNG, 0 ) + #if LCURL_CURL_VER_GE(7,30,0) OPT_ENTRY(max_host_connections, MAX_HOST_CONNECTIONS, LNG, 0 ) OPT_ENTRY(max_pipeline_length, MAX_PIPELINE_LENGTH, LNG, 0 ) @@ -10,3 +11,7 @@ OPT_ENTRY(pipelining_site_bl, PIPELINING_SITE_BL, STR_ARR, 0 OPT_ENTRY(pipelining_server_bl, PIPELINING_SERVER_BL, STR_ARR, 0 ) OPT_ENTRY(max_total_connections, MAX_TOTAL_CONNECTIONS, LNG, 0 ) #endif + +#if LCURL_CURL_VER_GE(7,67,0) +OPT_ENTRY(max_concurrent_streams, MAX_CONCURRENT_STREAMS, LNG, 0 ) +#endif diff --git a/src/lcopturl.h b/src/lcopturl.h index 518ff85..20fee9e 100644 --- a/src/lcopturl.h +++ b/src/lcopturl.h @@ -23,3 +23,7 @@ ENTRY_FLAG(URLDECODE ) ENTRY_FLAG(URLENCODE ) ENTRY_FLAG(APPENDQUERY ) ENTRY_FLAG(GUESS_SCHEME ) + +#if LCURL_CURL_VER_GE(7,67,0) +ENTRY_FLAG(NO_AUTHORITY ) +#endif diff --git a/src/lcurl.c b/src/lcurl.c index 8ccea5c..9c09456 100644 --- a/src/lcurl.c +++ b/src/lcurl.c @@ -73,6 +73,94 @@ static int lcurl_url_new(lua_State *L) { #endif +#if LCURL_CURL_VER_GE(7,73,0) + +static void lcurl_easy_option_push(lua_State *L, const struct curl_easyoption *opt) { + lua_newtable(L); + lua_pushliteral(L, "id"); lutil_pushuint(L, opt->id); lua_rawset(L, -3); + lua_pushliteral(L, "name"); lua_pushstring(L, opt->name); lua_rawset(L, -3); + lua_pushliteral(L, "type"); lutil_pushuint(L, opt->type); lua_rawset(L, -3); + lua_pushliteral(L, "flags"); lutil_pushuint(L, opt->flags); lua_rawset(L, -3); + lua_pushliteral(L, "flags_set"); lua_newtable(L); + lua_pushliteral(L, "alias"); lua_pushboolean(L, opt->flags & CURLOT_FLAG_ALIAS); lua_rawset(L, -3); + lua_rawset(L, -3); + lua_pushliteral(L, "type_name"); + switch(opt->type){ + case CURLOT_LONG : lua_pushliteral(L, "LONG" ); break; + case CURLOT_VALUES : lua_pushliteral(L, "VALUES" ); break; + case CURLOT_OFF_T : lua_pushliteral(L, "OFF_T" ); break; + case CURLOT_OBJECT : lua_pushliteral(L, "OBJECT" ); break; + case CURLOT_STRING : lua_pushliteral(L, "STRING" ); break; + case CURLOT_SLIST : lua_pushliteral(L, "SLIST" ); break; + case CURLOT_CBPTR : lua_pushliteral(L, "CBPTR" ); break; + case CURLOT_BLOB : lua_pushliteral(L, "BLOB" ); break; + case CURLOT_FUNCTION: lua_pushliteral(L, "FUNCTION"); break; + default: lua_pushliteral(L, "UNKNOWN"); + } + lua_rawset(L, -3); +} + +static int lcurl_easy_option_next(lua_State *L) { + const struct curl_easyoption *opt; + + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); + + lua_rawgeti(L, 1, 1); + opt = lua_touserdata(L, -1); + lua_settop(L, 1); + + opt = curl_easy_option_next(opt); + if (!opt) { + return 0; + } + + lcurl_easy_option_push(L, opt); + + lua_pushlightuserdata(L, (void*)opt); + lua_rawseti(L, 1, 1); + + return 1; +} + +static int lcurl_easy_option_by_id(lua_State *L) { + const struct curl_easyoption *opt = NULL; + lua_Integer id = luaL_checkinteger(L, 1); + + lua_settop(L, 0); + opt = curl_easy_option_by_id(id); + if (!opt) { + return 0; + } + + lcurl_easy_option_push(L, opt); + + return 1; +} + +static int lcurl_easy_option_by_name(lua_State *L) { + const struct curl_easyoption *opt = NULL; + const char *name = luaL_checkstring(L, 1); + + lua_settop(L, 0); + opt = curl_easy_option_by_name(name); + if (!opt) { + return 0; + } + + lcurl_easy_option_push(L, opt); + + return 1; +} + +static int lcurl_easy_option_iter(lua_State *L) { + lua_pushcfunction(L, lcurl_easy_option_next); + lua_newtable(L); + return 2; +} + +#endif + static int lcurl_version(lua_State *L){ lua_pushstring(L, curl_version()); return 1; @@ -137,11 +225,26 @@ static int lcurl_version_info(lua_State *L){ #ifdef CURL_VERSION_BROTLI lua_pushliteral(L, "BROTLI"); lua_pushboolean(L, data->features & CURL_VERSION_BROTLI ); lua_rawset(L, -3); #endif +#ifdef CURL_VERSION_ALTSVC + lua_pushliteral(L, "ALTSVC"); lua_pushboolean(L, data->features & CURL_VERSION_ALTSVC ); lua_rawset(L, -3); +#endif +#ifdef CURL_VERSION_HTTP3 + lua_pushliteral(L, "HTTP3"); lua_pushboolean(L, data->features & CURL_VERSION_HTTP3 ); lua_rawset(L, -3); +#endif +#ifdef CURL_VERSION_ZSTD + lua_pushliteral(L, "ZSTD"); lua_pushboolean(L, data->features & CURL_VERSION_ZSTD ); lua_rawset(L, -3); +#endif +#ifdef CURL_VERSION_UNICODE + lua_pushliteral(L, "UNICODE"); lua_pushboolean(L, data->features & CURL_VERSION_UNICODE ); lua_rawset(L, -3); +#endif +#ifdef CURL_VERSION_HSTS + lua_pushliteral(L, "HSTS"); lua_pushboolean(L, data->features & CURL_VERSION_HSTS ); lua_rawset(L, -3); +#endif lua_setfield(L, -2, "features"); /* bitmask, see defines below */ if(data->ssl_version){lua_pushstring(L, data->ssl_version); lua_setfield(L, -2, "ssl_version");} /* human readable string */ - lua_pushnumber(L, data->ssl_version_num); lua_setfield(L, -2, "ssl_version_num"); /* not used anymore, always 0 */ + lutil_pushuint(L, data->ssl_version_num); lua_setfield(L, -2, "ssl_version_num"); /* not used anymore, always 0 */ if(data->libz_version){lua_pushstring(L, data->libz_version); lua_setfield(L, -2, "libz_version");} /* human readable string */ /* protocols is terminated by an entry with a NULL protoname */ @@ -153,7 +256,7 @@ static int lcurl_version_info(lua_State *L){ if(data->age >= CURLVERSION_SECOND){ if(data->ares){lua_pushstring(L, data->ares); lua_setfield(L, -2, "ares");} - lua_pushnumber(L, data->ares_num); lua_setfield(L, -2, "ares_num"); + lutil_pushuint(L, data->ares_num); lua_setfield(L, -2, "ares_num"); } if(data->age >= CURLVERSION_THIRD){ /* added in 7.12.0 */ @@ -162,18 +265,40 @@ static int lcurl_version_info(lua_State *L){ #if LCURL_CURL_VER_GE(7,16,1) if(data->age >= CURLVERSION_FOURTH){ - lua_pushnumber(L, data->iconv_ver_num); lua_setfield(L, -2, "iconv_ver_num"); + lutil_pushuint(L, data->iconv_ver_num); lua_setfield(L, -2, "iconv_ver_num"); if(data->libssh_version){lua_pushstring(L, data->libssh_version);lua_setfield(L, -2, "libssh_version");} } #endif #if LCURL_CURL_VER_GE(7,57,0) if(data->age >= CURLVERSION_FOURTH){ - lua_pushnumber(L, data->brotli_ver_num); lua_setfield(L, -2, "brotli_ver_num"); + lutil_pushuint(L, data->brotli_ver_num); lua_setfield(L, -2, "brotli_ver_num"); if(data->brotli_version){lua_pushstring(L, data->brotli_version);lua_setfield(L, -2, "brotli_version");} } #endif +#if LCURL_CURL_VER_GE(7,66,0) + if(data->age >= CURLVERSION_SIXTH){ + lutil_pushuint(L, data->nghttp2_ver_num); lua_setfield(L, -2, "nghttp2_ver_num"); + if(data->nghttp2_version){lua_pushstring(L, data->nghttp2_version);lua_setfield(L, -2, "nghttp2_version");} + if(data->quic_version){lua_pushstring(L, data->quic_version);lua_setfield(L, -2, "quic_version");} + } +#endif + +#if LCURL_CURL_VER_GE(7,70,0) + if(data->age >= CURLVERSION_SEVENTH){ + if(data->cainfo){lua_pushstring(L, data->cainfo);lua_setfield(L, -2, "cainfo");} + if(data->capath){lua_pushstring(L, data->capath);lua_setfield(L, -2, "capath");} + } +#endif + +#if LCURL_CURL_VER_GE(7,72,0) + if(data->age >= CURLVERSION_EIGHTH){ + lutil_pushuint(L, data->zstd_ver_num); lua_setfield(L, -2, "zstd_ver_num"); + if(data->zstd_version){lua_pushstring(L, data->zstd_version);lua_setfield(L, -2, "zstd_version");} + } +#endif + if(lua_isstring(L, 1)){ lua_pushvalue(L, 1); lua_rawget(L, -2); } @@ -192,7 +317,12 @@ static const struct luaL_Reg lcurl_functions[] = { #endif {"version", lcurl_version }, {"version_info", lcurl_version_info }, - +#if LCURL_CURL_VER_GE(7,73,0) + {"ieasy_options", lcurl_easy_option_iter }, + {"easy_option_by_id", lcurl_easy_option_by_id }, + {"easy_option_by_name", lcurl_easy_option_by_name }, +#endif + {NULL,NULL} }; @@ -207,6 +337,11 @@ static const struct luaL_Reg lcurl_functions_safe[] = { #endif {"version", lcurl_version }, {"version_info", lcurl_version_info }, +#if LCURL_CURL_VER_GE(7,73,0) + {"ieasy_options", lcurl_easy_option_iter }, + {"easy_option_by_id", lcurl_easy_option_by_id }, + {"easy_option_by_name", lcurl_easy_option_by_name }, +#endif {NULL,NULL} };