aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-24 10:12:51 -0400
committerChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-03-24 10:12:51 -0400
commit966bdd6e94555f0889e7661f4dcc85ee0a5d38bc (patch)
tree001f91f9d51650c9537db975313f486563a2fb00 /src
parentnative: fix two potential runoffs (diff)
native: ok this is kind of big, see rest of message
splitting this like usual was too much effort sorry * implement mime-headers * move util stuff out of jurl.c * reorganize header a bit (will do more of this soon) * make cleanup universal * wrap slist generation
Diffstat (limited to 'src')
-rw-r--r--src/cleanup.c24
-rw-r--r--src/jurl.c79
-rw-r--r--src/jurl.h30
-rw-r--r--src/mime.c18
-rw-r--r--src/setopt.c2
-rw-r--r--src/util.c72
6 files changed, 131 insertions, 94 deletions
diff --git a/src/cleanup.c b/src/cleanup.c
new file mode 100644
index 0000000..5e387a3
--- /dev/null
+++ b/src/cleanup.c
@@ -0,0 +1,24 @@
+#include "jurl.h"
+
+void jurl_do_cleanup(struct jurl_cleanup **src) {
+ while (src) {
+ struct jurl_cleanup *cur = *src;
+ switch (cur->type) {
+ case JURL_CLEANUP_TYPE_SLIST:
+ curl_slist_free_all(cur->slist);
+ break;
+ default:
+ janet_panic("unknown type of cleanup data in do_cleanup");
+ }
+ *src = cur->next;
+ free(cur);
+ }
+}
+
+struct jurl_cleanup *register_cleanup(struct jurl_cleanup **prev, enum jurl_cleanup_type type) {
+ struct jurl_cleanup *out = malloc(sizeof(struct jurl_cleanup));
+ out->next = *prev;
+ *prev = out;
+ out->type = type;
+ return out;
+}
diff --git a/src/jurl.c b/src/jurl.c
index 7b15d5b..1b74ea2 100644
--- a/src/jurl.c
+++ b/src/jurl.c
@@ -5,18 +5,7 @@ static int jurl_gc(void *p, size_t s) {
(void) s;
jurl_handle *jurl = (jurl_handle*)p;
if (jurl->handle) curl_easy_cleanup(jurl->handle);
- while (jurl->cleanup) {
- struct jurl_cleanup *cur = jurl->cleanup;
- switch (cur->type) {
- case JURL_CLEANUP_TYPE_SLIST:
- curl_slist_free_all(cur->slist);
- break;
- default:
- janet_panic("unknown type of cleanup data in jurl_gc");
- }
- jurl->cleanup = cur->next;
- free(cur);
- }
+ jurl_do_cleanup(&jurl->cleanup);
return 0;
}
@@ -72,64 +61,6 @@ jurl_handle *janet_getjurl(Janet *argv, int32_t n) {
return (jurl_handle*)janet_getabstract(argv, n, &jurl_type);
}
-// this function plays fast and loose and I hope the gc doesn't kill me for it
-// anyway, it goes like so:
-// (wrap-error :ok something) -> [:ok something]
-// (wrap-error :err something) -> [:err "explanation of :err"]
-JANET_CFUN(jurl_wrap_error) {
- janet_fixarity(argc, 2);
- CURLcode code;
- if (janet_checktype(argv[0], JANET_NUMBER)) {
- argv[0] = jurl_geterror(janet_getinteger(argv, 0));
- }
- if (!janet_checktype(argv[0], JANET_KEYWORD)) {
- janet_panicf("jurl_wrap_error: expected number or keyword, got %T", janet_type(argv[0]));
- }
- if (!janet_keyeq(argv[0], "ok")) {
- // will this break one day?
- // find out next time!
- argv[1] = jurl_strerror(1, argv);
- }
- return janet_wrap_tuple(janet_tuple_n(argv, 2));
-}
-
-JANET_CFUN(jurl_escape) {
- janet_fixarity(argc, 1);
- JanetByteView b = janet_getbytes(argv, 0);
- CURL* curl;
-#if !CURL_AT_LEAST_VERSION(7,82,0)
- curl = curl_easy_init();
-#endif
-
- char *s = curl_easy_escape(curl, (const char*)b.bytes, b.len);
- Janet out = janet_cstringv(s);
-
- curl_free(s);
-#if !CURL_AT_LEAST_VERSION(7,82,0)
- curl_easy_cleanup(curl);
-#endif
- return out;
-}
-
-JANET_CFUN(jurl_unescape) {
- janet_fixarity(argc, 1);
- JanetByteView b = janet_getbytes(argv, 0);
- CURL *curl;
-#if !CURL_AT_LEAST_VERSION(7,82,0)
- curl = curl_easy_init();
-#endif
-
- int len;
- char *s = curl_easy_unescape(curl, (const char*)b.bytes, b.len, &len);
- Janet out = janet_stringv((const uint8_t*)s, len);
-
- curl_free(s);
-#if !CURL_AT_LEAST_VERSION(7,82,0)
- curl_easy_cleanup(curl);
-#endif
- return out;
-}
-
JANET_CFUN(jurl_new) {
janet_fixarity(argc, 0);
jurl_handle *jurl = (jurl_handle*)janet_abstract(&jurl_type, sizeof(jurl_handle));
@@ -138,14 +69,6 @@ JANET_CFUN(jurl_new) {
return janet_wrap_abstract(jurl);
}
-struct jurl_cleanup *register_cleanup(jurl_handle *jurl, enum jurl_cleanup_type type) {
- struct jurl_cleanup *out = malloc(sizeof(struct jurl_cleanup));
- out->next = jurl->cleanup;
- jurl->cleanup = out;
- out->type = type;
- return out;
-}
-
JANET_CFUN(jurl_reset) {
janet_fixarity(argc, 1);
jurl_handle *jurl = janet_getjurl(argv, 0);
diff --git a/src/jurl.h b/src/jurl.h
index e6e23df..4b54165 100644
--- a/src/jurl.h
+++ b/src/jurl.h
@@ -2,7 +2,7 @@
#include <curl/curl.h>
#include <janet.h>
-// jurl globals
+// cleanup.c
enum jurl_cleanup_type {
JURL_CLEANUP_TYPE_SLIST,
};
@@ -14,40 +14,40 @@ struct jurl_cleanup {
};
};
+struct jurl_cleanup *register_cleanup(struct jurl_cleanup **prev, enum jurl_cleanup_type type);
+void jurl_do_cleanup(struct jurl_cleanup **src);
+
+// jurl.c
struct jurl_handle {
CURL* handle;
struct jurl_cleanup* cleanup;
};
typedef struct jurl_handle jurl_handle;
-// jurl.c
-struct jurl_cleanup *register_cleanup(jurl_handle *jurl, enum jurl_cleanup_type type);
-JANET_CFUN(jurl_escape);
-JANET_CFUN(jurl_unescape);
JANET_CFUN(jurl_new);
JANET_CFUN(jurl_reset);
JANET_CFUN(jurl_dup);
JANET_CFUN(jurl_perform);
-JANET_CFUN(jurl_wrap_error);
jurl_handle *janet_getjurl(Janet *argv, int32_t n);
-// jurl_callbacks.c
+// callbacks.c
CURLcode jurl_setcallback(jurl_handle *jurl, CURLoption opt, JanetFunction *fun);
-// jurl_enums.c
+// enums.c
CURLcode jurl_setenum(jurl_handle *jurl, CURLoption opt, Janet val);
-// jurl_errors.c
+// errors.c
Janet jurl_geterror(CURLcode code);
JANET_CFUN(jurl_strerror);
-// jurl_getinfo.c
+// getinfo.c
JANET_CFUN(jurl_getinfo);
-// jurl_mime.c
+// mime.c
struct jurl_mime {
CURL *curl;
curl_mime *handle;
+ struct jurl_cleanup* cleanup;
int clean;
};
typedef struct jurl_mime jurl_mime;
@@ -64,5 +64,11 @@ JANET_CFUN(jurl_mime_encoder);
JANET_CFUN(jurl_mime_subparts);
jurl_mime *janet_getjurlmime(Janet *argv, int32_t n);
-// jurl_setopt.c
+// setopt.c
JANET_CFUN(jurl_setopt);
+
+// util.c
+int janet_getslist(struct curl_slist **slist, Janet *argv, int32_t n);
+JANET_CFUN(jurl_escape);
+JANET_CFUN(jurl_unescape);
+JANET_CFUN(jurl_wrap_error);
diff --git a/src/mime.c b/src/mime.c
index 078d02f..c29eb1f 100644
--- a/src/mime.c
+++ b/src/mime.c
@@ -6,6 +6,7 @@ static int jurl_mime_gc(void *p, size_t s) {
jurl_mime *mime = (jurl_mime*)p;
if (mime->clean) curl_mime_free(mime->handle);
curl_easy_cleanup(mime->curl);
+ jurl_do_cleanup(&mime->cleanup);
return 0;
}
@@ -182,10 +183,21 @@ JANET_CFUN(jurl_mime_type) {
return jurl_geterror(ret);
}
-// TODO: really? I have to do cleanup *again*? ;-;
+// due to how the cleanup works, I either have to convert mimepart to an abstract
+// or also pass through the mime
+// I opt for option 2 for now
+// note that the part MUST belong to the mime
JANET_CFUN(jurl_mime_headers) {
- janet_panic("not implemented");
- return janet_wrap_nil(); // unreachable
+ janet_fixarity(argc, 3);
+ jurl_mime *mime = janet_getjurlmime(argv, 0);
+ curl_mimepart *part = (curl_mimepart*)janet_getpointer(argv, 1);
+ struct jurl_cleanup *clean = register_cleanup(&mime->cleanup, JURL_CLEANUP_TYPE_SLIST);
+ if (!janet_getslist(&clean->slist, argv, 2)) {
+ janet_panicf("failed to get slist in jurl_mime_headers, got %v", argv[2]);
+ }
+ return jurl_geterror(
+ curl_mime_headers(part, clean->slist, 0)
+ );
}
JANET_CFUN(jurl_mime_encoder) {
diff --git a/src/setopt.c b/src/setopt.c
index e000731..cabb9a6 100644
--- a/src/setopt.c
+++ b/src/setopt.c
@@ -417,7 +417,7 @@ JANET_CFUN(jurl_setopt) {
break;
case JURL_PARAMTYPE_SLIST: {
// we register the cleanup ahead of time, because...
- struct jurl_cleanup *clean = register_cleanup(jurl, JURL_CLEANUP_TYPE_SLIST);
+ struct jurl_cleanup *clean = register_cleanup(&jurl->cleanup, JURL_CLEANUP_TYPE_SLIST);
JanetView args = janet_getindexed(argv, 2);
for (int32_t i = 0; i < args.len; i++) {
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..a9a526b
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,72 @@
+#include "jurl.h"
+
+int janet_getslist(struct curl_slist **slist, Janet *argv, int32_t n) {
+ JanetView args = janet_getindexed(argv, n);
+ for (int32_t i = 0; i< args.len; i++) {
+ const char *s = janet_getcstring(args.items, i);
+ struct curl_slist *newlist = curl_slist_append(*slist, s);
+ if (!newlist) {
+ return 0;
+ }
+ *slist = newlist;
+ }
+ return 1;
+}
+
+JANET_CFUN(jurl_escape) {
+ janet_fixarity(argc, 1);
+ JanetByteView b = janet_getbytes(argv, 0);
+ CURL* curl;
+#if !CURL_AT_LEAST_VERSION(7,82,0)
+ curl = curl_easy_init();
+#endif
+
+ char *s = curl_easy_escape(curl, (const char*)b.bytes, b.len);
+ Janet out = janet_cstringv(s);
+
+ curl_free(s);
+#if !CURL_AT_LEAST_VERSION(7,82,0)
+ curl_easy_cleanup(curl);
+#endif
+ return out;
+}
+
+JANET_CFUN(jurl_unescape) {
+ janet_fixarity(argc, 1);
+ JanetByteView b = janet_getbytes(argv, 0);
+ CURL *curl;
+#if !CURL_AT_LEAST_VERSION(7,82,0)
+ curl = curl_easy_init();
+#endif
+
+ int len;
+ char *s = curl_easy_unescape(curl, (const char*)b.bytes, b.len, &len);
+ Janet out = janet_stringv((const uint8_t*)s, len);
+
+ curl_free(s);
+#if !CURL_AT_LEAST_VERSION(7,82,0)
+ curl_easy_cleanup(curl);
+#endif
+ return out;
+}
+
+// this function plays fast and loose and I hope the gc doesn't kill me for it
+// anyway, it goes like so:
+// (wrap-error :ok something) -> [:ok something]
+// (wrap-error :err something) -> [:err "explanation of :err"]
+JANET_CFUN(jurl_wrap_error) {
+ janet_fixarity(argc, 2);
+ CURLcode code;
+ if (janet_checktype(argv[0], JANET_NUMBER)) {
+ argv[0] = jurl_geterror(janet_getinteger(argv, 0));
+ }
+ if (!janet_checktype(argv[0], JANET_KEYWORD)) {
+ janet_panicf("jurl_wrap_error: expected number or keyword, got %T", janet_type(argv[0]));
+ }
+ if (!janet_keyeq(argv[0], "ok")) {
+ // will this break one day?
+ // find out next time!
+ argv[1] = jurl_strerror(1, argv);
+ }
+ return janet_wrap_tuple(janet_tuple_n(argv, 2));
+}