Skip to content

Commit

Permalink
refactor(core): allow custom protocol handler to resolve async
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Sep 5, 2023
1 parent 29818de commit f12862e
Show file tree
Hide file tree
Showing 17 changed files with 353 additions and 259 deletions.
5 changes: 5 additions & 0 deletions .changes/custom-protocol-response-refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": patch:breaking
---

Changed `Builder::register_uri_scheme_protocol` to take a second parameter to resolve the request instead of returning a response object.
5 changes: 5 additions & 0 deletions .changes/invoke-system-args.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": patch:breaking
---

Changed `Builder::invoke_system` to take references instead of owned values.
5 changes: 5 additions & 0 deletions .changes/runtime-custom-protocol-async.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-runtime": patch:enhance
---

Changed custom protocol closure type to enable asynchronous usage.
5 changes: 5 additions & 0 deletions .changes/wry-0.32.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-runtime-wry": patch:enhance
---

Update wry to 0.32 to include asynchronous custom protocol support.
2 changes: 1 addition & 1 deletion core/tauri-runtime-wry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ rust-version = { workspace = true }
features = [ "dox" ]

[dependencies]
wry = { version = "0.31", default-features = false, features = [ "file-drop", "protocol" ] }
wry = { git = "https://github.com/tauri-apps/wry", branch = "refactor/custom-protocol-response", default-features = false, features = [ "file-drop", "protocol" ] }
tauri-runtime = { version = "1.0.0-alpha.0", path = "../tauri-runtime" }
tauri-utils = { version = "2.0.0-alpha.7", path = "../tauri-utils" }
uuid = { version = "1", features = [ "v4" ] }
Expand Down
24 changes: 14 additions & 10 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,15 @@ impl<T: UserEvent> fmt::Debug for Context<T> {

struct HttpRequestWrapper(HttpRequest);

impl From<&WryRequest<Vec<u8>>> for HttpRequestWrapper {
fn from(req: &WryRequest<Vec<u8>>) -> Self {
impl From<WryRequest<Vec<u8>>> for HttpRequestWrapper {
fn from(req: WryRequest<Vec<u8>>) -> Self {
let (parts, body) = req.into_parts();
let parts = RequestParts {
uri: req.uri().to_string(),
method: req.method().clone(),
headers: req.headers().clone(),
uri: parts.uri.to_string(),
method: parts.method,
headers: parts.headers,
};
Self(HttpRequest::new_internal(parts, req.body().clone()))
Self(HttpRequest::new_internal(parts, body))
}
}

Expand Down Expand Up @@ -2701,11 +2702,14 @@ fn create_webview<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
}

for (scheme, protocol) in uri_scheme_protocols {
webview_builder = webview_builder.with_custom_protocol(scheme, move |wry_request| {
protocol(&HttpRequestWrapper::from(wry_request).0)
.map(|tauri_response| HttpResponseWrapper::from(tauri_response).0)
webview_builder =
webview_builder.with_custom_protocol(scheme, move |wry_request: WryRequest<Vec<u8>>, api| {
protocol(
HttpRequestWrapper::from(wry_request).0,
Box::new(move |response| api.respond(HttpResponseWrapper::from(response).0)),
)
.map_err(|_| wry::Error::InitScriptError)
});
});
}

for script in webview_attributes.initialization_scripts {
Expand Down
26 changes: 19 additions & 7 deletions core/tauri-runtime/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ use std::{

use self::dpi::PhysicalPosition;

type UriSchemeProtocol =
dyn Fn(&HttpRequest) -> Result<HttpResponse, Box<dyn std::error::Error>> + Send + Sync + 'static;
type UriSchemeProtocol = dyn Fn(
HttpRequest,
Box<dyn FnOnce(HttpResponse) + Send + Sync>,
) -> Result<(), Box<dyn std::error::Error>>
+ Send
+ Sync
+ 'static;

type WebResourceRequestHandler = dyn Fn(&HttpRequest, &mut HttpResponse) + Send + Sync;
type WebResourceRequestHandler = dyn Fn(HttpRequest, &mut HttpResponse) + Send + Sync;

type NavigationHandler = dyn Fn(&Url) -> bool + Send;

Expand Down Expand Up @@ -306,16 +311,23 @@ impl<T: UserEvent, R: Runtime<T>> PendingWindow<T, R> {

pub fn register_uri_scheme_protocol<
N: Into<String>,
H: Fn(&HttpRequest) -> Result<HttpResponse, Box<dyn std::error::Error>> + Send + Sync + 'static,
H: Fn(
HttpRequest,
Box<dyn FnOnce(HttpResponse) + Send + Sync>,
) -> Result<(), Box<dyn std::error::Error>>
+ Send
+ Sync
+ 'static,
>(
&mut self,
uri_scheme: N,
protocol: H,
) {
let uri_scheme = uri_scheme.into();
self
.uri_scheme_protocols
.insert(uri_scheme, Box::new(move |data| (protocol)(data)));
self.uri_scheme_protocols.insert(
uri_scheme,
Box::new(move |data, responder| (protocol)(data, responder)),
);
}

#[cfg(target_os = "android")]
Expand Down
8 changes: 6 additions & 2 deletions core/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ impl<R: Runtime> Builder<R> {
#[must_use]
pub fn invoke_system<F>(mut self, initialization_script: String, responder: F) -> Self
where
F: Fn(Window<R>, String, &InvokeResponse, CallbackFn, CallbackFn) + Send + Sync + 'static,
F: Fn(&Window<R>, &str, &InvokeResponse, CallbackFn, CallbackFn) + Send + Sync + 'static,
{
self.invoke_initialization_script = initialization_script;
self.invoke_responder.replace(Arc::new(responder));
Expand Down Expand Up @@ -1352,7 +1352,11 @@ impl<R: Runtime> Builder<R> {
#[must_use]
pub fn register_uri_scheme_protocol<
N: Into<String>,
H: Fn(&AppHandle<R>, &HttpRequest) -> Result<HttpResponse, Box<dyn std::error::Error>>
H: Fn(
&AppHandle<R>,
HttpRequest,
Box<dyn FnOnce(HttpResponse) + Send + Sync>,
) -> Result<(), Box<dyn std::error::Error>>
+ Send
+ Sync
+ 'static,
Expand Down
2 changes: 1 addition & 1 deletion core/tauri/src/asset_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use url::Position;
use url::Url;

pub fn asset_protocol_handler(
request: &Request,
request: Request,
scope: FsScope,
window_origin: String,
) -> Result<Response, Box<dyn std::error::Error>> {
Expand Down
27 changes: 17 additions & 10 deletions core/tauri/src/ipc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//!
//! This module includes utilities to send messages to the JS layer of the webview.

use std::sync::Arc;
use std::sync::{Arc, Mutex};

use futures_util::Future;
use http::HeaderMap;
Expand All @@ -31,9 +31,10 @@ pub type InvokeHandler<R> = dyn Fn(Invoke<R>) -> bool + Send + Sync + 'static;

/// A closure that is responsible for respond a JS message.
pub type InvokeResponder<R> =
dyn Fn(Window<R>, String, &InvokeResponse, CallbackFn, CallbackFn) + Send + Sync + 'static;
type OwnedInvokeResponder<R> =
dyn Fn(Window<R>, String, InvokeResponse, CallbackFn, CallbackFn) + Send + Sync + 'static;
dyn Fn(&Window<R>, &str, &InvokeResponse, CallbackFn, CallbackFn) + Send + Sync + 'static;
/// Similar to [`InvokeResponder`] but taking owned arguments.
pub type OwnedInvokeResponder<R> =
dyn FnOnce(Window<R>, String, InvokeResponse, CallbackFn, CallbackFn) + Send + Sync + 'static;

/// Possible values of an IPC payload.
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -225,7 +226,7 @@ impl From<InvokeError> for InvokeResponse {
#[default_runtime(crate::Wry, wry)]
pub struct InvokeResolver<R: Runtime> {
window: Window<R>,
responder: Arc<OwnedInvokeResponder<R>>,
responder: Arc<Mutex<Option<Box<OwnedInvokeResponder<R>>>>>,
cmd: String,
pub(crate) callback: CallbackFn,
pub(crate) error: CallbackFn,
Expand All @@ -246,7 +247,7 @@ impl<R: Runtime> Clone for InvokeResolver<R> {
impl<R: Runtime> InvokeResolver<R> {
pub(crate) fn new(
window: Window<R>,
responder: Arc<OwnedInvokeResponder<R>>,
responder: Arc<Mutex<Option<Box<OwnedInvokeResponder<R>>>>>,
cmd: String,
callback: CallbackFn,
error: CallbackFn,
Expand Down Expand Up @@ -348,7 +349,7 @@ impl<R: Runtime> InvokeResolver<R> {
/// If the Result `is_err()`, the callback will be the `error_callback` function name and the argument will be the Err value.
pub async fn return_task<T, F>(
window: Window<R>,
responder: Arc<OwnedInvokeResponder<R>>,
responder: Arc<Mutex<Option<Box<OwnedInvokeResponder<R>>>>>,
task: F,
cmd: String,
success_callback: CallbackFn,
Expand All @@ -370,7 +371,7 @@ impl<R: Runtime> InvokeResolver<R> {

pub(crate) fn return_closure<T: IpcResponse, F: FnOnce() -> Result<T, InvokeError>>(
window: Window<R>,
responder: Arc<OwnedInvokeResponder<R>>,
responder: Arc<Mutex<Option<Box<OwnedInvokeResponder<R>>>>>,
f: F,
cmd: String,
success_callback: CallbackFn,
Expand All @@ -388,13 +389,19 @@ impl<R: Runtime> InvokeResolver<R> {

pub(crate) fn return_result(
window: Window<R>,
responder: Arc<OwnedInvokeResponder<R>>,
responder: Arc<Mutex<Option<Box<OwnedInvokeResponder<R>>>>>,
response: InvokeResponse,
cmd: String,
success_callback: CallbackFn,
error_callback: CallbackFn,
) {
(responder)(window, cmd, response, success_callback, error_callback);
(responder.lock().unwrap().take().expect("resolver consumed"))(
window,
cmd,
response,
success_callback,
error_callback,
);
}
}

Expand Down
Loading

0 comments on commit f12862e

Please sign in to comment.