Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 12 commits into from
Feb 1, 2024
8 changes: 8 additions & 0 deletions .changes/webview-proxy.md
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 2 additions & 2 deletions .github/workflows/test-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
8 changes: 8 additions & 0 deletions core/tauri-config-schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions core/tauri-runtime-wry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]
28 changes: 27 additions & 1 deletion core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions core/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
12 changes: 12 additions & 0 deletions core/tauri-runtime/src/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
}
Expand All @@ -255,6 +259,7 @@ impl WebviewAttributes {
transparent: false,
bounds: None,
auto_resize: false,
proxy_url: None,
}
}

Expand Down Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -1311,6 +1319,7 @@ impl Default for WindowConfig {
window_effects: None,
incognito: false,
parent: None,
proxy_url: None,
}
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2349,6 +2359,7 @@ mod build {
minimizable,
closable,
title,
proxy_url,
fullscreen,
focus,
transparent,
Expand Down
1 change: 1 addition & 0 deletions core/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions core/tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
//!
Expand Down
13 changes: 13 additions & 0 deletions core/tauri/src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
9 changes: 9 additions & 0 deletions core/tauri/src/webview/webview_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`].
Expand Down
12 changes: 11 additions & 1 deletion tooling/api/src/webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ class Webview {
* @param payload Event payload.
*/
async emitTo(
target: string,
target: string | EventTarget,
event: string,
payload?: unknown
): Promise<void> {
Expand Down Expand Up @@ -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 }
Expand Down
8 changes: 8 additions & 0 deletions tooling/cli/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading