From 4af7f6a4a0106e35364f42c27deabe128f31807e Mon Sep 17 00:00:00 2001 From: ading2210 Date: Tue, 16 Jan 2024 18:21:19 -0500 Subject: [PATCH] remove usage of asyncify --- README.md | 2 +- client/build.sh | 10 +++--- client/main.c | 50 +++++++++++++++------------ client/main.js | 80 +++++++------------------------------------- client/messages.js | 65 +++++++++++++++++++++++++++++++++++ client/tools/curl.sh | 2 +- 6 files changed, 113 insertions(+), 96 deletions(-) create mode 100644 client/messages.js diff --git a/README.md b/README.md index db1997d..5cbddb6 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ cd libcurl.js/server ./run.sh ``` -You can use the `PORT` and `SOCKS5_PORT` environment variables to control which ports the websocket proxy and the SOCKS5 server run on. +You can use the `HOST` and `PORT` environment variables to control the hostname and port that the proxy server listens on. ## Copyright: This project is licensed under the GNU AGPL v3. diff --git a/client/build.sh b/client/build.sh index 1523b70..3fbbaac 100755 --- a/client/build.sh +++ b/client/build.sh @@ -7,13 +7,14 @@ LIB_DIR="build/curl-wasm/lib/" OUT_FILE="out/libcurl.js" ES6_FILE="out/libcurl_module.mjs" MODULE_FILE="out/emscripten_compiled.js" +FRAGMENTS_DIR="fragments" WRAPPER_SOURCE="main.js" WISP_CLIENT="wisp_client" -EXPORTED_FUNCS="_init_curl,_start_request,_request_loop" +EXPORTED_FUNCS="_init_curl,_start_request,_tick_request,_active_requests" RUNTIME_METHODS="addFunction,removeFunction,allocate,ALLOC_NORMAL" COMPILER_OPTIONS="-o $MODULE_FILE -lcurl -lssl -lcrypto -lcjson -lz -lbrotlidec -lbrotlicommon -I $INCLUDE_DIR -L $LIB_DIR" -EMSCRIPTEN_OPTIONS="-lwebsocket.js -sASYNCIFY -sASYNCIFY_ONLY=start_request,request_loop -sASSERTIONS=1 -sALLOW_TABLE_GROWTH -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS -sEXPORTED_RUNTIME_METHODS=$RUNTIME_METHODS" +EMSCRIPTEN_OPTIONS="-lwebsocket.js -sASSERTIONS=1 -sALLOW_TABLE_GROWTH -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS -sEXPORTED_RUNTIME_METHODS=$RUNTIME_METHODS" if [ "$1" = "release" ]; then COMPILER_OPTIONS="-O3 -flto $COMPILER_OPTIONS" @@ -47,8 +48,9 @@ rm $MODULE_FILE #add wisp libraries sed -i "s/new WebSocketConstructor/new WispWebSocket/" $OUT_FILE -sed -i "/__wisp_libraries__/r $WISP_CLIENT/polyfill.js" $OUT_FILE -sed -i "/__wisp_libraries__/r $WISP_CLIENT/wisp.js" $OUT_FILE +sed -i "/__extra_libraries__/r $WISP_CLIENT/polyfill.js" $OUT_FILE +sed -i "/__extra_libraries__/r $WISP_CLIENT/wisp.js" $OUT_FILE +sed -i "/__extra_libraries__/r ./messages.js" $OUT_FILE #generate es6 module cp $OUT_FILE $ES6_FILE diff --git a/client/main.c b/client/main.c index b43b265..45fcda8 100644 --- a/client/main.c +++ b/client/main.c @@ -26,6 +26,10 @@ struct RequestInfo { EndCallback end_callback; }; +int starts_with(const char *a, const char *b) { + return strncmp(a, b, strlen(b)) == 0; +} + int write_function(void *data, size_t size, size_t nmemb, DataCallback data_callback) { long real_size = size * nmemb; char* chunk = malloc(real_size); @@ -35,30 +39,30 @@ int write_function(void *data, size_t size, size_t nmemb, DataCallback data_call return real_size; } -void request_loop() { +int active_requests() { + return request_active; +} + +void tick_request() { CURLMcode mc; struct CURLMsg *curl_msg; request_active = 1; - do { - mc = curl_multi_perform(multi_handle, &request_active); - - 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; - } + + mc = curl_multi_perform(multi_handle, &request_active); - //ensure we dont block the main thread - emscripten_sleep(0); + if(!mc) + mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL); - int msgq = 0; - curl_msg = curl_multi_info_read(multi_handle, &msgq); - if (curl_msg && curl_msg->msg == CURLMSG_DONE) { - finish_request(curl_msg); - } - } while(request_active); + if(mc) { + fprintf(stderr, "curl_multi_poll() failed, code %d.\n", (int)mc); + return; + } + + int msgq = 0; + curl_msg = curl_multi_info_read(multi_handle, &msgq); + if (curl_msg && curl_msg->msg == CURLMSG_DONE) { + finish_request(curl_msg); + } } void start_request(const char* url, const char* json_params, DataCallback data_callback, EndCallback end_callback, const char* body, int body_length) { @@ -77,6 +81,11 @@ void start_request(const char* url, const char* json_params, DataCallback data_c curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(http_handle, CURLOPT_ACCEPT_ENCODING, ""); + //if url is a websocket, tell curl that we should handle the connection manually + if (starts_with(url, "wss://") || starts_with(url, "ws://")) { + curl_easy_setopt(http_handle, CURLOPT_CONNECT_ONLY, 2L); + } + //parse json options cJSON* request_json = cJSON_Parse(json_params); cJSON* item = NULL; @@ -136,9 +145,6 @@ void start_request(const char* url, const char* json_params, DataCallback data_c curl_easy_setopt(http_handle, CURLOPT_PRIVATE, request_info); curl_multi_add_handle(multi_handle, http_handle); - if (!request_active) { - request_loop(); - } } void finish_request(CURLMsg *curl_msg) { diff --git a/client/main.js b/client/main.js index 2a5d10b..59d1c28 100644 --- a/client/main.js +++ b/client/main.js @@ -4,77 +4,11 @@ window.libcurl = (function() { //emscripten compiled code is inserted here /* __emscripten_output__ */ -//wisp client code goes here -/* __wisp_libraries__ */ +//extra client code goes here +/* __extra_libraries__ */ const websocket_url = `wss://${location.hostname}/ws/`; -const status_messages = { - 100: "Continue", - 101: "Switching Protocols", - 102: "Processing", - 103: "Early Hints", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non-Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 207: "Multi-Status", - 208: "Already Reported", - 226: "IM Used", - 300: "Multiple Choices", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 306: "Switch Proxy", - 307: "Temporary Redirect", - 308: "Permanent Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Payload Too Large", - 414: "URI Too Long", - 415: "Unsupported Media Type", - 416: "Range Not Satisfiable", - 417: "Expectation Failed", - 418: "I'm a teapot", - 421: "Misdirected Request", - 422: "Unprocessable Content", - 423: "Locked", - 424: "Failed Dependency", - 425: "Too Early", - 426: "Upgrade Required", - 428: "Precondition Required", - 429: "Too Many Requests", - 431: "Request Header Fields Too Large", - 451: "Unavailable For Legal Reasons", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported", - 506: "Variant Also Negotiates", - 507: "Insufficient Storage", - 508: "Loop Detected", - 510: "Not Extended", - 511: "Network Authentication Required" -} - //a case insensitive dictionary for request headers class Headers { constructor(obj) { @@ -154,6 +88,16 @@ function perform_request(url, params, js_data_callback, js_end_callback, body=nu data_callback_ptr = Module.addFunction(data_callback, "vii"); _start_request(url_ptr, params_ptr, data_callback_ptr, end_callback_ptr, body_ptr, body_length); _free(params_ptr); + + if (!_active_requests()) { + //time out requests after a while + let event_loop = setInterval(() => { + _tick_request(); + if (!_active_requests()) { + clearInterval(event_loop); + } + }, 500); + } } function merge_arrays(arrays) { diff --git a/client/messages.js b/client/messages.js new file mode 100644 index 0000000..1d1f488 --- /dev/null +++ b/client/messages.js @@ -0,0 +1,65 @@ +const status_messages = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 103: "Early Hints", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status", + 208: "Already Reported", + 226: "IM Used", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Payload Too Large", + 414: "URI Too Long", + 415: "Unsupported Media Type", + 416: "Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", + 421: "Misdirected Request", + 422: "Unprocessable Content", + 423: "Locked", + 424: "Failed Dependency", + 425: "Too Early", + 426: "Upgrade Required", + 428: "Precondition Required", + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage", + 508: "Loop Detected", + 510: "Not Extended", + 511: "Network Authentication Required" +} diff --git a/client/tools/curl.sh b/client/tools/curl.sh index cd4e40e..20fb1cb 100755 --- a/client/tools/curl.sh +++ b/client/tools/curl.sh @@ -17,7 +17,7 @@ git clone -b master --depth=1 https://github.com/curl/curl cd curl autoreconf -fi -emconfigure ./configure --host i686-linux --disable-shared --disable-threaded-resolver --without-libpsl --disable-netrc --disable-ipv6 --disable-tftp --disable-ntlm-wb --with-ssl=$OPENSSL_PREFIX --with-zlib=$ZLIB_PREFIX --with-brotli=$BROTLI_PREFIX +emconfigure ./configure --host i686-linux --disable-shared --disable-threaded-resolver --without-libpsl --disable-netrc --disable-ipv6 --disable-tftp --disable-ntlm-wb --enable-websockets --with-ssl=$OPENSSL_PREFIX --with-zlib=$ZLIB_PREFIX --with-brotli=$BROTLI_PREFIX emmake make -j$CORE_COUNT CFLAGS="-pthread" LIBS="-lbrotlicommon" rm -rf $PREFIX