Repository navigation
feat(http): send fetch request bodies as raw IPC payloads - #3732
Open
followdarko wants to merge 1 commit into
Open
followdarko wants to merge 1 commit into
followdarko wants to merge 1 commit into
Conversation
The guest code encoded a request body as a JSON array with one number
per byte, built and stringified on the webview's main thread. A
non-empty body is now the raw IPC payload and the other request options
ride in a `client-config` IPC header, as `plugin:fs|write_file` does.
The `fetch` command still accepts `{ clientConfig }` JSON arguments,
used for requests without a body and by older guest code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3731.
The problem
fetchsends the request body inside the JSON arguments ofplugin:http|fetchasArray.from(new Uint8Array(buffer)): one number per byte, built and stringified on the webview's main thread, then parsed back byserde_json. The window stalls for as long as that takes, which grows with the body.The change
invoke(cmd, new Uint8Array(buffer), { headers }), and the rest of the request options as percent-encoded JSON in aclient-configIPC header.plugin:fs|write_filepasses file contents and options the same way.fetchtakestauri::ipc::Requestand reads the options from that header and the body fromInvokeBody::Raw, or from a JSON number array, which is how a raw payload arrives on Android and under thepostMessagefallback.{ clientConfig }from the JSON arguments as before. The guest code still uses that form for a request without a body, and it keeps older guest code working against this crate.Android and the isolation pattern get no speed-up, since a raw payload travels as a number array there, but they take the same code path.
Verification
A small app on macOS 15.7 (arm64, WKWebView, release build) sends the same requests through the previous
api-iife.jsand through this one, both against this crate, to a local server that answers with the body's length and hash. "Stall" is the longest gap between event-loop turns while the request is in flight. Median of 10 requests per row:performance.now()in WKWebView has 1 ms resolution, so the small rows are at its floor.The same app checks that binary and text bodies arrive byte for byte, that a byte-string header value keeps its bytes and the content type is sent, that a POST without a body and a GET still go through, and that the previous guest code still works against this crate.
Unit tests cover reading the options and the body: a raw payload, a number array, an out-of-range number, the JSON arguments with and without
data, and a raw payload without the header. The existingapi-e2ehttp specs (JSON, binary, multipart and byte-string header bodies) all go through the new path.cargo test -p tauri-plugin-http,cargo clippy -p tauri-plugin-http --all-targets -- -D warnings,cargo fmt --check,pnpm build,eslintandprettier --checkpass onv2.