Skip to content

Commit 3b13fda

Browse files
feat(core): add WindowBuilder::on_request, closes #3533 (#3618)
Co-authored-by: Jonas Kruckenberg <iterpre@protonmail.com>
1 parent 8c93587 commit 3b13fda

File tree

10 files changed

+256
-84
lines changed

10 files changed

+256
-84
lines changed

.changes/window-request-handler.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch
3+
---
4+
5+
Added `WindowBuilder::on_web_resource_request`, which allows customizing the tauri custom protocol response.

core/tauri-runtime-wry/src/lib.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,10 @@ struct HttpRequestWrapper(HttpRequest);
219219

220220
impl From<&WryHttpRequest> for HttpRequestWrapper {
221221
fn from(req: &WryHttpRequest) -> Self {
222-
Self(HttpRequest {
223-
body: req.body.clone(),
224-
head: HttpRequestPartsWrapper::from(req.head.clone()).0,
225-
})
222+
Self(HttpRequest::new_internal(
223+
HttpRequestPartsWrapper::from(req.head.clone()).0,
224+
req.body.clone(),
225+
))
226226
}
227227
}
228228

@@ -242,9 +242,10 @@ impl From<HttpResponseParts> for HttpResponsePartsWrapper {
242242
struct HttpResponseWrapper(WryHttpResponse);
243243
impl From<HttpResponse> for HttpResponseWrapper {
244244
fn from(response: HttpResponse) -> Self {
245+
let (parts, body) = response.into_parts();
245246
Self(WryHttpResponse {
246-
body: response.body,
247-
head: HttpResponsePartsWrapper::from(response.head).0,
247+
body,
248+
head: HttpResponsePartsWrapper::from(parts).0,
248249
})
249250
}
250251
}
@@ -1466,6 +1467,26 @@ pub struct Wry {
14661467
tray_context: TrayContext,
14671468
}
14681469

1470+
impl fmt::Debug for Wry {
1471+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1472+
let mut d = f.debug_struct("Wry");
1473+
d.field("main_thread_id", &self.main_thread_id)
1474+
.field("global_shortcut_manager", &self.global_shortcut_manager)
1475+
.field(
1476+
"global_shortcut_manager_handle",
1477+
&self.global_shortcut_manager_handle,
1478+
)
1479+
.field("clipboard_manager", &self.clipboard_manager)
1480+
.field("clipboard_manager_handle", &self.clipboard_manager_handle)
1481+
.field("event_loop", &self.event_loop)
1482+
.field("windows", &self.windows)
1483+
.field("web_context", &self.web_context);
1484+
#[cfg(feature = "system-tray")]
1485+
d.field("tray_context", &self.tray_context);
1486+
d.finish()
1487+
}
1488+
}
1489+
14691490
/// A handle to the Wry runtime.
14701491
#[derive(Debug, Clone)]
14711492
pub struct WryHandle {

core/tauri-runtime/src/http/request.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use super::{
1717
///
1818
/// - **Linux:** Headers are not exposed.
1919
pub struct Request {
20-
pub head: RequestParts,
21-
pub body: Vec<u8>,
20+
head: RequestParts,
21+
body: Vec<u8>,
2222
}
2323

2424
/// Component parts of an HTTP `Request`
@@ -47,6 +47,17 @@ impl Request {
4747
}
4848
}
4949

50+
/// Creates a new `Request` with the given head and body.
51+
///
52+
/// # Stability
53+
///
54+
/// This API is used internally. It may have breaking changes in the future.
55+
#[inline]
56+
#[doc(hidden)]
57+
pub fn new_internal(head: RequestParts, body: Vec<u8>) -> Request {
58+
Request { head, body }
59+
}
60+
5061
/// Returns a reference to the associated HTTP method.
5162
#[inline]
5263
pub fn method(&self) -> &Method {
@@ -72,6 +83,10 @@ impl Request {
7283
}
7384

7485
/// Consumes the request returning the head and body RequestParts.
86+
///
87+
/// # Stability
88+
///
89+
/// This API is used internally. It may have breaking changes in the future.
7590
#[inline]
7691
pub fn into_parts(self) -> (RequestParts, Vec<u8>) {
7792
(self.head, self.body)

core/tauri-runtime/src/http/response.rs

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ type Result<T> = core::result::Result<T, Box<dyn std::error::Error>>;
3232
/// ```
3333
///
3434
pub struct Response {
35-
pub head: ResponseParts,
36-
pub body: Vec<u8>,
35+
head: ResponseParts,
36+
body: Vec<u8>,
3737
}
3838

3939
/// Component parts of an HTTP `Response`
@@ -42,16 +42,16 @@ pub struct Response {
4242
/// header fields.
4343
#[derive(Clone)]
4444
pub struct ResponseParts {
45-
/// The response's status
45+
/// The response's status.
4646
pub status: StatusCode,
4747

48-
/// The response's version
48+
/// The response's version.
4949
pub version: Version,
5050

51-
/// The response's headers
51+
/// The response's headers.
5252
pub headers: HeaderMap<HeaderValue>,
5353

54-
/// The response's mimetype type
54+
/// The response's mimetype type.
5555
pub mimetype: Option<String>,
5656
}
5757

@@ -74,16 +74,39 @@ impl Response {
7474
}
7575
}
7676

77-
/// Returns the `StatusCode`.
77+
/// Consumes the response returning the head and body ResponseParts.
78+
///
79+
/// # Stability
80+
///
81+
/// This API is used internally. It may have breaking changes in the future.
82+
#[inline]
83+
#[doc(hidden)]
84+
pub fn into_parts(self) -> (ResponseParts, Vec<u8>) {
85+
(self.head, self.body)
86+
}
87+
88+
/// Sets the status code.
89+
#[inline]
90+
pub fn set_status(&mut self, status: StatusCode) {
91+
self.head.status = status;
92+
}
93+
94+
/// Returns the [`StatusCode`].
7895
#[inline]
7996
pub fn status(&self) -> StatusCode {
8097
self.head.status
8198
}
8299

100+
/// Sets the mimetype.
101+
#[inline]
102+
pub fn set_mimetype(&mut self, mimetype: Option<String>) {
103+
self.head.mimetype = mimetype;
104+
}
105+
83106
/// Returns a reference to the mime type.
84107
#[inline]
85-
pub fn mimetype(&self) -> Option<String> {
86-
self.head.mimetype.clone()
108+
pub fn mimetype(&self) -> Option<&String> {
109+
self.head.mimetype.as_ref()
87110
}
88111

89112
/// Returns a reference to the associated version.
@@ -92,12 +115,24 @@ impl Response {
92115
self.head.version
93116
}
94117

118+
/// Returns a mutable reference to the associated header field map.
119+
#[inline]
120+
pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
121+
&mut self.head.headers
122+
}
123+
95124
/// Returns a reference to the associated header field map.
96125
#[inline]
97126
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
98127
&self.head.headers
99128
}
100129

130+
/// Returns a mutable reference to the associated HTTP body.
131+
#[inline]
132+
pub fn body_mut(&mut self) -> &mut Vec<u8> {
133+
&mut self.body
134+
}
135+
101136
/// Returns a reference to the associated HTTP body.
102137
#[inline]
103138
pub fn body(&self) -> &Vec<u8> {

core/tauri-runtime/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ pub trait ClipboardManager: Debug + Clone + Send + Sync {
311311
}
312312

313313
/// The webview runtime interface.
314-
pub trait Runtime: Sized + 'static {
314+
pub trait Runtime: Debug + Sized + 'static {
315315
/// The message dispatcher.
316316
type Dispatcher: Dispatch<Runtime = Self>;
317317
/// The runtime handle type.

core/tauri/src/app.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::{
2323
sealed::{ManagerBase, RuntimeOrDispatch},
2424
utils::config::{Config, WindowUrl},
2525
utils::{assets::Assets, Env},
26+
window::WindowBuilder,
2627
Context, Invoke, InvokeError, InvokeResponse, Manager, Scopes, StateManager, Window,
2728
};
2829

@@ -386,15 +387,12 @@ macro_rules! shared_app_impl {
386387
WebviewAttributes,
387388
),
388389
{
389-
let (window_builder, webview_attributes) = setup(
390-
<R::Dispatcher as Dispatch>::WindowBuilder::new(),
391-
WebviewAttributes::new(url),
392-
);
393-
self.create_new_window(PendingWindow::new(
394-
window_builder,
395-
webview_attributes,
396-
label,
397-
)?)
390+
let mut builder = WindowBuilder::<R>::new(self, label, url);
391+
let (window_builder, webview_attributes) =
392+
setup(builder.window_builder, builder.webview_attributes);
393+
builder.window_builder = window_builder;
394+
builder.webview_attributes = webview_attributes;
395+
builder.build()
398396
}
399397

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

13121310
for pending in self.pending_windows {
1313-
let pending = app
1314-
.manager
1315-
.prepare_window(app.handle.clone(), pending, &window_labels)?;
1311+
let pending =
1312+
app
1313+
.manager
1314+
.prepare_window(app.handle.clone(), pending, &window_labels, None)?;
13161315
let detached = app.runtime.as_ref().unwrap().create_window(pending)?;
13171316
let _window = app.manager.attach_window(app.handle(), detached);
13181317
#[cfg(feature = "updater")]

core/tauri/src/lib.rs

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ pub type Result<T> = std::result::Result<T, Error>;
174174
/// A task to run on the main thread.
175175
pub type SyncTask = Box<dyn FnOnce() + Send>;
176176

177-
use crate::runtime::window::PendingWindow;
178177
use serde::Serialize;
179178
use std::{collections::HashMap, fmt, sync::Arc};
180179

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

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

617-
#[derive(Clone, serde::Serialize)]
618-
struct WindowCreatedEvent {
619-
label: String,
620-
}
621-
622616
/// Managed handle to the application runtime.
623617
pub trait ManagerBase<R: Runtime> {
624618
/// The manager behind the [`Managed`] item.
625619
fn manager(&self) -> &WindowManager<R>;
626-
627620
fn runtime(&self) -> RuntimeOrDispatch<'_, R>;
628621
fn managed_app_handle(&self) -> AppHandle<R>;
629-
630-
/// Creates a new [`Window`] on the [`Runtime`] and attaches it to the [`Manager`].
631-
fn create_new_window(
632-
&self,
633-
pending: crate::PendingWindow<R>,
634-
) -> crate::Result<crate::Window<R>> {
635-
use crate::runtime::Dispatch;
636-
let labels = self.manager().labels().into_iter().collect::<Vec<_>>();
637-
let pending = self
638-
.manager()
639-
.prepare_window(self.managed_app_handle(), pending, &labels)?;
640-
let window = match self.runtime() {
641-
RuntimeOrDispatch::Runtime(runtime) => runtime.create_window(pending),
642-
RuntimeOrDispatch::RuntimeHandle(handle) => handle.create_window(pending),
643-
RuntimeOrDispatch::Dispatch(mut dispatcher) => dispatcher.create_window(pending),
644-
}
645-
.map(|window| {
646-
self
647-
.manager()
648-
.attach_window(self.managed_app_handle(), window)
649-
})?;
650-
651-
self.manager().emit_filter(
652-
"tauri://window-created",
653-
None,
654-
Some(WindowCreatedEvent {
655-
label: window.label().into(),
656-
}),
657-
|w| w != &window,
658-
)?;
659-
660-
Ok(window)
661-
}
662622
}
663623
}
664624

0 commit comments

Comments
 (0)