feat(core): add support to setting a webview proxy, closes #4263 (#8441)

* feat(wry): support proxy in wry runtime

wry has been supported http/socks5 proxy in
[#1006](https://github.com/tauri-apps/wry/pull/1006), which has been
merged in [commit
3cc4d79](3cc4d79843).

This patch aims to support its feature.

Signed-off-by: lin fu <river@vvl.me>

* Apply suggestions from code review

* Apply suggestions from code review

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

* Update core/tauri/src/window/mod.rs

* add macos-proxy flag

* add change file

* delete file

* update change file

* use macos-14 runner to test core

---------

Signed-off-by: lin fu <river@vvl.me>
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
This commit is contained in:
time-river 2024-02-01 19:53:32 +08:00 committed by GitHub
parent a093682d2d
commit 6639a579c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 114 additions and 4 deletions

View File

@ -0,0 +1,8 @@
---
'tauri': 'minor:feat'
'tauri-utils': 'minor:feat'
'tauri-runtime-wry': 'minor'
'tauri-runtime': 'minor'
---
Added the `WindowConfig::proxy_url` `WebviewBuilder::proxy_url() / WebviewWindowBuilder::proxy_url()` options when creating a webview.

View File

@ -46,8 +46,8 @@ jobs:
command: 'test'
}
- {
target: x86_64-apple-darwin,
os: macos-latest,
target: aarch64-apple-darwin,
os: macos-14,
toolchain: '1.70.0',
cross: false,
command: 'test'

View File

@ -574,6 +574,14 @@
"string",
"null"
]
},
"proxyUrl": {
"description": "The proxy URL for the WebView for all network requests.\n\nMust be either a `http://` or a `socks5://` URL.\n\n## Platform-specific\n\n- **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+.",
"type": [
"string",
"null"
],
"format": "uri"
}
},
"additionalProperties": false

View File

