Skip to content

Commit

Permalink
feat(core): add WindowBuilder::on_request, closes #3533 (#3618)
Browse files Browse the repository at this point in the history
Co-authored-by: Jonas Kruckenberg <iterpre@protonmail.com>
  • Loading branch information
lucasfernog and JonasKruckenberg committed Mar 6, 2022
1 parent 8c93587 commit 3b13fda
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 84 deletions.
5 changes: 5 additions & 0 deletions .changes/window-request-handler.md
@@ -0,0 +1,5 @@
---
"tauri": patch
---

Added `WindowBuilder::on_web_resource_request`, which allows customizing the tauri custom protocol response.
33 changes: 27 additions & 6 deletions core/tauri-runtime-wry/src/lib.rs
Expand Up @@ -219,10 +219,10 @@ struct HttpRequestWrapper(HttpRequest);

impl From<&WryHttpRequest> for HttpRequestWrapper {
fn from(req: &WryHttpRequest) -> Self {
Self(HttpRequest {
body: req.body.clone(),
head: HttpRequestPartsWrapper::from(req.head.clone()).0,
})
Self(HttpRequest::new_internal(
HttpRequestPartsWrapper::from(req.head.clone()).0,
req.body.clone(),
))
}
}

Expand All @@ -242,9 +242,10 @@ impl From<HttpResponseParts> for HttpResponsePartsWrapper {
struct HttpResponseWrapper(WryHttpResponse);
impl From<HttpResponse> for HttpResponseWrapper {
fn from(response: HttpResponse) -> Self {
let (parts, body) = response.into_parts();
Self(WryHttpResponse {
body: response.body,
head: HttpResponsePartsWrapper::from(response.head).0,
body,
head: HttpResponsePartsWrapper::from(parts).0,
})
}
}
Expand Down Expand Up @@ -1466,6 +1467,26 @@ pub struct Wry {
tray_context: TrayContext,
}

impl fmt::Debug for Wry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_struct("Wry");
d.field("main_thread_id", &self.main_thread_id)
.field("global_shortcut_manager", &self.global_shortcut_manager)
.field(
"global_shortcut_manager_handle",
&self.global_shortcut_manager_handle,
)
.field("clipboard_manager", &self.clipboard_manager)
.field("clipboard_manager_handle", &self.clipboard_manager_handle)
.field("event_loop", &self.event_loop)
.field("windows", &self.windows)
.field("web_context", &self.web_context);
#[cfg(feature = "system-tray")]
d.field("tray_context", &self.tray_context);
d.finish()
}
}

