Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/cookies-for-url.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": minor:feat
---

Added `Webview::cookies()`, `Webview::cookies_for_url()`, `WebviewWindow::cookies()` and `Webview::cookies_for_url()`.
6 changes: 6 additions & 0 deletions .changes/webview-cookies-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-runtime": minor:feat
"tauri-runtime-wry": minor:feat
---

Added `WebviewDispatch::cookies()` and `WebviewDispatch::cookies_for_url()`.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 37 additions & 3 deletions crates/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ use tauri_runtime::{
CursorIcon, DetachedWindow, DetachedWindowWebview, DragDropEvent, PendingWindow, RawWindow,
WebviewEvent, WindowBuilder, WindowBuilderBase, WindowEvent, WindowId, WindowSizeConstraints,
},
DeviceEventFilter, Error, EventLoopProxy, ExitRequestedEventAction, Icon, ProgressBarState,
ProgressBarStatus, Result, RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs, UserAttentionType,
UserEvent, WebviewDispatch, WebviewEventId, WindowDispatch, WindowEventId,
Cookie, DeviceEventFilter, Error, EventLoopProxy, ExitRequestedEventAction, Icon,
ProgressBarState, ProgressBarStatus, Result, RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs,
UserAttentionType, UserEvent, WebviewDispatch, WebviewEventId, WindowDispatch, WindowEventId,
};

