diff --git a/.changes/windows-http.md b/.changes/windows-http.md new file mode 100644 index 000000000..402381bc7 --- /dev/null +++ b/.changes/windows-http.md @@ -0,0 +1,5 @@ +--- +"wry": "minor" +--- + +**Breaking change** Wry now defaults to `http://.localhost/` for custom protocols on Windows. diff --git a/.changes/windows-with-https-scheme.md b/.changes/windows-with-https-scheme.md new file mode 100644 index 000000000..0565f6e95 --- /dev/null +++ b/.changes/windows-with-https-scheme.md @@ -0,0 +1,5 @@ +--- +"wry": "minor" +--- + +Add `WebViewBuilderExtWindows::with_https_scheme` to be able to choose between `http` and `https` for custom protocols on Windows. diff --git a/src/webview/mod.rs b/src/webview/mod.rs index ededc87cf..ec0e68d9a 100644 --- a/src/webview/mod.rs +++ b/src/webview/mod.rs @@ -277,6 +277,7 @@ pub(crate) struct PlatformSpecificWebViewAttributes { additional_browser_args: Option, browser_accelerator_keys: bool, theme: Option, + https_scheme: bool, } #[cfg(windows)] impl Default for PlatformSpecificWebViewAttributes { @@ -285,6 +286,7 @@ impl Default for PlatformSpecificWebViewAttributes { additional_browser_args: None, browser_accelerator_keys: true, // This is WebView2's default behavior theme: None, + https_scheme: false, // To match macOS & Linux behavior in the context of mixed content. } } } @@ -695,6 +697,14 @@ pub trait WebViewBuilderExtWindows { /// /// Defaults to [`Theme::Auto`] which will follow the OS defaults. fn with_theme(self, theme: Theme) -> Self; + + /// Determines whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost`. + /// + /// Using a `http` scheme will allow mixed content when trying to fetch `http` endpoints + /// and is therefore less secure but will match the behavior of the `://localhost` protocols used on macOS and Linux. + /// + /// The default value is `false`. + fn with_https_scheme(self, enabled: bool) -> Self; } #[cfg(windows)] @@ -713,6 +723,11 @@ impl WebViewBuilderExtWindows for WebViewBuilder<'_> { self.platform_specific.theme = Some(theme); self } + + fn with_https_scheme(mut self, enabled: bool) -> Self { + self.platform_specific.https_scheme = enabled; + self + } } #[cfg(target_os = "android")] diff --git a/src/webview/webview2/mod.rs b/src/webview/webview2/mod.rs index e73ee5cbe..9781cb963 100644 --- a/src/webview/webview2/mod.rs +++ b/src/webview/webview2/mod.rs @@ -537,15 +537,20 @@ window.addEventListener('mousemove', (e) => window.chrome.webview.postMessage('_ } } + let scheme = if pl_attrs.https_scheme { + "https" + } else { + "http" + }; let mut custom_protocol_names = HashSet::new(); if !attributes.custom_protocols.is_empty() { for (name, _) in &attributes.custom_protocols { - // WebView2 doesn't support non-standard protocols yet, so we have to use this workaround + // WebView2 supports non-standard protocols only on Windows 10+, so we have to use this workaround // See https://github.com/MicrosoftEdge/WebView2Feedback/issues/73 custom_protocol_names.insert(name.clone()); unsafe { webview.AddWebResourceRequestedFilter( - PCWSTR::from_raw(encode_wide(format!("https://{}.*", name)).as_ptr()), + PCWSTR::from_raw(encode_wide(format!("{scheme}://{name}.*")).as_ptr()), COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL, ) } @@ -616,11 +621,11 @@ window.addEventListener('mousemove', (e) => window.chrome.webview.postMessage('_ if let Some(custom_protocol) = custom_protocols .iter() - .find(|(name, _)| uri.starts_with(&format!("https://{}.", name))) + .find(|(name, _)| uri.starts_with(&format!("{scheme}://{name}."))) { // Undo the protocol workaround when giving path to resolver let path = uri.replace( - &format!("https://{}.", custom_protocol.0), + &format!("{scheme}://{}.", custom_protocol.0), &format!("{}://", custom_protocol.0), ); @@ -741,11 +746,11 @@ window.addEventListener('mousemove', (e) => window.chrome.webview.postMessage('_ let mut url_string = String::from(url.as_str()); let name = url.scheme(); if custom_protocol_names.contains(name) { - // WebView2 doesn't support non-standard protocols yet, so we have to use this workaround + // WebView2 supports non-standard protocols only on Windows 10+, so we have to use this workaround // See https://github.com/MicrosoftEdge/WebView2Feedback/issues/73 url_string = url .as_str() - .replace(&format!("{}://", name), &format!("https://{}.", name)) + .replace(&format!("{}://", name), &format!("{scheme}://{name}.")) } if let Some(headers) = attributes.headers {