@ -50,3 +50,4 @@ macos-private-api = [
objc-exception = [ "wry/objc-exception" ]
linux-protocol-body = [ "wry/linux-body", "webkit2gtk/v2_40" ]
tracing = [ "dep:tracing", "wry/tracing" ]
macos-proxy = [ "wry/mac-proxy" ]

View File

@ -63,7 +63,10 @@ use tauri_utils::TitleBarStyle;
use tauri_utils::{
config::WindowConfig, debug_eprintln, ProgressBarState, ProgressBarStatus, Theme,
};
use wry::{FileDropEvent as WryFileDropEvent, Url, WebContext, WebView, WebViewBuilder};
use wry::{
FileDropEvent as WryFileDropEvent, ProxyConfig, ProxyEndpoint, Url, WebContext, WebView,
WebViewBuilder,
};
pub use tao;
pub use tao::window::{Window, WindowBuilder as TaoWindowBuilder, WindowId as TaoWindowId};
@ -3111,6 +3114,23 @@ pub fn center_window(window: &Window, window_size: TaoPhysicalSize<u32>) -> Resu
}
}
fn parse_proxy_url(url: &Url) -> Result<ProxyConfig> {
let host = url.host().map(|h| h.to_string()).unwrap_or_default();
let port = url.port().map(|p| p.to_string()).unwrap_or_default();
if url.scheme() == "http" {
let config = ProxyConfig::Http(ProxyEndpoint { host, port });
Ok(config)
} else if url.scheme() == "socks5" {
let config = ProxyConfig::Socks5(ProxyEndpoint { host, port });
Ok(config)
} else {
Err(Error::InvalidProxyUrl)
}
}
fn create_window<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
window_id: WindowId,
webview_id: u32,
@ -3405,6 +3425,12 @@ fn create_webview<T: UserEvent>(
webview_builder = webview_builder.with_user_agent(&user_agent);
}
if let Some(proxy_url) = webview_attributes.proxy_url {
let config = parse_proxy_url(&proxy_url)?;
webview_builder = webview_builder.with_proxy_config(config);
}
#[cfg(windows)]
{
if let Some(additional_browser_args) = webview_attributes.additional_browser_args {

View File

@ -122,6 +122,8 @@ pub enum Error {
Infallible(#[from] std::convert::Infallible),
#[error("the event loop has been closed")]
EventLoopClosed,
#[error("Invalid proxy url")]
InvalidProxyUrl,
#[error("window not found")]
WindowNotFound,
}

View File

@ -211,6 +211,7 @@ pub struct WebviewAttributes {
pub transparent: bool,
pub bounds: Option<(Position, Size)>,
pub auto_resize: bool,
pub proxy_url: Option<Url>,
}
impl From<&WindowConfig> for WebviewAttributes {
@ -234,6 +235,9 @@ impl From<&WindowConfig> for WebviewAttributes {
if let Some(effects) = &config.window_effects {
builder = builder.window_effects(effects.clone());
}
if let Some(url) = &config.proxy_url {
builder = builder.proxy_url(url.to_owned());
}
builder
}
}
@ -255,6 +259,7 @@ impl WebviewAttributes {
transparent: false,
bounds: None,
auto_resize: false,
proxy_url: None,
}
}
@ -338,6 +343,13 @@ impl WebviewAttributes {
self.auto_resize = true;
self
}
/// Enable proxy for the WebView
#[must_use]
pub fn proxy_url(mut self, url: Url) -> Self {
self.proxy_url = Some(url);
self
}
}
/// IPC handler.

View File

@ -1267,6 +1267,14 @@ pub struct WindowConfig {
/// - **Linux**: This makes the new window transient for parent, see <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
/// - **macOS**: This adds the window as a child of parent, see <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>
pub parent: Option<String>,
/// The proxy URL for the WebView for all network requests.
///
/// Must be either a `http://` or a `socks5://` URL.
///
/// ## Platform-specific
///
/// - **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+.
pub proxy_url: Option<Url>,
}
impl Default for WindowConfig {
@ -1311,6 +1319,7 @@ impl Default for WindowConfig {
window_effects: None,
incognito: false,
parent: None,
proxy_url: None,
}
}
}
@ -2306,6 +2315,7 @@ mod build {
let minimizable = self.minimizable;
let closable = self.closable;
let title = str_lit(&self.title);
let proxy_url = opt_str_lit(self.proxy_url.as_ref());
let fullscreen = self.fullscreen;
let focus = self.focus;
let transparent = self.transparent;
@ -2349,6 +2359,7 @@ mod build {
minimizable,
closable,
title,
proxy_url,
fullscreen,
focus,
transparent,

View File

@ -163,6 +163,7 @@ config-json5 = [ "tauri-macros/config-json5" ]
config-toml = [ "tauri-macros/config-toml" ]
icon-ico = [ "infer", "ico" ]
icon-png = [ "infer", "png" ]
macos-proxy = [ "tauri-runtime-wry/macos-proxy" ]
[[example]]
name = "commands"

View File

@ -35,6 +35,7 @@
//! - **config-toml**: Adds support to TOML format for the configuration `Tauri.toml`.
//! - **icon-ico**: Adds support to set `.ico` window icons. Enables [`Icon::File`] and [`Icon::Raw`] variants.
//! - **icon-png**: Adds support to set `.png` window icons. Enables [`Icon::File`] and [`Icon::Raw`] variants.
//! - **macos-proxy**: Adds support for [`WebviewBuilder::proxy_url`] on macOS. Requires macOS 14+.
//!
//! ## Cargo allowlist features
//!

View File

@ -758,6 +758,19 @@ fn main() {
self
}
/// Set a proxy URL for the WebView for all network requests.
///
/// Must be either a `http://` or a `socks5://` URL.
///
/// ## Platform-specific
///
/// - **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+.
#[must_use]
pub fn proxy_url(mut self, url: Url) -> Self {
self.webview_attributes.proxy_url = Some(url);
self
}
/// Enable or disable transparency for the WebView.
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
#[cfg_attr(

View File

@ -824,6 +824,15 @@ fn main() {
self.webview_builder = self.webview_builder.auto_resize();
self
}
/// Set a proxy URL for the WebView for all network requests.
///
/// Must be either a `http://` or a `socks5://` URL.
#[must_use]
pub fn proxy_url(mut self, url: Url) -> Self {
self.webview_builder = self.webview_builder.proxy_url(url);
self
}
}
/// A type that wraps a [`Window`] together with a [`Webview`].

View File

@ -306,7 +306,7 @@ class Webview {
* @param payload Event payload.
*/
async emitTo(
target: string,
target: string | EventTarget,
event: string,
payload?: unknown
): Promise<void> {
@ -791,6 +791,16 @@ interface WebviewOptions {
* - **Android:** Unsupported.
*/
incognito?: boolean
/**
* The proxy URL for the WebView for all network requests.
*
* Must be either a `http://` or a `socks5://` URL.
*
* #### Platform-specific
*
* - **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+.
* */
proxyUrl?: string
}
export { Webview, WebviewWindow, getCurrent, getAll }

View File

@ -574,6 +574,14 @@
"string",
"null"
]
},
"proxyUrl": {
"description": "The proxy URL for the WebView for all network requests.\n\nMust be either a `http://` or a `socks5://` URL.\n\n## Platform-specific\n\n- **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+.",
"type": [
"string",
"null"
],
"format": "uri"
}
},
"additionalProperties": false