mirror of
https://github.com/ading2210/libcurl.js.git
synced 2025-05-11 13:30:01 -04:00
patch js in a better way, fix event loop logic
This commit is contained in:
parent
4af7f6a4a0
commit
fc32c7c1fb
8 changed files with 57 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
/client/build
|
/client/build
|
||||||
/client/out
|
/client/out
|
||||||
|
/client/fragments/tmp
|
||||||
/server/.venv
|
/server/.venv
|
||||||
/server/websockify
|
/server/websockify
|
|
@ -14,10 +14,10 @@ WISP_CLIENT="wisp_client"
|
||||||
EXPORTED_FUNCS="_init_curl,_start_request,_tick_request,_active_requests"
|
EXPORTED_FUNCS="_init_curl,_start_request,_tick_request,_active_requests"
|
||||||
RUNTIME_METHODS="addFunction,removeFunction,allocate,ALLOC_NORMAL"
|
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"
|
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
|
if [ "$1" = "release" ]; then
|
||||||
COMPILER_OPTIONS="-O3 -flto $COMPILER_OPTIONS"
|
COMPILER_OPTIONS="-Oz -flto $COMPILER_OPTIONS"
|
||||||
EMSCRIPTEN_OPTIONS="-sSINGLE_FILE $EMSCRIPTEN_OPTIONS"
|
EMSCRIPTEN_OPTIONS="-sSINGLE_FILE $EMSCRIPTEN_OPTIONS"
|
||||||
else
|
else
|
||||||
COMPILER_OPTIONS="$COMPILER_OPTIONS --profiling"
|
COMPILER_OPTIONS="$COMPILER_OPTIONS --profiling"
|
||||||
|
@ -36,22 +36,19 @@ COMPILE_CMD="emcc main.c $COMPILER_OPTIONS $EMSCRIPTEN_OPTIONS"
|
||||||
echo $COMPILE_CMD
|
echo $COMPILE_CMD
|
||||||
$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
|
#merge compiled emscripten module and wrapper code
|
||||||
cp $WRAPPER_SOURCE $OUT_FILE
|
cp $WRAPPER_SOURCE $OUT_FILE
|
||||||
sed -i "/__emscripten_output__/r $MODULE_FILE" $OUT_FILE
|
sed -i "/__emscripten_output__/r $MODULE_FILE" $OUT_FILE
|
||||||
rm $MODULE_FILE
|
rm $MODULE_FILE
|
||||||
|
|
||||||
#add wisp libraries
|
#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/polyfill.js" $OUT_FILE
|
||||||
sed -i "/__extra_libraries__/r $WISP_CLIENT/wisp.js" $OUT_FILE
|
sed -i "/__extra_libraries__/r $WISP_CLIENT/wisp.js" $OUT_FILE
|
||||||
sed -i "/__extra_libraries__/r ./messages.js" $OUT_FILE
|
sed -i "/__extra_libraries__/r ./messages.js" $OUT_FILE
|
||||||
|
|
||||||
|
#apply patches
|
||||||
|
python3 patcher.py $FRAGMENTS_DIR $OUT_FILE
|
||||||
|
|
||||||
#generate es6 module
|
#generate es6 module
|
||||||
cp $OUT_FILE $ES6_FILE
|
cp $OUT_FILE $ES6_FILE
|
||||||
sed -i 's/window.libcurl/export const libcurl/' $ES6_FILE
|
sed -i 's/window.libcurl/export const libcurl/' $ES6_FILE
|
5
client/fragments/force_wsproxy.js
Normal file
5
client/fragments/force_wsproxy.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/* INSERT
|
||||||
|
var ?opts ?= ?undefined;
|
||||||
|
*/
|
||||||
|
var parts=addr.split("/");
|
||||||
|
url = url + parts[0] + ":" + port;
|
9
client/fragments/silence_socket.js
Normal file
9
client/fragments/silence_socket.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/* DELETE
|
||||||
|
err\("__syscall_getsockname " ?\+ ?fd\);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* INSERT
|
||||||
|
function _emscripten_console_error\(str\) {
|
||||||
|
*/
|
||||||
|
if (UTF8ToString(str).endsWith("__syscall_setsockopt\\n")) return;
|
4
client/fragments/wisp_support.js
Normal file
4
client/fragments/wisp_support.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/* REPLACE
|
||||||
|
new WebSocketConstructor
|
||||||
|
*/
|
||||||
|
new WispWebSocket
|
|
@ -50,14 +50,6 @@ void tick_request() {
|
||||||
|
|
||||||
mc = curl_multi_perform(multi_handle, &request_active);
|
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;
|
int msgq = 0;
|
||||||
curl_msg = curl_multi_info_read(multi_handle, &msgq);
|
curl_msg = curl_multi_info_read(multi_handle, &msgq);
|
||||||
if (curl_msg && curl_msg->msg == CURLMSG_DONE) {
|
if (curl_msg && curl_msg->msg == CURLMSG_DONE) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ window.libcurl = (function() {
|
||||||
/* __extra_libraries__ */
|
/* __extra_libraries__ */
|
||||||
|
|
||||||
const websocket_url = `wss://${location.hostname}/ws/`;
|
const websocket_url = `wss://${location.hostname}/ws/`;
|
||||||
|
var event_loop = null;
|
||||||
|
|
||||||
//a case insensitive dictionary for request headers
|
//a case insensitive dictionary for request headers
|
||||||
class 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");
|
data_callback_ptr = Module.addFunction(data_callback, "vii");
|
||||||
_start_request(url_ptr, params_ptr, data_callback_ptr, end_callback_ptr, body_ptr, body_length);
|
_start_request(url_ptr, params_ptr, data_callback_ptr, end_callback_ptr, body_ptr, body_length);
|
||||||
_free(params_ptr);
|
_free(params_ptr);
|
||||||
|
|
||||||
if (!_active_requests()) {
|
_tick_request();
|
||||||
//time out requests after a while
|
if (!event_loop) {
|
||||||
let event_loop = setInterval(() => {
|
event_loop = setInterval(() => {
|
||||||
_tick_request();
|
_tick_request();
|
||||||
if (!_active_requests()) {
|
if (!_active_requests()) {
|
||||||
clearInterval(event_loop);
|
clearInterval(event_loop);
|
||||||
|
event_loop = null;
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
client/patcher.py
Normal file
26
client/patcher.py
Normal file
|
@ -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)
|
Loading…
Add table
Add a link
Reference in a new issue