From 465fa2e17015b031c5f1ffc309b78d3a960caf3b Mon Sep 17 00:00:00 2001 From: ading2210 Date: Wed, 3 Jan 2024 02:27:32 -0500 Subject: [PATCH] use curl multi interface for async support --- client/build.sh | 11 +++++--- client/index.html | 1 + client/main.c | 68 ++++++++++++++++++++++++++++++----------------- 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/client/build.sh b/client/build.sh index 5db64ab..119cea6 100755 --- a/client/build.sh +++ b/client/build.sh @@ -5,14 +5,19 @@ LIB_DIR="build/curl-wasm/lib/" CACERT_FILE="cacert.pem" OUT_FILE="out/libcurl.js" -EXPORTED_FUNCS="_main" -COMPILER_OPTIONS="-o $OUT_FILE -Os -lcurl -lssl -lcrypto -I $INCLUDE_DIR -L $LIB_DIR" -EMSCRIPTEN_OPTIONS="-lwebsocket.js -sWEBSOCKET_URL=wss://debug.ading.dev/ws -pthread -sPROXY_TO_PTHREAD -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS --preload-file $CACERT_FILE" +EXPORTED_FUNCS="_main,_do_request" +COMPILER_OPTIONS="-o $OUT_FILE -lcurl -lssl -lcrypto -I $INCLUDE_DIR -L $LIB_DIR" +EMSCRIPTEN_OPTIONS="-lwebsocket.js -sWEBSOCKET_URL=wss://debug.ading.dev/ws -sASYNCIFY -sALLOW_UNIMPLEMENTED_SYSCALLS -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS --preload-file $CACERT_FILE" if [ ! -f $CACERT_FILE ]; then wget "https://curl.se/ca/cacert.pem" -O $CACERT_FILE fi +if [ ! -d $INCLUDE_DIR ]; then + tools/openssl.sh + tools/curl.sh +fi + COMPILE_CMD="emcc main.c $COMPILER_OPTIONS $EMSCRIPTEN_OPTIONS" echo $COMPILE_CMD $COMPILE_CMD diff --git a/client/index.html b/client/index.html index 55bd031..e782a22 100644 --- a/client/index.html +++ b/client/index.html @@ -3,6 +3,7 @@ +

emscripten tests

diff --git a/client/main.c b/client/main.c index 37e4e61..5215a9e 100644 --- a/client/main.c +++ b/client/main.c @@ -1,34 +1,52 @@ +#include "emscripten/emscripten.h" #include #include +#include -int main() { - CURL *curl; - CURLcode res; - - char* url = "https://ading.dev/"; - +int do_request(const char* url) { printf("downloading %s\n", url); + + CURL *http_handle; + CURLM *multi_handle; + int still_running = 1; - curl = curl_easy_init(); - if (curl) { - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_PROXY, "socks5h://127.0.0.1:1234"); - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); - curl_easy_setopt(curl, CURLOPT_CAINFO, "/cacert.pem"); - curl_easy_setopt(curl, CURLOPT_CAPATH, "/cacert.pem"); - - /* example.com is redirected, so we tell libcurl to follow redirection */ - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_global_init(CURL_GLOBAL_DEFAULT); + http_handle = curl_easy_init(); - /* Perform the request, res will get the return code */ - res = curl_easy_perform(curl); - /* Check for errors */ - if(res != CURLE_OK) - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(res)); + curl_easy_setopt(http_handle, CURLOPT_URL, url); + curl_easy_setopt(http_handle, CURLOPT_PROXY, "socks5h://127.0.0.1:1234"); + curl_easy_setopt(http_handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); + curl_easy_setopt(http_handle, CURLOPT_CAINFO, "/cacert.pem"); + curl_easy_setopt(http_handle, CURLOPT_CAPATH, "/cacert.pem"); + + multi_handle = curl_multi_init(); + curl_multi_add_handle(multi_handle, http_handle); + + do { + CURLMcode mc = curl_multi_perform(multi_handle, &still_running); + + if(!mc) + mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL); + + if(mc) { + fprintf(stderr, "curl_multi_poll() failed, code %d.\n", (int)mc); + break; + } + + //ensure we dont block the main thread + emscripten_sleep(0); + + } while(still_running); + + curl_multi_remove_handle(multi_handle, http_handle); + curl_easy_cleanup(http_handle); + curl_multi_cleanup(multi_handle); + curl_global_cleanup(); - /* always cleanup */ - curl_easy_cleanup(curl); - } return 0; +} + +int main() { + printf("emscripten libcurl module loaded\n"); + do_request("https://ifconfig.me/all"); } \ No newline at end of file