update wisp server, fix some memory issues

This commit is contained in:
ading2210 2024-06-30 23:14:44 -07:00
parent 8ac0f40896
commit 11795d2772
8 changed files with 57 additions and 46 deletions

View file

@ -42,7 +42,6 @@ This is an experimental port of [libcurl](https://curl.se/libcurl/) to WebAssemb
- Works in all major browsers (Chromium >= 64, Firefox >= 65, Safari >= 14)
- Has the ability to create multiple independent sessions
- Small footprint size (800kb after compression) and low runtime memory usage
- Support for running inside a web worker
- Support for Brotli and gzip compressed responses
## Building:

View file

@ -55,7 +55,10 @@ class HTTPSession extends CurlSession {
resolve(response);
}
let finish_callback = (error) => {
_free(body_ptr);
if (body_ptr != null) {
_free(body_ptr);
body_ptr = null;
}
if (error > 0) {
error_msg(`Request "${url}" failed with error code ${error}: ${get_error_str(error)}`);
reject(`Request failed with error code ${error}: ${get_error_str(error)}`);

View file

@ -8,6 +8,18 @@ class CurlSession {
this.event_loop = null;
this.requests_list = [];
this.to_remove = [];
this.end_callback_ptr = Module.addFunction((request_id, error) => {
this.end_callback(request_id, error);
}, "vii");
this.headers_callback_ptr = Module.addFunction((request_id, chunk_ptr, chunk_size) => {
this.headers_callback(request_id, chunk_ptr, chunk_size)
}, "viii");
this.data_callback_ptr = Module.addFunction((request_id, chunk_ptr, chunk_size) => {
this.data_callback(request_id, chunk_ptr, chunk_size)
}, "viii");
this.request_callbacks = {};
this.last_request_id = 0;
}
assert_ready() {
@ -21,37 +33,36 @@ class CurlSession {
_session_set_options(this.session_ptr, connections_limit, cache_limit);
}
end_callback(request_id, error) {
this.active_requests--;
this.request_callbacks[request_id].end(error);
delete this.request_callbacks[request_id];
}
data_callback(request_id, chunk_ptr, chunk_size) {
let data = Module.HEAPU8.subarray(chunk_ptr, chunk_ptr + chunk_size);
let chunk = new Uint8Array(data);
this.request_callbacks[request_id].data(chunk);
}
headers_callback(request_id, chunk_ptr, chunk_size) {
let data = Module.HEAPU8.subarray(chunk_ptr, chunk_ptr + chunk_size);
let chunk = new Uint8Array(data);
this.request_callbacks[request_id].headers(chunk);
}
create_request(url, js_data_callback, js_end_callback, js_headers_callback) {
this.assert_ready();
let end_callback_ptr;
let data_callback_ptr;
let headers_callback_ptr;
let end_callback = (error) => {
Module.removeFunction(end_callback_ptr);
Module.removeFunction(data_callback_ptr);
this.active_requests--;
js_end_callback(error);
let request_id = this.last_request_id++;
this.request_callbacks[request_id] = {
end: js_end_callback,
data: js_data_callback,
headers: js_headers_callback
}
let data_callback = (chunk_ptr, chunk_size) => {
let data = Module.HEAPU8.subarray(chunk_ptr, chunk_ptr + chunk_size);
let chunk = new Uint8Array(data);
js_data_callback(chunk);
}
let headers_callback = (chunk_ptr, chunk_size) => {
let data = Module.HEAPU8.subarray(chunk_ptr, chunk_ptr + chunk_size);
let chunk = new Uint8Array(data);
js_headers_callback(chunk);
}
end_callback_ptr = Module.addFunction(end_callback, "vi");
headers_callback_ptr = Module.addFunction(headers_callback, "vii");
data_callback_ptr = Module.addFunction(data_callback, "vii");
let request_ptr = c_func(_create_request, [url, data_callback_ptr, end_callback_ptr, headers_callback_ptr]);
let request_ptr = c_func(_create_request, [
url, request_id, this.data_callback_ptr, this.end_callback_ptr, this.headers_callback_ptr
]);
return request_ptr;
}
@ -109,6 +120,9 @@ class CurlSession {
}
_session_cleanup(this.session_ptr);
this.session_ptr = null;
Module.removeFunction(this.end_callback_ptr);
Module.removeFunction(this.headers_callback_ptr);
Module.removeFunction(this.data_callback_ptr);
}
close() {
@ -137,7 +151,7 @@ class CurlSession {
if (headers_received) {
stream_controller.error("The operation was aborted.");
}
real_abort_callback();
real_end_callback(-1);
});
}

View file

@ -65,13 +65,6 @@ class CurlWebSocket extends CurlSession {
//CURLE_OK - data received
if (result_code === 0 && !result_closed) {
if (_get_result_closed(result_ptr)) {
_free(data_ptr);
_free(result_ptr);
this.cleanup();
return returned_data;
}
let data_size = _get_result_size(result_ptr);
let data_heap = Module.HEAPU8.subarray(data_ptr, data_ptr + data_size);
let data = new Uint8Array(data_heap);

View file

@ -18,17 +18,17 @@ struct curl_blob cacert_blob;
size_t write_function(char *data, size_t size, size_t nmemb, struct RequestInfo *request_info) {
size_t real_size = size * nmemb;
(*request_info->data_callback)(data, real_size);
(*request_info->data_callback)(request_info->request_id, data, real_size);
return real_size;
}
size_t header_function(char *data, size_t size, size_t nmemb, struct RequestInfo *request_info) {
size_t real_size = size * nmemb;
(*request_info->headers_callback)(data, real_size);
(*request_info->headers_callback)(request_info->request_id, data, real_size);
return real_size;
}
CURL* create_request(const char* url, DataCallback data_callback, EndCallback end_callback, DataCallback headers_callback) {
CURL* create_request(const char* url, int request_id, DataCallback data_callback, EndCallback end_callback, DataCallback headers_callback) {
CURL *http_handle = curl_easy_init();
//create request metadata struct
@ -36,6 +36,7 @@ CURL* create_request(const char* url, DataCallback data_callback, EndCallback en
request_info->http_handle = http_handle;
request_info->curl_msg = NULL;
request_info->headers_list = NULL;
request_info->request_id = request_id;
request_info->end_callback = end_callback;
request_info->data_callback = data_callback;
request_info->headers_callback = headers_callback;
@ -71,7 +72,7 @@ void finish_request(CURLMsg *curl_msg) {
if (request_info->headers_list != NULL) {
curl_slist_free_all(request_info->headers_list);
}
(*request_info->end_callback)(error);
(*request_info->end_callback)(request_info->request_id, error);
}
unsigned char* get_cacert() {

View file

@ -1,12 +1,13 @@
#include "curl/curl.h"
typedef void(*DataCallback)(char* chunk_ptr, int chunk_size);
typedef void(*EndCallback)(int error);
typedef void(*DataCallback)(int request_id, char* chunk_ptr, int chunk_size);
typedef void(*EndCallback)(int request_id, int error);
struct RequestInfo {
CURL* http_handle;
struct CURLMsg *curl_msg;
struct curl_slist* headers_list;
int request_id;
DataCallback data_callback;
DataCallback headers_callback;
EndCallback end_callback;

View file

@ -14,7 +14,7 @@ fi
source $SERVER_PATH/.venv/bin/activate
if ! python3 -c "import websockets, asyncudp" 2> /dev/null; then
pip3 install -r $SERVER_PATH/requirements.txt
pip3 install -e $SERVER_PATH
fi
python3 $SERVER_PATH/main.py "$@"
python3 -m wisp.server "$@"

@ -1 +1 @@
Subproject commit 351682f7e19c8a7a58d261ba666abaae95f04f6a
Subproject commit b7cfab072b04dbd4345aedaf5e47c9e0d57ab873