Skip to content

Commit f37e97d

Browse files
amrbashirFabianLarslucasfernog
authored
feat: add use_https_scheme for Windows and Android (#11477)
* feat: add `use_https_scheme` for Windows and Android closes #11252 * fix compilation * Apply suggestions from code review Co-authored-by: Fabian-Lars <github@fabianlars.de> * change wording * add migrations * migrate `dangerousUseHttpScheme` * fmt * infer AssetResolver::get https scheme config * fix tests --------- Co-authored-by: Fabian-Lars <github@fabianlars.de> Co-authored-by: Lucas Nogueira <lucas@tauri.app>
1 parent 058c0db commit f37e97d

File tree

22 files changed

+358
-79
lines changed

22 files changed

+358
-79
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri": "minor:feat"
3+
"tauri-utils": "minor:feat"
4+
---
5+
6+
Add `app > windows > useHttpsScheme` config option to choose whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": "minor:feat"
3+
"tauri-runtime": "minor:feat"
4+
"tauri-runtime-wry": "minor:feat"
5+
---
6+
7+
Add `WebviewWindowBuilder/WebviewBuilder::use_https_scheme` to choose whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android

crates/tauri-cli/config.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,11 @@
486486
"description": "Whether browser extensions can be installed for the webview process\n\n ## Platform-specific:\n\n - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled)\n - **MacOS / Linux / iOS / Android** - Unsupported.",
487487
"default": false,
488488
"type": "boolean"
489+
},
490+
"useHttpsScheme": {
491+
"description": "Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.",
492+
"default": false,
493+
"type": "boolean"
489494
}
490495
},
491496
"additionalProperties": false

crates/tauri-cli/src/migrate/migrations/v1/config.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,28 @@ fn migrate_config(config: &mut Value) -> Result<MigratedConfig> {
8787
migrated.permissions = permissions;
8888
}
8989

90+
// dangerousUseHttpScheme/useHttpsScheme
91+
let dangerouse_use_http = tauri_config
92+
.get("security")
93+
.and_then(|w| w.as_object())
94+
.and_then(|w| {
95+
w.get("dangerousUseHttpScheme")
96+
.or_else(|| w.get("dangerous-use-http-scheme"))
97+
})
98+
.and_then(|v| v.as_bool())
99+
.unwrap_or_default();
100+
101+
if let Some(windows) = tauri_config
102+
.get_mut("windows")
103+
.and_then(|w| w.as_array_mut())
104+
{
105+
for window in windows {
106+
if let Some(window) = window.as_object_mut() {
107+
window.insert("useHttpsScheme".to_string(), (!dangerouse_use_http).into());
108+
}
109+
}
110+
}
111+
90112
// security
91113
if let Some(security) = tauri_config
92114
.get_mut("security")
@@ -802,7 +824,8 @@ mod test {
802824
"pattern": { "use": "brownfield" },
803825
"security": {
804826
"csp": "default-src 'self' tauri:"
805-
}
827+
},
828+
"windows": [{}]
806829
}
807830
});
808831

@@ -907,6 +930,8 @@ mod test {
907930
migrated["app"]["withGlobalTauri"],
908931
original["build"]["withGlobalTauri"]
909932
);
933+
934+
assert_eq!(migrated["app"]["windows"][0]["useHttpsScheme"], true);
910935
}
911936

912937
#[test]
@@ -941,6 +966,28 @@ mod test {
941966
);
942967
}
943968

