Skip to content

Commit cedb24d

Browse files
charrondevacharron-hllucasfernog
authored
feat: add Webview::cookies and Webview::cookies_for_url() (#12665)
* Add support for fetching cookies by url * Add support for fetching all cookies * add missing getters, update change file * update docs for windows deadlock * fix mobile build * Update crates/tauri-runtime/Cargo.toml * add docs for stability [skip ci] --------- Co-authored-by: Adam Charron <acharron@higherlogic.com> Co-authored-by: Lucas Nogueira <lucas@tauri.app>
1 parent 30f5a15 commit cedb24d

File tree

11 files changed

+198
-18
lines changed

11 files changed

+198
-18
lines changed

.changes/cookies-for-url.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": minor:feat
3+
---
4+
5+
Added `Webview::cookies()`, `Webview::cookies_for_url()`, `WebviewWindow::cookies()` and `Webview::cookies_for_url()`.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri-runtime": minor:feat
3+
"tauri-runtime-wry": minor:feat
4+
---
5+
6+
Added `WebviewDispatch::cookies()` and `WebviewDispatch::cookies_for_url()`.

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tauri-runtime-wry/src/lib.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ use tauri_runtime::{
2323
CursorIcon, DetachedWindow, DetachedWindowWebview, DragDropEvent, PendingWindow, RawWindow,
2424
WebviewEvent, WindowBuilder, WindowBuilderBase, WindowEvent, WindowId, WindowSizeConstraints,
2525
},
26-
DeviceEventFilter, Error, EventLoopProxy, ExitRequestedEventAction, Icon, ProgressBarState,
27-
ProgressBarStatus, Result, RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs, UserAttentionType,
28-
UserEvent, WebviewDispatch, WebviewEventId, WindowDispatch, WindowEventId,
26+
Cookie, DeviceEventFilter, Error, EventLoopProxy, ExitRequestedEventAction, Icon,
27+
ProgressBarState, ProgressBarStatus, Result, RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs,
28+
UserAttentionType, UserEvent, WebviewDispatch, WebviewEventId, WindowDispatch, WindowEventId,
2929
};
3030