#[cfg(any(target_os = "macos", target_os = "ios"))]
Expand Down Expand Up @@ -1299,6 +1299,8 @@ pub enum WebviewMessage {
EvaluateScript(String),
#[cfg(all(feature = "tracing", not(target_os = "android")))]
EvaluateScript(String, Sender<()>, tracing::Span),
CookiesForUrl(Url, Sender<Result<Vec<tauri_runtime::Cookie<'static>>>>),
Cookies(Sender<Result<Vec<tauri_runtime::Cookie<'static>>>>),
WebviewEvent(WebviewEvent),
SynthesizedWindowEvent(SynthesizedWindowEvent),
Navigate(Url),
Expand Down Expand Up @@ -1549,6 +1551,25 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
Ok(())
}

fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>> {
let current_window_id = self.window_id.lock().unwrap();
let (tx, rx) = channel();
send_user_message(
&self.context,
Message::Webview(
*current_window_id,
self.webview_id,
WebviewMessage::CookiesForUrl(url, tx),
),
)?;

rx.recv().unwrap()
}

fn cookies(&self) -> Result<Vec<Cookie<'static>>> {
webview_getter!(self, WebviewMessage::Cookies)?
}

fn set_auto_resize(&self, auto_resize: bool) -> Result<()> {
send_user_message(
&self.context,
Expand Down Expand Up @@ -3407,6 +3428,19 @@ fn handle_user_message<T: UserEvent>(
)
.unwrap();
}

WebviewMessage::Cookies(tx) => {
tx.send(webview.cookies().map_err(|_| Error::FailedToSendMessage))
.unwrap();
}

WebviewMessage::CookiesForUrl(url, tx) => {
let webview_cookies = webview
.cookies_for_url(url.as_str())
.map_err(|_| Error::FailedToSendMessage);
tx.send(webview_cookies).unwrap();
}

WebviewMessage::Bounds(tx) => {
tx.send(
webview
Expand Down
2 changes: 2 additions & 0 deletions crates/tauri-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ http = "1"
raw-window-handle = "0.6"
url = { version = "2" }
dpi = { version = "0.1", features = ["serde"] }
# WARNING: cookie::Cookie is re-exported so bumping this is a breaking change
cookie = "0.18"

[target."cfg(windows)".dependencies.windows]
version = "0.58"
Expand Down
9 changes: 9 additions & 0 deletions crates/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ use http::{
/// UI scaling utilities.
pub use dpi;

/// Cookie extraction
pub use cookie::Cookie;

pub type WindowEventId = u32;
pub type WebviewEventId = u32;

Expand Down Expand Up @@ -516,6 +519,12 @@ pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + '
/// Moves the webview to the given window.
fn reparent(&self, window_id: WindowId) -> Result<()>;

/// Get cookies for a particular url.
fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;

/// Return all cookies in the cookie store.
fn cookies(&self) -> Result<Vec<Cookie<'static>>>;

/// Sets whether the webview should automatically grow and shrink its size and position when the parent window resizes.
fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;

Expand Down
8 changes: 8 additions & 0 deletions crates/tauri/src/test/mock_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,14 @@ impl<T: UserEvent> WebviewDispatch<T> for MockWebviewDispatcher {
Ok(())
}

fn cookies(&self) -> Result<Vec<tauri_runtime::Cookie<'static>>> {
Ok(Vec::new())
}

fn cookies_for_url(&self, url: Url) -> Result<Vec<tauri_runtime::Cookie<'static>>> {
Ok(Vec::new())
}

fn set_auto_resize(&self, auto_resize: bool) -> Result<()> {
Ok(())
}
Expand Down
49 changes: 45 additions & 4 deletions crates/tauri/src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use http::HeaderMap;
use serde::Serialize;
use tauri_macros::default_runtime;
pub use tauri_runtime::webview::PageLoadEvent;
pub use tauri_runtime::Cookie;
#[cfg(desktop)]
use tauri_runtime::{
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
Expand Down Expand Up @@ -246,8 +247,8 @@ impl<R: Runtime> WebviewBuilder<R> {
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
/// You should use `async` commands when creating windows.
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when creating webviews.
///
/// # Examples
///
Expand Down Expand Up @@ -322,8 +323,8 @@ async fn create_window(app: tauri::AppHandle) {
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
/// You should use `async` commands when creating webviews.
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when creating webviews.
///
/// # Examples
///
Expand Down Expand Up @@ -1703,6 +1704,46 @@ tauri::Builder::default()
.clear_all_browsing_data()
.map_err(Into::into)
}

/// Returns all cookies in the runtime's cookie store including HTTP-only and secure cookies.
///
/// Note that cookies will only be returned for URLs with an http or https scheme.
/// Cookies set through javascript for local files
/// (such as those served from the tauri://) protocol are not currently supported.
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when reading cookies.
///
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
pub fn cookies_for_url(&self, url: Url) -> crate::Result<Vec<Cookie<'static>>> {
self
.webview
.dispatcher
.cookies_for_url(url)
.map_err(Into::into)
}

/// Returns all cookies in the runtime's cookie store for all URLs including HTTP-only and secure cookies.
///
/// Note that cookies will only be returned for URLs with an http or https scheme.
/// Cookies set through javascript for local files
/// (such as those served from the tauri://) protocol are not currently supported.
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when reading cookies.
///
/// ## Platform-specific
///
/// - **Android**: Unsupported, always returns an empty [`Vec`].
///
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
pub fn cookies(&self) -> crate::Result<Vec<Cookie<'static>>> {
self.webview.dispatcher.cookies().map_err(Into::into)
}
}

impl<R: Runtime> Listener<R> for Webview<R> {
Expand Down
47 changes: 41 additions & 6 deletions crates/tauri/src/webview/webview_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ use crate::{
ipc::{CommandArg, CommandItem, InvokeError, OwnedInvokeResponder},
manager::AppManager,
sealed::{ManagerBase, RuntimeOrDispatch},
webview::PageLoadPayload,
webview::WebviewBuilder,
webview::{Cookie, PageLoadPayload, WebviewBuilder},
window::WindowBuilder,
AppHandle, Event, EventId, Manager, Runtime, Webview, WindowEvent,
};
Expand All @@ -61,8 +60,8 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
/// You should use `async` commands when creating windows.
/// On Windows, this function deadlocks when used in a synchronous command and event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when creating windows.
///
/// # Examples
///
Expand Down Expand Up @@ -118,8 +117,8 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
/// You should use `async` commands when creating windows.
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when creating windows.
///
/// # Examples
///
Expand Down Expand Up @@ -2005,6 +2004,42 @@ impl<R: Runtime> WebviewWindow<R> {
pub fn clear_all_browsing_data(&self) -> crate::Result<()> {
self.webview.clear_all_browsing_data()
}

/// Returns all cookies in the runtime's cookie store including HTTP-only and secure cookies.
///
/// Note that cookies will only be returned for URLs with an http or https scheme.
/// Cookies set through javascript for local files
/// (such as those served from the tauri://) protocol are not currently supported.
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when reading cookies.
///
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
pub fn cookies_for_url(&self, url: Url) -> crate::Result<Vec<Cookie<'static>>> {
self.webview.cookies_for_url(url)
}

/// Returns all cookies in the runtime's cookie store for all URLs including HTTP-only and secure cookies.
///
/// Note that cookies will only be returned for URLs with an http or https scheme.
/// Cookies set through javascript for local files
/// (such as those served from the tauri://) protocol are not currently supported.
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when reading cookies.
///
/// ## Platform-specific
///
/// - **Android**: Unsupported, always returns an empty [`Vec`].
///
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
pub fn cookies(&self) -> crate::Result<Vec<Cookie<'static>>> {
self.webview.cookies()
}
}

impl<R: Runtime> Listener<R> for WebviewWindow<R> {
Expand Down
8 changes: 4 additions & 4 deletions crates/tauri/src/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ impl<'a, R: Runtime, M: Manager<R>> WindowBuilder<'a, R, M> {
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
/// You should use `async` commands when creating windows.
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when creating windows.
///
/// # Examples
///
Expand Down Expand Up @@ -217,8 +217,8 @@ async fn create_window(app: tauri::AppHandle) {
///
/// # Known issues
///
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
/// You should use `async` commands when creating windows.
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
/// You should use `async` commands and separate threads when creating windows.
///
/// # Examples
///
Expand Down
11 changes: 10 additions & 1 deletion examples/helloworld/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

#[tauri::command]
fn greet(name: &str) -> String {
fn greet(app: tauri::AppHandle, name: String) -> String {
use tauri::Manager;
println!("greet {name}");
let w = app.get_webview_window("main").unwrap();
println!("{:?}", w.get_webview_window("main").unwrap().cookies());
format!("Hello {name}, You have been greeted from Rust!")
}

fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.setup(|app| {
use tauri::Manager;
println!("{:?}", app.get_webview_window("main").unwrap().cookies());
Ok(())
})
.run(tauri::generate_context!(
"../../examples/helloworld/tauri.conf.json"
))
Expand Down
Loading