diff --git a/.changes/convert-file-src-https.md b/.changes/convert-file-src-https.md new file mode 100644 index 000000000..9ba8d29ab --- /dev/null +++ b/.changes/convert-file-src-https.md @@ -0,0 +1,5 @@ +--- +"tauri": patch:feat +--- + +Add `use_https` parameter to `PathResolver::convert_file_src` to support webviews with `use_https_scheme` enabled. diff --git a/crates/tauri/src/path/android.rs b/crates/tauri/src/path/android.rs index 451032ee7..a03f95013 100644 --- a/crates/tauri/src/path/android.rs +++ b/crates/tauri/src/path/android.rs @@ -4,6 +4,7 @@ use super::Result; use crate::{plugin::PluginHandle, Runtime}; +use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; use std::path::{Path, PathBuf}; /// A helper class to access the mobile path APIs. @@ -175,4 +176,43 @@ impl PathResolver { pub fn home_dir(&self) -> Result { self.call_resolve("getHomeDir") } + + /// Converts a file path to a URL that can be loaded by the webview. + /// + /// This is the Rust equivalent of the JavaScript `convertFileSrc` function. + /// Note: The file must be allowed by the app's asset scope for the webview to load it. + /// + /// # Arguments + /// + /// * `path` - The file path to convert + /// * `protocol` - The protocol to use, defaults to `"asset"` if `None` + /// * `use_https` - Whether to use HTTPS scheme instead of HTTP. + /// Set to `true` if your webview has `use_https_scheme` enabled. Defaults to `false` if `None`. + /// + /// # Examples + /// + /// ```rust,no_run + /// use tauri::Manager; + /// tauri::Builder::default() + /// .setup(|app| { + /// let video_path = app.path().app_data_dir()?.join("video.mp4"); + /// let url = app.path().convert_file_src(&video_path, None, None); + /// // On Android: http://asset.localhost/... + /// println!("URL: {}", url); + /// + /// // With HTTPS enabled: + /// let https_url = app.path().convert_file_src(&video_path, None, Some(true)); + /// // On Android: https://asset.localhost/... + /// println!("HTTPS URL: {}", https_url); + /// Ok(()) + /// }); + /// ``` + pub fn convert_file_src>(&self, path: P, protocol: Option<&str>, use_https: Option) -> String { + let protocol = protocol.unwrap_or("asset"); + let path = path.as_ref(); + let encoded = utf8_percent_encode(&path.to_string_lossy(), NON_ALPHANUMERIC).to_string(); + + let scheme = if use_https.unwrap_or(false) { "https" } else { "http" }; + format!("{scheme}://{protocol}.localhost/{encoded}") + } } diff --git a/crates/tauri/src/path/desktop.rs b/crates/tauri/src/path/desktop.rs index 96ea0bd7e..0aad9f2d5 100644 --- a/crates/tauri/src/path/desktop.rs +++ b/crates/tauri/src/path/desktop.rs @@ -4,6 +4,7 @@ use super::{Error, Result}; use crate::{AppHandle, Manager, Runtime}; +use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; use std::path::{Path, PathBuf}; /// The path resolver is a helper class for general and application-specific path APIs. @@ -293,4 +294,52 @@ impl PathResolver { pub fn temp_dir(&self) -> Result { Ok(std::env::temp_dir()) } + + /// Converts a file path to a URL that can be loaded by the webview. + /// + /// This is the Rust equivalent of the JavaScript `convertFileSrc` function. + /// Note: The file must be allowed by the app's asset scope for the webview to load it. + /// + /// # Arguments + /// + /// * `path` - The file path to convert + /// * `protocol` - The protocol to use, defaults to `"asset"` if `None` + /// * `use_https` - Whether to use HTTPS scheme instead of HTTP (Windows only). + /// Set to `true` if your webview has `use_https_scheme` enabled. Defaults to `false` if `None`. + /// + /// # Examples + /// + /// ```rust,no_run + /// use tauri::Manager; + /// tauri::Builder::default() + /// .setup(|app| { + /// let video_path = app.path().app_data_dir()?.join("video.mp4"); + /// let url = app.path().convert_file_src(&video_path, None, None); + /// // On Windows: http://asset.localhost/C%3A%5CUsers%5C... + /// // On macOS/Linux: asset://localhost/%2FUsers%2F... + /// println!("URL: {}", url); + /// + /// // With HTTPS enabled (Windows): + /// let https_url = app.path().convert_file_src(&video_path, None, Some(true)); + /// // On Windows: https://asset.localhost/C%3A%5CUsers%5C... + /// println!("HTTPS URL: {}", https_url); + /// Ok(()) + /// }); + /// ``` + pub fn convert_file_src>(&self, path: P, protocol: Option<&str>, use_https: Option) -> String { + let protocol = protocol.unwrap_or("asset"); + let path = dunce::simplified(path.as_ref()); + let encoded = utf8_percent_encode(&path.to_string_lossy(), NON_ALPHANUMERIC).to_string(); + + #[cfg(windows)] + { + let scheme = if use_https.unwrap_or(false) { "https" } else { "http" }; + format!("{scheme}://{protocol}.localhost/{encoded}") + } + #[cfg(not(windows))] + { + let _ = use_https; // unused on non-Windows platforms + format!("{protocol}://localhost/{encoded}") + } + } }