3131
#[cfg(any(target_os = "macos", target_os = "ios"))]
@@ -1317,6 +1317,8 @@ pub enum WebviewMessage {
13171317
EvaluateScript(String),
13181318
#[cfg(all(feature = "tracing", not(target_os = "android")))]
13191319
EvaluateScript(String, Sender<()>, tracing::Span),
1320+
CookiesForUrl(Url, Sender<Result<Vec<tauri_runtime::Cookie<'static>>>>),
1321+
Cookies(Sender<Result<Vec<tauri_runtime::Cookie<'static>>>>),
13201322
WebviewEvent(WebviewEvent),
13211323
SynthesizedWindowEvent(SynthesizedWindowEvent),
13221324
Navigate(Url),
@@ -1578,6 +1580,25 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
15781580
Ok(())
15791581
}
15801582

1583+
fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>> {
1584+
let current_window_id = self.window_id.lock().unwrap();
1585+
let (tx, rx) = channel();
1586+
send_user_message(
1587+
&self.context,
1588+
Message::Webview(
1589+
*current_window_id,
1590+
self.webview_id,
1591+
WebviewMessage::CookiesForUrl(url, tx),
1592+
),
1593+
)?;
1594+
1595+
rx.recv().unwrap()
1596+
}
1597+
1598+
fn cookies(&self) -> Result<Vec<Cookie<'static>>> {
1599+
webview_getter!(self, WebviewMessage::Cookies)?
1600+
}
1601+
15811602
fn set_auto_resize(&self, auto_resize: bool) -> Result<()> {
15821603
send_user_message(
15831604
&self.context,
@@ -3506,6 +3527,19 @@ fn handle_user_message<T: UserEvent>(
35063527
)
35073528
.unwrap();
35083529
}
3530+
3531+
WebviewMessage::Cookies(tx) => {
3532+
tx.send(webview.cookies().map_err(|_| Error::FailedToSendMessage))
3533+
.unwrap();
3534+
}
3535+
3536+
WebviewMessage::CookiesForUrl(url, tx) => {
3537+
let webview_cookies = webview
3538+
.cookies_for_url(url.as_str())
3539+
.map_err(|_| Error::FailedToSendMessage);
3540+
tx.send(webview_cookies).unwrap();
3541+
}
3542+
35093543
WebviewMessage::Bounds(tx) => {
35103544
tx.send(
35113545
webview

crates/tauri-runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ http = "1"
3434
raw-window-handle = "0.6"
3535
url = { version = "2" }
3636
dpi = { version = "0.1", features = ["serde"] }
37+
# WARNING: cookie::Cookie is re-exported so bumping this is a breaking change, documented to be done as a minor bump
38+
cookie = "0.18"
3739

3840
[target."cfg(windows)".dependencies.windows]
3941
version = "0.60"

crates/tauri-runtime/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ use http::{
4343
/// UI scaling utilities.
4444
pub use dpi;
4545

46+
/// Cookie extraction
47+
pub use cookie::Cookie;
48+
4649
pub type WindowEventId = u32;
4750
pub type WebviewEventId = u32;
4851

@@ -537,6 +540,22 @@ pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + '
537540
/// Moves the webview to the given window.
538541
fn reparent(&self, window_id: WindowId) -> Result<()>;
539542

543+
/// Get cookies for a particular url.
544+
///
545+
/// # Stability
546+
///
547+
/// The return value of this function leverages [`cookie::Cookie`] which re-exports the cookie crate.
548+
/// This dependency might receive updates in minor Tauri releases.
549+
fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
550+
551+
/// Return all cookies in the cookie store.
552+
///
553+
/// # Stability
554+
///
555+
/// The return value of this function leverages [`cookie::Cookie`] which re-exports the cookie crate.
556+
/// This dependency might receive updates in minor Tauri releases.
557+
fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
558+
540559
/// Sets whether the webview should automatically grow and shrink its size and position when the parent window resizes.
541560
fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
542561

crates/tauri/src/test/mock_runtime.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,14 @@ impl<T: UserEvent> WebviewDispatch<T> for MockWebviewDispatcher {
612612
Ok(())
613613
}
614614

615+
fn cookies(&self) -> Result<Vec<tauri_runtime::Cookie<'static>>> {
616+
Ok(Vec::new())
617+
}
618+
619+
fn cookies_for_url(&self, url: Url) -> Result<Vec<tauri_runtime::Cookie<'static>>> {
620+
Ok(Vec::new())
621+
}
622+
615623
fn set_auto_resize(&self, auto_resize: bool) -> Result<()> {
616624
Ok(())
617625
}

crates/tauri/src/webview/mod.rs

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use http::HeaderMap;
1313
use serde::Serialize;
1414
use tauri_macros::default_runtime;
1515
pub use tauri_runtime::webview::PageLoadEvent;
16+
pub use tauri_runtime::Cookie;
1617
#[cfg(desktop)]
1718
use tauri_runtime::{
1819
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
@@ -246,8 +247,8 @@ impl<R: Runtime> WebviewBuilder<R> {
246247
///
247248
/// # Known issues
248249
///
249-
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
250-
/// You should use `async` commands when creating windows.
250+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
251+
/// You should use `async` commands and separate threads when creating webviews.
251252
///
252253
/// # Examples
253254
///
@@ -322,8 +323,8 @@ async fn create_window(app: tauri::AppHandle) {
322323
///
323324
/// # Known issues
324325
///
325-
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
326-
/// You should use `async` commands when creating webviews.
326+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
327+
/// You should use `async` commands and separate threads when creating webviews.
327328
///
328329
/// # Examples
329330
///
@@ -1723,6 +1724,56 @@ tauri::Builder::default()
17231724
.clear_all_browsing_data()
17241725
.map_err(Into::into)
17251726
}
1727+
1728+
/// Returns all cookies in the runtime's cookie store including HTTP-only and secure cookies.
1729+
///
1730+
/// Note that cookies will only be returned for URLs with an http or https scheme.
1731+
/// Cookies set through javascript for local files
1732+
/// (such as those served from the tauri://) protocol are not currently supported.
1733+
///
1734+
/// # Stability
1735+
///
1736+
/// The return value of this function leverages [`tauri_runtime::Cookie`] which re-exports the cookie crate.
1737+
/// This dependency might receive updates in minor Tauri releases.
1738+
///
1739+
/// # Known issues
1740+
///
1741+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
1742+
/// You should use `async` commands and separate threads when reading cookies.
1743+
///
1744+
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
1745+
pub fn cookies_for_url(&self, url: Url) -> crate::Result<Vec<Cookie<'static>>> {
1746+
self
1747+
.webview
1748+
.dispatcher
1749+
.cookies_for_url(url)
1750+
.map_err(Into::into)
1751+
}
1752+
1753+
/// Returns all cookies in the runtime's cookie store for all URLs including HTTP-only and secure cookies.
1754+
///
1755+
/// Note that cookies will only be returned for URLs with an http or https scheme.
1756+
/// Cookies set through javascript for local files
1757+
/// (such as those served from the tauri://) protocol are not currently supported.
1758+
///
1759+
/// # Stability
1760+
///
1761+
/// The return value of this function leverages [`tauri_runtime::Cookie`] which re-exports the cookie crate.
1762+
/// This dependency might receive updates in minor Tauri releases.
1763+
///
1764+
/// # Known issues
1765+
///
1766+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
1767+
/// You should use `async` commands and separate threads when reading cookies.
1768+
///
1769+
/// ## Platform-specific
1770+
///
1771+
/// - **Android**: Unsupported, always returns an empty [`Vec`].
1772+
///
1773+
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
1774+
pub fn cookies(&self) -> crate::Result<Vec<Cookie<'static>>> {
1775+
self.webview.dispatcher.cookies().map_err(Into::into)
1776+
}
17261777
}
17271778

17281779
impl<R: Runtime> Listener<R> for Webview<R> {

crates/tauri/src/webview/webview_window.rs

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ use crate::{
3737
ipc::{CommandArg, CommandItem, InvokeError, OwnedInvokeResponder},
3838
manager::AppManager,
3939
sealed::{ManagerBase, RuntimeOrDispatch},
40-
webview::PageLoadPayload,
41-
webview::WebviewBuilder,
40+
webview::{Cookie, PageLoadPayload, WebviewBuilder},
4241
window::WindowBuilder,
4342
AppHandle, Event, EventId, Manager, Runtime, Webview, WindowEvent,
4443
};
@@ -61,8 +60,8 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
6160
///
6261
/// # Known issues
6362
///
64-
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
65-
/// You should use `async` commands when creating windows.
63+
/// On Windows, this function deadlocks when used in a synchronous command and event handlers, see [the Webview2 issue].
64+
/// You should use `async` commands and separate threads when creating windows.
6665
///
6766
/// # Examples
6867
///
@@ -118,8 +117,8 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
118117
///
119118
/// # Known issues
120119
///
121-
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
122-
/// You should use `async` commands when creating windows.
120+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
121+
/// You should use `async` commands and separate threads when creating windows.
123122
///
124123
/// # Examples
125124
///
@@ -2043,6 +2042,52 @@ impl<R: Runtime> WebviewWindow<R> {
20432042
pub fn clear_all_browsing_data(&self) -> crate::Result<()> {
20442043
self.webview.clear_all_browsing_data()
20452044
}
2045+
2046+
/// Returns all cookies in the runtime's cookie store including HTTP-only and secure cookies.
2047+
///
2048+
/// Note that cookies will only be returned for URLs with an http or https scheme.
2049+
/// Cookies set through javascript for local files
2050+
/// (such as those served from the tauri://) protocol are not currently supported.
2051+
///
2052+
/// # Stability
2053+
///
2054+
/// The return value of this function leverages [`tauri_runtime::Cookie`] which re-exports the cookie crate.
2055+
/// This dependency might receive updates in minor Tauri releases.
2056+
///
2057+
/// # Known issues
2058+
///
2059+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
2060+
/// You should use `async` commands and separate threads when reading cookies.
2061+
///
2062+
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
2063+
pub fn cookies_for_url(&self, url: Url) -> crate::Result<Vec<Cookie<'static>>> {
2064+
self.webview.cookies_for_url(url)
2065+
}
2066+
2067+
/// Returns all cookies in the runtime's cookie store for all URLs including HTTP-only and secure cookies.
2068+
///
2069+
/// Note that cookies will only be returned for URLs with an http or https scheme.
2070+
/// Cookies set through javascript for local files
2071+
/// (such as those served from the tauri://) protocol are not currently supported.
2072+
///
2073+
/// # Stability
2074+
///
2075+
/// The return value of this function leverages [`tauri_runtime::Cookie`] which re-exports the cookie crate.
2076+
/// This dependency might receive updates in minor Tauri releases.
2077+
///
2078+
/// # Known issues
2079+
///
2080+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
2081+
/// You should use `async` commands and separate threads when reading cookies.
2082+
///
2083+
/// ## Platform-specific
2084+
///
2085+
/// - **Android**: Unsupported, always returns an empty [`Vec`].
2086+
///
2087+
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
2088+
pub fn cookies(&self) -> crate::Result<Vec<Cookie<'static>>> {
2089+
self.webview.cookies()
2090+
}
20462091
}
20472092

20482093
impl<R: Runtime> Listener<R> for WebviewWindow<R> {

crates/tauri/src/window/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ impl<'a, R: Runtime, M: Manager<R>> WindowBuilder<'a, R, M> {
140140
///
141141
/// # Known issues
142142
///
143-
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
144-
/// You should use `async` commands when creating windows.
143+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
144+
/// You should use `async` commands and separate threads when creating windows.
145145
///
146146
/// # Examples
147147
///
@@ -217,8 +217,8 @@ async fn create_window(app: tauri::AppHandle) {
217217
///
218218
/// # Known issues
219219
///
220-
/// On Windows, this function deadlocks when used in a synchronous command, see [the Webview2 issue].
221-
/// You should use `async` commands when creating windows.
220+
/// On Windows, this function deadlocks when used in a synchronous command or event handlers, see [the Webview2 issue].
221+
/// You should use `async` commands and separate threads when creating windows.
222222
///
223223
/// # Examples
224224
///

0 commit comments

Comments
 (0)