Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/macos-protocol-body-nocopy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": patch
---

On macOS, avoid an extra copy for owned custom protocol response bodies by transferring the body buffer into `NSData`.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ objc2-core-foundation = { version = "0.3.0", default-features = false, features
] }
objc2-foundation = { version = "0.3.0", default-features = false, features = [
"std",
"block2",
"objc2-core-foundation",
"NSURLRequest",
"NSURL",
Expand Down
4 changes: 0 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1316,10 +1316,6 @@ impl<'a> WebViewBuilder<'a> {
///
/// The closure take the URL to open and the window features object and returns [`NewWindowResponse`] to determine whether the window should open.
///
/// ## Platform-specific:
///
/// - **Windows**: The closure is executed on a separate thread to prevent a deadlock.
///
/// [window.open]: https://developer.mozilla.org/en-US/docs/Web/API/Window/open
pub fn with_new_window_req_handler(
mut self,
Expand Down
19 changes: 7 additions & 12 deletions src/wkwebview/class/url_scheme_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use std::{
borrow::Cow,
ffi::{c_char, c_void, CStr},
ffi::{c_char, CStr},
panic::AssertUnwindSafe,
ptr::NonNull,
};
Expand Down Expand Up @@ -214,7 +214,7 @@ extern "C" fn start_task(
check_webview_id_valid(webview_id)?;
check_task_is_valid(&webview, task_key, task_uuid.clone())?;

let content = sent_response.body();
let content_len = sent_response.body().len();
// default: application/octet-stream, but should be provided by the client
let wanted_mime = sent_response.headers().get(CONTENT_TYPE);
// default to 200
Expand All @@ -231,7 +231,7 @@ extern "C" fn start_task(
}
headers.insert(
&*NSString::from_str(CONTENT_LENGTH.as_str()),
&*NSString::from_str(&content.len().to_string()),
&*NSString::from_str(&content_len.to_string()),
);

// add headers
Expand Down Expand Up @@ -264,15 +264,10 @@ extern "C" fn start_task(
}))
.map_err(|_e| crate::Error::CustomProtocolTaskInvalid)?;

// Send data
let data = NSData::alloc();
// MIGRATE NOTE: we copied the content to the NSData because content will be freed
// when out of scope but NSData will also free the content when it's done and cause doube free.
let data = NSData::initWithBytes_length(
data,
content.as_ptr() as *mut c_void,
content.len(),
);
let data = match sent_response.into_body() {
Cow::Owned(content) => NSData::from_vec(content),
Cow::Borrowed(content) => NSData::with_bytes(content),
};

// Check validity again
check_webview_id_valid(webview_id)?;
Expand Down