969+
#[test]
970+
fn migrate_dangerous_use_http_scheme() {
971+
let original = serde_json::json!({
972+
"tauri": {
973+
"windows": [{}],
974+
"security": {
975+
"dangerousUseHttpScheme": true,
976+
}
977+
}
978+
});
979+
980+
let migrated = migrate(&original);
981+
assert_eq!(
982+
!migrated["app"]["windows"][0]["useHttpsScheme"]
983+
.as_bool()
984+
.unwrap(),
985+
original["tauri"]["security"]["dangerousUseHttpScheme"]
986+
.as_bool()
987+
.unwrap()
988+
);
989+
}
990+
944991
#[test]
945992
fn can_migrate_default_config() {
946993
let original = serde_json::to_value(tauri_utils_v1::config::Config::default()).unwrap();

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

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use tauri_runtime::{
2222
monitor::Monitor,
2323
webview::{DetachedWebview, DownloadEvent, PendingWebview, WebviewIpcHandler},
2424
window::{
25-
CursorIcon, DetachedWindow, DragDropEvent, PendingWindow, RawWindow, WebviewEvent,
26-
WindowBuilder, WindowBuilderBase, WindowEvent, WindowId, WindowSizeConstraints,
25+
CursorIcon, DetachedWindow, DetachedWindowWebview, DragDropEvent, PendingWindow, RawWindow,
26+
WebviewEvent, WindowBuilder, WindowBuilderBase, WindowEvent, WindowId, WindowSizeConstraints,
2727
},
2828
DeviceEventFilter, Error, EventLoopProxy, ExitRequestedEventAction, Icon, ProgressBarState,
2929
ProgressBarStatus, Result, RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs, UserAttentionType,
@@ -276,7 +276,16 @@ impl<T: UserEvent> Context<T> {
276276
let label = pending.label.clone();
277277
let context = self.clone();
278278
let window_id = self.next_window_id();
279-
let webview_id = pending.webview.as_ref().map(|_| context.next_webview_id());
279+
let (webview_id, use_https_scheme) = pending
280+
.webview
281+
.as_ref()
282+
.map(|w| {
283+
(
284+
Some(context.next_webview_id()),
285+
w.webview_attributes.use_https_scheme,
286+
)
287+
})
288+
.unwrap_or((None, false));
280289

281290
send_user_message(
282291
self,
@@ -300,13 +309,19 @@ impl<T: UserEvent> Context<T> {
300309
context: self.clone(),
301310
};
302311

303-
let detached_webview = webview_id.map(|id| DetachedWebview {
304-
label: label.clone(),
305-
dispatcher: WryWebviewDispatcher {
306-
window_id: Arc::new(Mutex::new(window_id)),
307-
webview_id: id,
308-
context: self.clone(),
309-
},
312+
let detached_webview = webview_id.map(|id| {
313+
let webview = DetachedWebview {
314+
label: label.clone(),
315+
dispatcher: WryWebviewDispatcher {
316+
window_id: Arc::new(Mutex::new(window_id)),
317+
webview_id: id,
318+
context: self.clone(),
319+
},
320+
};
321+
DetachedWindowWebview {
322+
webview,
323+
use_https_scheme,
324+
}
310325
});
311326

312327
Ok(DetachedWindow {
@@ -746,6 +761,8 @@ impl WindowBuilder for WindowBuilderWrapper {
746761
builder = builder.title_bar_style(TitleBarStyle::Visible);
747762
}
748763

764+
builder = builder.title("Tauri App");
765+
749766
builder
750767
}
751768

@@ -2497,10 +2514,16 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
24972514
) -> Result<DetachedWindow<T, Self>> {
24982515
let label = pending.label.clone();
24992516
let window_id = self.context.next_window_id();
2500-
let webview_id = pending
2517+
let (webview_id, use_https_scheme) = pending
25012518
.webview
25022519
.as_ref()
2503-
.map(|_| self.context.next_webview_id());
2520+
.map(|w| {
2521+
(
2522+
Some(self.context.next_webview_id()),
2523+
w.webview_attributes.use_https_scheme,
2524+
)
2525+
})
2526+
.unwrap_or((None, false));
25042527

25052528
let window = create_window(
25062529
window_id,
@@ -2524,13 +2547,19 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
25242547
.borrow_mut()
25252548
.insert(window_id, window);
25262549

2527-
let detached_webview = webview_id.map(|id| DetachedWebview {
2528-
label: label.clone(),
2529-
dispatcher: WryWebviewDispatcher {
2530-
window_id: Arc::new(Mutex::new(window_id)),
2531-
webview_id: id,
2532-
context: self.context.clone(),
2533-
},
2550+
let detached_webview = webview_id.map(|id| {
2551+
let webview = DetachedWebview {
2552+
label: label.clone(),
2553+
dispatcher: WryWebviewDispatcher {
2554+
window_id: Arc::new(Mutex::new(window_id)),
2555+
webview_id: id,
2556+
context: self.context.clone(),
2557+
},
2558+
};
2559+
DetachedWindowWebview {
2560+
webview,
2561+
use_https_scheme,
2562+
}
25342563
});
25352564

25362565
Ok(DetachedWindow {
@@ -4026,6 +4055,11 @@ fn create_webview<T: UserEvent>(
40264055
.with_clipboard(webview_attributes.clipboard)
40274056
.with_hotkeys_zoom(webview_attributes.zoom_hotkeys_enabled);
40284057

4058+
#[cfg(any(target_os = "windows", target_os = "android"))]
4059+
{
4060+
webview_builder = webview_builder.with_https_scheme(webview_attributes.use_https_scheme);
4061+
}
4062+
40294063
if webview_attributes.drag_drop_handler_enabled {
40304064
let proxy = context.proxy.clone();
40314065
let window_id_ = window_id.clone();
@@ -4168,11 +4202,6 @@ fn create_webview<T: UserEvent>(
41684202
});
41694203
}
41704204

4171-
#[cfg(windows)]
4172-
{
4173-
webview_builder = webview_builder.with_https_scheme(false);
4174-
}
4175-
41764205
#[cfg(windows)]
41774206
{
41784207
webview_builder = webview_builder
@@ -4282,7 +4311,7 @@ fn create_webview<T: UserEvent>(
42824311
builder
42834312
}
42844313
}
4285-
.map_err(|e| Error::CreateWebview(Box::new(dbg!(e))))?;
4314+
.map_err(|e| Error::CreateWebview(Box::new(e)))?;
42864315

42874316
if kind == WebviewKind::WindowContent {
42884317
#[cfg(any(

crates/tauri-runtime/src/webview.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ pub struct WebviewAttributes {
210210
pub proxy_url: Option<Url>,
211211
pub zoom_hotkeys_enabled: bool,
212212
pub browser_extensions_enabled: bool,
213+
pub use_https_scheme: bool,
213214
}
214215

215216
impl From<&WindowConfig> for WebviewAttributes {
@@ -218,6 +219,7 @@ impl From<&WindowConfig> for WebviewAttributes {
218219
.incognito(config.incognito)
219220
.focused(config.focus)
220221
.zoom_hotkeys_enabled(config.zoom_hotkeys_enabled)
222+
.use_https_scheme(config.use_https_scheme)
221223
.browser_extensions_enabled(config.browser_extensions_enabled);
222224
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
223225
{
@@ -264,6 +266,7 @@ impl WebviewAttributes {
264266
proxy_url: None,
265267
zoom_hotkeys_enabled: false,
266268
browser_extensions_enabled: false,
269+
use_https_scheme: false,
267270
}
268271
}
269272

@@ -388,6 +391,21 @@ impl WebviewAttributes {
388391
self.browser_extensions_enabled = enabled;
389392
self
390393
}
394+
395+
/// Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.
396+
///
397+
/// ## Note
398+
///
399+
/// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.
400+
///
401+
/// ## Warning
402+
///
403+
/// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.
404+
#[must_use]
405+
pub fn use_https_scheme(mut self, enabled: bool) -> Self {
406+
self.use_https_scheme = enabled;
407+
self
408+
}
391409
}
392410

393411
/// IPC handler.

crates/tauri-runtime/src/window.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,23 @@ pub struct DetachedWindow<T: UserEvent, R: Runtime<T>> {
512512
pub dispatcher: R::WindowDispatcher,
513513

514514
/// The webview dispatcher in case this window has an attached webview.
515-
pub webview: Option<DetachedWebview<T, R>>,
515+
pub webview: Option<DetachedWindowWebview<T, R>>,
516+
}
517+
518+
/// A detached webview associated with a window.
519+
#[derive(Debug)]
520+
pub struct DetachedWindowWebview<T: UserEvent, R: Runtime<T>> {
521+
pub webview: DetachedWebview<T, R>,
522+
pub use_https_scheme: bool,
523+
}
524+
525+
impl<T: UserEvent, R: Runtime<T>> Clone for DetachedWindowWebview<T, R> {
526+
fn clone(&self) -> Self {
527+
Self {
528+
webview: self.webview.clone(),
529+
use_https_scheme: self.use_https_scheme,
530+
}
531+
}
516532
}
517533

518534
impl<T: UserEvent, R: Runtime<T>> Clone for DetachedWindow<T, R> {

crates/tauri-schema-generator/schemas/config.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,11 @@
486486
"description": "Whether browser extensions can be installed for the webview process\n\n ## Platform-specific:\n\n - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled)\n - **MacOS / Linux / iOS / Android** - Unsupported.",
487487
"default": false,
488488
"type": "boolean"
489+
},
490+
"useHttpsScheme": {
491+
"description": "Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.",
492+
"default": false,
493+
"type": "boolean"
489494
}
490495
},
491496
"additionalProperties": false

crates/tauri-utils/src/config.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1519,6 +1519,18 @@ pub struct WindowConfig {
15191519
/// - **MacOS / Linux / iOS / Android** - Unsupported.
15201520
#[serde(default)]
15211521
pub browser_extensions_enabled: bool,
1522+
1523+
/// Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.
1524+
///
1525+
/// ## Note
1526+
///
1527+
/// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.
1528+
///
1529+
/// ## Warning
1530+
///
1531+
/// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.
1532+
#[serde(default, alias = "use-https-scheme")]
1533+
pub use_https_scheme: bool,
15221534
}
15231535

15241536
impl Default for WindowConfig {
@@ -1567,6 +1579,7 @@ impl Default for WindowConfig {
15671579
proxy_url: None,
15681580
zoom_hotkeys_enabled: false,
15691581
browser_extensions_enabled: false,
1582+
use_https_scheme: false,
15701583
}
15711584
}
15721585
}
@@ -2538,6 +2551,7 @@ mod build {
25382551
let parent = opt_str_lit(self.parent.as_ref());
25392552
let zoom_hotkeys_enabled = self.zoom_hotkeys_enabled;
25402553
let browser_extensions_enabled = self.browser_extensions_enabled;
2554+
let use_https_scheme = self.use_https_scheme;
25412555

25422556
literal_struct!(
25432557
tokens,
@@ -2584,7 +2598,8 @@ mod build {
25842598
incognito,
25852599
parent,
25862600
zoom_hotkeys_enabled,
2587-
browser_extensions_enabled
2601+
browser_extensions_enabled,
2602+
use_https_scheme
25882603
);
25892604
}
25902605
}

crates/tauri/scripts/core.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
}
99

1010
const osName = __TEMPLATE_os_name__
11+
const protocolScheme = __TEMPLATE_protocol_scheme__
1112

1213
Object.defineProperty(window.__TAURI_INTERNALS__, 'convertFileSrc', {
1314
value: function (filePath, protocol = 'asset') {
1415
const path = encodeURIComponent(filePath)
1516
return osName === 'windows' || osName === 'android'
16-
? `http://${protocol}.localhost/${path}`
17+
? `${protocolScheme}://${protocol}.localhost/${path}`
1718
: `${protocol}://localhost/${path}`
1819
}
1920
})

0 commit comments

Comments
 (0)