From fc32c7c1fb51a80e7b66d40ffd7dd7b606d33a0f Mon Sep 17 00:00:00 2001 From: ading2210 Date: Wed, 17 Jan 2024 01:04:43 -0500 Subject: [PATCH] patch js in a better way, fix event loop logic --- .gitignore | 1 + client/build.sh | 13 +++++-------- client/fragments/force_wsproxy.js | 5 +++++ client/fragments/silence_socket.js | 9 +++++++++ client/fragments/wisp_support.js | 4 ++++ client/main.c | 8 -------- client/main.js | 12 +++++++----- client/patcher.py | 26 ++++++++++++++++++++++++++ 8 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 client/fragments/force_wsproxy.js create mode 100644 client/fragments/silence_socket.js create mode 100644 client/fragments/wisp_support.js create mode 100644 client/patcher.py diff --git a/.gitignore b/.gitignore index 7b3cd3e..c322792 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /client/build /client/out +/client/fragments/tmp /server/.venv /server/websockify \ No newline at end of file diff --git a/client/build.sh b/client/build.sh index 3fbbaac..13b5c78 100755 --- a/client/build.sh +++ b/client/build.sh @@ -14,10 +14,10 @@ WISP_CLIENT="wisp_client" 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 -sASSERTIONS=1 -sALLOW_TABLE_GROWTH -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS -sEXPORTED_RUNTIME_METHODS=$RUNTIME_METHODS" +EMSCRIPTEN_OPTIONS="-lwebsocket.js -sASSERTIONS=1 -sALLOW_TABLE_GROWTH -sALLOW_MEMORY_GROWTH -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS -sEXPORTED_RUNTIME_METHODS=$RUNTIME_METHODS" if [ "$1" = "release" ]; then - COMPILER_OPTIONS="-O3 -flto $COMPILER_OPTIONS" + COMPILER_OPTIONS="-Oz -flto $COMPILER_OPTIONS" EMSCRIPTEN_OPTIONS="-sSINGLE_FILE $EMSCRIPTEN_OPTIONS" else COMPILER_OPTIONS="$COMPILER_OPTIONS --profiling" @@ -36,22 +36,19 @@ COMPILE_CMD="emcc main.c $COMPILER_OPTIONS $EMSCRIPTEN_OPTIONS" echo $COMPILE_CMD $COMPILE_CMD -#patch the output to work around some emscripten bugs -sed -i 's/err("__syscall_getsockname " \?+ \?fd);//' $MODULE_FILE -sed -i 's/function _emscripten_console_error(str) {/& if(UTF8ToString(str).endsWith("__syscall_setsockopt\\n")) return;/' $MODULE_FILE -sed -i "s/var \?opts \?= \?undefined;/& var parts=addr.split('\/');url=url+parts[0]+':'+port;/" $MODULE_FILE - #merge compiled emscripten module and wrapper code cp $WRAPPER_SOURCE $OUT_FILE sed -i "/__emscripten_output__/r $MODULE_FILE" $OUT_FILE rm $MODULE_FILE #add wisp libraries -sed -i "s/new WebSocketConstructor/new WispWebSocket/" $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 +#apply patches +python3 patcher.py $FRAGMENTS_DIR $OUT_FILE + #generate es6 module cp $OUT_FILE $ES6_FILE sed -i 's/window.libcurl/export const libcurl/' $ES6_FILE \ No newline at end of file diff --git a/client/fragments/force_wsproxy.js b/client/fragments/force_wsproxy.js new file mode 100644 index 0000000..32993a8 --- /dev/null +++ b/client/fragments/force_wsproxy.js @@ -0,0 +1,5 @@ +/* INSERT +var ?opts ?= ?undefined; +*/ +var parts=addr.split("/"); +url = url + parts[0] + ":" + port; \ No newline at end of file diff --git a/client/fragments/silence_socket.js b/client/fragments/silence_socket.js new file mode 100644 index 0000000..2178f6a --- /dev/null +++ b/client/fragments/silence_socket.js @@ -0,0 +1,9 @@ +/* DELETE +err\("__syscall_getsockname " ?\+ ?fd\); +*/ + + +/* INSERT +function _emscripten_console_error\(str\) { +*/ +if (UTF8ToString(str).endsWith("__syscall_setsockopt\\n")) return; \ No newline at end of file diff --git a/client/fragments/wisp_support.js b/client/fragments/wisp_support.js new file mode 100644 index 0000000..8ed84cd --- /dev/null +++ b/client/fragments/wisp_support.js @@ -0,0 +1,4 @@ +/* REPLACE +new WebSocketConstructor +*/ +new WispWebSocket \ No newline at end of file diff --git a/client/main.c b/client/main.c index 45fcda8..be843ef 100644 --- a/client/main.c +++ b/client/main.c @@ -50,14 +50,6 @@ void tick_request() { 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); - return; - } - int msgq = 0; curl_msg = curl_multi_info_read(multi_handle, &msgq); if (curl_msg && curl_msg->msg == CURLMSG_DONE) { diff --git a/client/main.js b/client/main.js index 59d1c28..0f90b49 100644 --- a/client/main.js +++ b/client/main.js @@ -8,6 +8,7 @@ window.libcurl = (function() { /* __extra_libraries__ */ const websocket_url = `wss://${location.hostname}/ws/`; +var event_loop = null; //a case insensitive dictionary for request headers class Headers { @@ -88,15 +89,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 (!event_loop) { + event_loop = setInterval(() => { _tick_request(); if (!_active_requests()) { clearInterval(event_loop); + event_loop = null; } - }, 500); + }, 0); } } diff --git a/client/patcher.py b/client/patcher.py new file mode 100644 index 0000000..bf06c6d --- /dev/null +++ b/client/patcher.py @@ -0,0 +1,26 @@ +import re +import sys +import pathlib + +match_regex = r'/\* (.+?)\n(.+?)\n\*/\n(.*?)(\n\n|$)' + +fragments_dir = sys.argv[1] +target_dir = sys.argv[2] +fragments_path = pathlib.Path(fragments_dir) +target_path = pathlib.Path(target_dir) +target_text = target_path.read_text() + +for fragment_file in fragments_path.iterdir(): + print(f"applying patch from {fragment_file.name}") + fragment_text = fragment_file.read_text() + matches = re.findall(match_regex, fragment_text, re.S) + + for mode, patch_regex, patch_text, _ in matches: + if mode == "DELETE": + target_text = re.sub(patch_regex, "", target_text) + elif mode == "REPLACE": + target_text = re.sub(patch_regex, patch_text, target_text) + elif mode == "INSERT": + target_text = re.sub("("+patch_regex+")", r'\1'+patch_text, target_text) + +target_path.write_text(target_text) \ No newline at end of file