/// A handle to the Wry runtime.
#[derive(Debug, Clone)]
pub struct WryHandle {
Expand Down
19 changes: 17 additions & 2 deletions core/tauri-runtime/src/http/request.rs
Expand Up @@ -17,8 +17,8 @@ use super::{
///
/// - **Linux:** Headers are not exposed.
pub struct Request {
pub head: RequestParts,
pub body: Vec<u8>,
head: RequestParts,
body: Vec<u8>,
}

/// Component parts of an HTTP `Request`
Expand Down Expand Up @@ -47,6 +47,17 @@ impl Request {
}
}

/// Creates a new `Request` with the given head and body.
///
/// # Stability
///
/// This API is used internally. It may have breaking changes in the future.
#[inline]
#[doc(hidden)]
pub fn new_internal(head: RequestParts, body: Vec<u8>) -> Request {
Request { head, body }
}

/// Returns a reference to the associated HTTP method.
#[inline]
pub fn method(&self) -> &Method {
Expand All @@ -72,6 +83,10 @@ impl Request {
}

/// Consumes the request returning the head and body RequestParts.
///
/// # Stability
///
/// This API is used internally. It may have breaking changes in the future.
#[inline]
pub fn into_parts(self) -> (RequestParts, Vec<u8>) {
(self.head, self.body)
Expand Down
53 changes: 44 additions & 9 deletions core/tauri-runtime/src/http/response.rs
Expand Up @@ -32,8 +32,8 @@ type Result<T> = core::result::Result<T, Box<dyn std::error::Error>>;
/// ```
///
pub struct Response {
pub head: ResponseParts,
pub body: Vec<u8>,
head: ResponseParts,
body: Vec<u8>,
}

/// Component parts of an HTTP `Response`
Expand All @@ -42,16 +42,16 @@ pub struct Response {
/// header fields.
#[derive(Clone)]
pub struct ResponseParts {
/// The response's status
/// The response's status.
pub status: StatusCode,

/// The response's version
/// The response's version.
pub version: Version,

/// The response's headers
/// The response's headers.
pub headers: HeaderMap<HeaderValue>,

/// The response's mimetype type
/// The response's mimetype type.
pub mimetype: Option<String>,
}

Expand All @@ -74,16 +74,39 @@ impl Response {
}
}

/// Returns the `StatusCode`.
/// Consumes the response returning the head and body ResponseParts.
///
/// # Stability
///
/// This API is used internally. It may have breaking changes in the future.
#[inline]
#[doc(hidden)]
pub fn into_parts(self) -> (ResponseParts, Vec<u8>) {
(self.head, self.body)
}

/// Sets the status code.
#[inline]
pub fn set_status(&mut self, status: StatusCode) {
self.head.status = status;
}

/// Returns the [`StatusCode`].
#[inline]
pub fn status(&self) -> StatusCode {
self.head.status
}

/// Sets the mimetype.
#[inline]
pub fn set_mimetype(&mut self, mimetype: Option<String>) {
self.head.mimetype = mimetype;
}

/// Returns a reference to the mime type.
#[inline]
pub fn mimetype(&self) -> Option<String> {
self.head.mimetype.clone()
pub fn mimetype(&self) -> Option<&String> {
self.head.mimetype.as_ref()
}

/// Returns a reference to the associated version.
Expand All @@ -92,12 +115,24 @@ impl Response {
self.head.version
}

/// Returns a mutable reference to the associated header field map.
#[inline]
pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
&mut self.head.headers
}

/// Returns a reference to the associated header field map.
#[inline]
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
&self.head.headers
}

/// Returns a mutable reference to the associated HTTP body.
#[inline]
pub fn body_mut(&mut self) -> &mut Vec<u8> {
&mut self.body
}

/// Returns a reference to the associated HTTP body.
#[inline]
pub fn body(&self) -> &Vec<u8> {
Expand Down
2 changes: 1 addition & 1 deletion core/tauri-runtime/src/lib.rs
Expand Up @@ -311,7 +311,7 @@ pub trait ClipboardManager: Debug + Clone + Send + Sync {
}

/// The webview runtime interface.
pub trait Runtime: Sized + 'static {
pub trait Runtime: Debug + Sized + 'static {
/// The message dispatcher.
type Dispatcher: Dispatch<Runtime = Self>;
/// The runtime handle type.
Expand Down
23 changes: 11 additions & 12 deletions core/tauri/src/app.rs
Expand Up @@ -23,6 +23,7 @@ use crate::{
sealed::{ManagerBase, RuntimeOrDispatch},
utils::config::{Config, WindowUrl},
utils::{assets::Assets, Env},
window::WindowBuilder,
Context, Invoke, InvokeError, InvokeResponse, Manager, Scopes, StateManager, Window,
};

Expand Down Expand Up @@ -386,15 +387,12 @@ macro_rules! shared_app_impl {
WebviewAttributes,
),
{
let (window_builder, webview_attributes) = setup(
<R::Dispatcher as Dispatch>::WindowBuilder::new(),
WebviewAttributes::new(url),
);
self.create_new_window(PendingWindow::new(
window_builder,
webview_attributes,
label,
)?)
let mut builder = WindowBuilder::<R>::new(self, label, url);
let (window_builder, webview_attributes) =
setup(builder.window_builder, builder.webview_attributes);
builder.window_builder = window_builder;
builder.webview_attributes = webview_attributes;
builder.build()
}

#[cfg(feature = "system-tray")]
Expand Down Expand Up @@ -1310,9 +1308,10 @@ impl<R: Runtime> Builder<R> {
let mut main_window = None;

for pending in self.pending_windows {
let pending = app
.manager
.prepare_window(app.handle.clone(), pending, &window_labels)?;
let pending =
app
.manager
.prepare_window(app.handle.clone(), pending, &window_labels, None)?;
let detached = app.runtime.as_ref().unwrap().create_window(pending)?;
let _window = app.manager.attach_window(app.handle(), detached);
#[cfg(feature = "updater")]
Expand Down
42 changes: 1 addition & 41 deletions core/tauri/src/lib.rs
Expand Up @@ -174,7 +174,6 @@ pub type Result<T> = std::result::Result<T, Error>;
/// A task to run on the main thread.
pub type SyncTask = Box<dyn FnOnce() + Send>;

use crate::runtime::window::PendingWindow;
use serde::Serialize;
use std::{collections::HashMap, fmt, sync::Arc};

Expand Down Expand Up @@ -600,7 +599,7 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
/// Prevent implementation details from leaking out of the [`Manager`] trait.
pub(crate) mod sealed {
use crate::{app::AppHandle, manager::WindowManager};
use tauri_runtime::{Runtime, RuntimeHandle};
use tauri_runtime::Runtime;

/// A running [`Runtime`] or a dispatcher to it.
pub enum RuntimeOrDispatch<'r, R: Runtime> {
Expand All @@ -614,51 +613,12 @@ pub(crate) mod sealed {
Dispatch(R::Dispatcher),
}

#[derive(Clone, serde::Serialize)]
struct WindowCreatedEvent {
label: String,
}

/// Managed handle to the application runtime.
pub trait ManagerBase<R: Runtime> {
/// The manager behind the [`Managed`] item.
fn manager(&self) -> &WindowManager<R>;

fn runtime(&self) -> RuntimeOrDispatch<'_, R>;
fn managed_app_handle(&self) -> AppHandle<R>;

/// Creates a new [`Window`] on the [`Runtime`] and attaches it to the [`Manager`].
fn create_new_window(
&self,
pending: crate::PendingWindow<R>,
) -> crate::Result<crate::Window<R>> {
use crate::runtime::Dispatch;
let labels = self.manager().labels().into_iter().collect::<Vec<_>>();
let pending = self
.manager()
.prepare_window(self.managed_app_handle(), pending, &labels)?;
let window = match self.runtime() {
RuntimeOrDispatch::Runtime(runtime) => runtime.create_window(pending),
RuntimeOrDispatch::RuntimeHandle(handle) => handle.create_window(pending),
RuntimeOrDispatch::Dispatch(mut dispatcher) => dispatcher.create_window(pending),
}
.map(|window| {
self
.manager()
.attach_window(self.managed_app_handle(), window)
})?;

self.manager().emit_filter(
"tauri://window-created",
None,
Some(WindowCreatedEvent {
label: window.label().into(),
}),
|w| w != &window,
)?;

Ok(window)
}
}
}

Expand Down

0 comments on commit 3b13fda

Please sign in to comment.