aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-26 13:59:11 -0400
committerChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-26 13:59:11 -0400
commitec6e4f972d0f20e015e10cc7e324674877a6860b (patch)
treee6ee347aa49664afac5f3135678b58cb7797e11f /src
parentjanet: implement headers and cookies (diff)
native: implement getinfo on enums and bitmasks
Diffstat (limited to 'src')
-rw-r--r--src/enums.c103
-rw-r--r--src/getinfo.c26
-rw-r--r--src/jurl.h2
3 files changed, 122 insertions, 9 deletions
diff --git a/src/enums.c b/src/enums.c
index fd6d9bb..1c7ca2e 100644
--- a/src/enums.c
+++ b/src/enums.c
@@ -1,6 +1,9 @@
-// enums.c: implements curl_easy_setopt options that take bitmasks or a specific value
+// enums.c: implements
+// * curl_easy_setopt options that take bitmasks or a specific value
+// * curl_easy_getinfo options that return bitmasks or a specific value
#include "jurl.h"
+// setopt section
struct jurl_enum {
CURLoption opt;
long value;
@@ -198,3 +201,101 @@ CURLcode jurl_setenum(jurl_handle *jurl, CURLoption opt, Janet val) {
}
return curl_easy_setopt(jurl->handle, opt, set);
}
+
+// getinfo section
+struct jurl_info_enum {
+ CURLINFO info;
+ long code;
+ const char *keyword;
+};
+
+static struct jurl_info_enum info_enums[] = {
+ {CURLINFO_HTTP_VERSION, 0, "http-version/cannot-determine"},
+ {CURLINFO_HTTP_VERSION, CURL_HTTP_VERSION_1_0, "http-version/1.0"},
+ {CURLINFO_HTTP_VERSION, CURL_HTTP_VERSION_1_1, "http-version/1.1"},
+ {CURLINFO_HTTP_VERSION, CURL_HTTP_VERSION_2_0, "http-version/2.0"},
+ {CURLINFO_HTTP_VERSION, CURL_HTTP_VERSION_3, "http-version/3"},
+
+ {CURLINFO_PROXY_ERROR, CURLPX_OK, "proxy-error/ok"},
+ {CURLINFO_PROXY_ERROR, CURLPX_BAD_ADDRESS_TYPE, "proxy-error/bad-address-type"},
+ {CURLINFO_PROXY_ERROR, CURLPX_BAD_VERSION, "proxy-error/bad-version"},
+ {CURLINFO_PROXY_ERROR, CURLPX_CLOSED, "proxy-error/closed"},
+ {CURLINFO_PROXY_ERROR, CURLPX_GSSAPI, "proxy-error/gssapi"},
+ {CURLINFO_PROXY_ERROR, CURLPX_GSSAPI_PERMSG, "proxy-error/gssapi-permsg"},
+ {CURLINFO_PROXY_ERROR, CURLPX_GSSAPI_PROTECTION, "proxy-error/gssapi-protection"},
+ {CURLINFO_PROXY_ERROR, CURLPX_IDENTD, "proxy-error/identd"},
+ {CURLINFO_PROXY_ERROR, CURLPX_IDENTD_DIFFER, "proxy-error/identd-differ"},
+ {CURLINFO_PROXY_ERROR, CURLPX_LONG_HOSTNAME, "proxy-error/long-hostname"},
+ {CURLINFO_PROXY_ERROR, CURLPX_LONG_PASSWD, "proxy-error/long-passwd"},
+ {CURLINFO_PROXY_ERROR, CURLPX_LONG_USER, "proxy-error/long-user"},
+ {CURLINFO_PROXY_ERROR, CURLPX_NO_AUTH, "proxy-error/no-auth"},
+ {CURLINFO_PROXY_ERROR, CURLPX_RECV_ADDRESS, "proxy-error/recv-address"},
+ {CURLINFO_PROXY_ERROR, CURLPX_RECV_AUTH, "proxy-error/recv-auth"},
+ {CURLINFO_PROXY_ERROR, CURLPX_RECV_CONNECT, "proxy-error/connect"},
+ {CURLINFO_PROXY_ERROR, CURLPX_RECV_REQACK, "proxy-error/reqack"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED, "proxy-error/reply-address-type-not-supported"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_COMMAND_NOT_SUPPORTED, "proxy-error/reply-command-not-supported"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_CONNECTION_REFUSED, "proxy-error/reply-connection-refused"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_GENERAL_SERVER_FAILURE, "proxy-error/reply-general-server-failure"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_HOST_UNREACHABLE, "proxy-error/reply-host-unreachable"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_NETWORK_UNREACHABLE, "proxy-error/reply-network-unreachable"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_NOT_ALLOWED, "proxy-error/reply-not-allowed"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_TTL_EXPIRED, "proxy-error/reply-ttl-expired"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REPLY_UNASSIGNED, "proxy-error/reply-unassigned"},
+ {CURLINFO_PROXY_ERROR, CURLPX_REQUEST_FAILED, "proxy-error/request-failed"},
+ {CURLINFO_PROXY_ERROR, CURLPX_RESOLVE_HOST, "proxy-error/resolve-host"},
+ {CURLINFO_PROXY_ERROR, CURLPX_SEND_AUTH, "proxy-error/send-auth"},
+ {CURLINFO_PROXY_ERROR, CURLPX_SEND_CONNECT, "proxy-error/send-connect"},
+ {CURLINFO_PROXY_ERROR, CURLPX_SEND_REQUEST, "proxy-error/send-request"},
+ {CURLINFO_PROXY_ERROR, CURLPX_UNKNOWN_FAIL, "proxy-error/unknown-fail"},
+ {CURLINFO_PROXY_ERROR, CURLPX_UNKNOWN_MODE, "proxy-error/unknown-mode"},
+ {CURLINFO_PROXY_ERROR, CURLPX_USER_REJECTED, "proxy-error/user-rejected"},
+
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_BASIC, "basic"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_DIGEST, "digest"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_DIGEST_IE, "digest-ie"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_BEARER, "bearer"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_NEGOTIATE, "negotiate"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_NTLM, "ntlm"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_NTLM_WB, "ntlm-wb"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_ANY, "any"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_ANYSAFE, "anysafe"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_ONLY, "only"},
+ {CURLINFO_HTTPAUTH_AVAIL, CURLAUTH_AWS_SIGV4, "aws-sigv4"},
+
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_BASIC, "basic"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_DIGEST, "digest"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_DIGEST_IE, "digest-ie"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_BEARER, "bearer"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_NEGOTIATE, "negotiate"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_NTLM, "ntlm"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_NTLM_WB, "ntlm-wb"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_ANY, "any"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_ANYSAFE, "anysafe"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_ONLY, "only"},
+ {CURLINFO_PROXYAUTH_AVAIL, CURLAUTH_AWS_SIGV4, "aws-sigv4"},
+};
+#define jurl_info_size (sizeof(info_enums) / sizeof(struct jurl_info_enum))
+
+// these must be separate because the semantics differ greatly
+Janet jurl_getinfoenum(CURLINFO info, long code) {
+ for (size_t i = 0; i < jurl_info_size; i++) {
+ if (info_enums[i].info == info && info_enums[i].code == code) {
+ return janet_ckeywordv(info_enums[i].keyword);
+ }
+ }
+ janet_panicf("jurl_getinfo: unrecognized code for option %d: %d", info, code);
+}
+
+Janet jurl_getinfomask(CURLINFO info, long code) {
+ JanetArray *arr = janet_array(0);
+
+ for (size_t i = 0; i < jurl_info_size; i++) {
+ if (info_enums[i].info == info && (code & info_enums[i].code)) {
+ janet_array_ensure(arr, arr->count + 1, 1);
+ janet_array_push(arr, janet_ckeywordv(info_enums[i].keyword));
+ }
+ }
+
+ return janet_wrap_array(arr);
+}
diff --git a/src/getinfo.c b/src/getinfo.c
index 542d599..8d41b97 100644
--- a/src/getinfo.c
+++ b/src/getinfo.c
@@ -115,30 +115,35 @@ JANET_CFUN(jurl_getinfo) {
janet_panic("could not find option to set in jurl_getinfo");
}
+ CURLcode res;
switch(opt->type) {
case JURL_PARAMTYPE_STRING: {
char *out;
- CURLcode res = curl_easy_getinfo(curl, opt->info, &out);
+ res = curl_easy_getinfo(curl, opt->info, &out);
if (res != CURLE_OK) janet_panic("getinfo returned != CURLE_OK");
return janet_cstringv(out);
}
case JURL_PARAMTYPE_LONG: {
long out;
- CURLcode res = curl_easy_getinfo(curl, opt->info, &out);
+ res = curl_easy_getinfo(curl, opt->info, &out);
if (res != CURLE_OK) janet_panic("getinfo returned != CURLE_OK");
return janet_wrap_integer(out);
}
- case JURL_PARAMTYPE_ENUM: // TODO
- janet_panic("jurl_getinfo: enums not implemented");
+ case JURL_PARAMTYPE_ENUM: {
+ long out;
+ res = curl_easy_getinfo(curl, opt->info, &out);
+ if (res != CURLE_OK) janet_panic("getinfo returned != CURLE_OK");
+ return jurl_getinfoenum(opt->info, out);
+ }
case JURL_PARAMTYPE_OFF_T: {
curl_off_t out;
- CURLcode res = curl_easy_getinfo(curl, opt->info, &out);
+ res = curl_easy_getinfo(curl, opt->info, &out);
if (res != CURLE_OK) janet_panic("getinfo returned != CURLE_OK");
return janet_wrap_integer(out);
}
case JURL_PARAMTYPE_SLIST: {
struct curl_slist *slist;
- CURLcode res = curl_easy_getinfo(curl, opt->info, &slist);
+ res = curl_easy_getinfo(curl, opt->info, &slist);
if (res != CURLE_OK) janet_panic("getinfo returned != CURLE_OK");
// we iterate twice to avoid allocating n times
@@ -161,11 +166,16 @@ JANET_CFUN(jurl_getinfo) {
curl_slist_free_all(slist);
return janet_wrap_array(out);
}
- case JURL_PARAMTYPE_BITMASK: // TODO
+ case JURL_PARAMTYPE_BITMASK: {
+ long out;
+ res = curl_easy_getinfo(curl, opt->info, &out);
+ if (res != CURLE_OK) janet_panic("getinfo returned != CURLE_OK");
+ return jurl_getinfomask(opt->info, out);
+ }
janet_panic("jurl_getinfo: bitmasks not implemented");
case JURL_PARAMTYPE_BOOLEAN: {
long out;
- CURLcode res = curl_easy_getinfo(curl, opt->info, &out);
+ res = curl_easy_getinfo(curl, opt->info, &out);
if (res != CURLE_OK) janet_panic("getinfo returned != CURLE_OK");
return janet_wrap_boolean(out);
}
diff --git a/src/jurl.h b/src/jurl.h
index bf3bd72..0364e3b 100644
--- a/src/jurl.h
+++ b/src/jurl.h
@@ -49,6 +49,8 @@ struct jurl_cleanup *register_cleanup(struct jurl_cleanup **prev, enum jurl_clea
// enums.c
CURLcode jurl_setenum(jurl_handle *jurl, CURLoption opt, Janet val);
+Janet jurl_getinfoenum(CURLINFO info, long code);
+Janet jurl_getinfomask(CURLINFO info, long code);
// errors.c
Janet jurl_geterror(CURLcode code);