From b9b871b25a2059f3da7308921989cf13e4d7d830 Mon Sep 17 00:00:00 2001 From: ading2210 Date: Sun, 10 Mar 2024 10:24:42 -0400 Subject: [PATCH] add abort controller support --- CHANGELOG.md | 5 ++++- README.md | 3 +-- client/javascript/main.js | 36 +++++++++++++++++++++++++++++++++--- client/package.json | 2 +- client/publish.sh | 1 + 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dbce63..8b49220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Libcurl.js Changelog: -## v0.5.0 (3/8/24): +## v0.5.1 (3/10/24): +- Added support for aborting requests + +## v0.5.0 (3/9/24): - Added support for streaming HTTP responses via a readable stream - Improve compatibility for older browsers - Support for all types of fetch request bodies diff --git a/README.md b/README.md index 7c26f63..9c7d54f 100644 --- a/README.md +++ b/README.md @@ -94,11 +94,10 @@ console.log(await r.text()); Most of the standard Fetch API's features are supported, with the exception of: - CORS enforcement -- `FormData` or `URLSearchParams` as the request body - Sending credentials/cookies automatically - Caching -The response may contain multiple HTTP headers with the same name, which the `Headers` object isn't able to properly represent. If this matters to you, use `response.raw_headers`, which is an array of key value pairs, instead of `response.headers`. There is support for streaming the response body using a `ReadableStream`. +The response may contain multiple HTTP headers with the same name, which the `Headers` object isn't able to properly represent. If this matters to you, use `response.raw_headers`, which is an array of key value pairs, instead of `response.headers`. There is support for streaming the response body using a `ReadableStream`, as well as canceling requests using an `AbortSignal`. Also note that there is a hard limit of 50 active TCP connections due to emscripten limitations. diff --git a/client/javascript/main.js b/client/javascript/main.js index 387fd6f..022f838 100644 --- a/client/javascript/main.js +++ b/client/javascript/main.js @@ -173,6 +173,25 @@ async function create_options(params) { function perform_request_async(url, params, body) { return new Promise((resolve, reject) => { let stream_controller; + let http_handle; + let response_obj; + let aborted = false; + + //handle abort signals + if (params.signal instanceof AbortSignal) { + params.signal.addEventListener("abort", () => { + if (aborted) return; + aborted = true; + _cleanup_handle(http_handle); + if (!response_obj) { + reject(new DOMException("The operation was aborted.")); + } + else { + stream_controller.error("The operation was aborted."); + } + }); + } + let stream = new ReadableStream({ start(controller) { stream_controller = controller; @@ -180,10 +199,21 @@ function perform_request_async(url, params, body) { }); function data_callback(new_data) { - stream_controller.enqueue(new_data); + try { + stream_controller.enqueue(new_data); + } + catch (e) { + //the readable stream has been closed elsewhere, so cancel the request + if (e instanceof TypeError) { + _cleanup_handle(http_handle); + } + else { + throw e; + } + } } function headers_callback(response_info) { - let response_obj = create_response(stream, response_info); + response_obj = create_response(stream, response_info); resolve(response_obj); } function finish_callback(error) { @@ -196,7 +226,7 @@ function perform_request_async(url, params, body) { stream_controller.close(); } - perform_request(url, params, data_callback, finish_callback, headers_callback, body); + http_handle = perform_request(url, params, data_callback, finish_callback, headers_callback, body); }); } diff --git a/client/package.json b/client/package.json index a4f85c0..419fd56 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "libcurl.js", - "version": "0.5.0", + "version": "0.5.1", "description": "An experimental port of libcurl to WebAssembly for use in the browser.", "main": "libcurl.mjs", "scripts": { diff --git a/client/publish.sh b/client/publish.sh index 2a055e0..c164ff3 100755 --- a/client/publish.sh +++ b/client/publish.sh @@ -7,6 +7,7 @@ cp package.json out cp ../README.md out cp ../LICENSE out +cp ../CHANGELOG.md out cd out npm publish \ No newline at end of file