diff --git a/Cargo.toml b/Cargo.toml index 1841539..6678270 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,6 +78,10 @@ required-features = ["tokio-runtime"] name = "iframe-workaround" required-features = ["tokio-runtime", "tokio"] +[[example]] +name = "storage-cookie" +required-features = ["tokio-runtime"] + [[example]] name = "httpfuture" diff --git a/examples/storage-cookie.rs b/examples/storage-cookie.rs new file mode 100644 index 0000000..fe2fbb7 --- /dev/null +++ b/examples/storage-cookie.rs @@ -0,0 +1,48 @@ +use futures::StreamExt; + +use chromiumoxide::browser::Browser; +use chromiumoxide::browser::BrowserConfig; +use chromiumoxide::cdp::browser_protocol::network::CookieParam; + +#[tokio::main] +async fn main() -> Result<(), Box> { + tracing_subscriber::fmt::init(); + + let (mut browser, mut handler) = + Browser::launch(BrowserConfig::builder().with_head().build()?).await?; + let _ = tokio::spawn(async move { while let Some(_) = handler.next().await {} }); + + let _ = browser.new_page("https://setcookie.net/").await?; + let example_cookie = CookieParam::builder() + .domain(".setcookie.net") + .name("set_from_chromiumoxide") + .value("Test Value") + .path("/") + .build()?; + + println!("\x1b[32mType 'c' to clear all cookies, 's' to set a cookie, 'q' to quit the browser\x1b[0m"); + loop { + // Read Cookies + println!("All Browser cookies: {:?}", browser.get_cookies().await?); + + let mut input = String::new(); + std::io::stdin().read_line(&mut input)?; + + if input.trim() == "c" { + // Clear Cookies + browser.clear_cookies().await?; + } + if input.trim() == "s" { + // Set Cookies + browser.set_cookies(vec![example_cookie.clone()]).await?; + } + if input.trim() == "q" { + break; + } + } + + browser.close().await?; + browser.wait().await?; + + Ok(()) +} diff --git a/src/browser.rs b/src/browser.rs index ae229a2..0c2e486 100644 --- a/src/browser.rs +++ b/src/browser.rs @@ -11,6 +11,10 @@ use futures::channel::oneshot::channel as oneshot_channel; use futures::select; use futures::SinkExt; +use chromiumoxide_cdp::cdp::browser_protocol::network::{Cookie, CookieParam}; +use chromiumoxide_cdp::cdp::browser_protocol::storage::{ + ClearCookiesParams, GetCookiesParams, SetCookiesParams, +}; use chromiumoxide_cdp::cdp::browser_protocol::target::{ CreateBrowserContextParams, CreateTargetParams, DisposeBrowserContextParams, TargetId, TargetInfo, @@ -480,6 +484,33 @@ impl Browser { Ok(()) } + + /// Clears cookies. + pub async fn clear_cookies(&self) -> Result<()> { + self.execute(ClearCookiesParams::default()).await?; + Ok(()) + } + + /// Returns all browser cookies. + pub async fn get_cookies(&self) -> Result> { + Ok(self + .execute(GetCookiesParams::default()) + .await? + .result + .cookies) + } + + /// Sets given cookies. + pub async fn set_cookies(&self, mut cookies: Vec) -> Result<&Self> { + for cookie in &mut cookies { + if let Some(url) = cookie.url.as_ref() { + crate::page::validate_cookie_url(url)?; + } + } + + self.execute(SetCookiesParams::new(cookies)).await?; + Ok(self) + } } impl Drop for Browser { diff --git a/src/page.rs b/src/page.rs index 51f2ea7..f8cf8ca 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1240,7 +1240,7 @@ impl From> for Page { } } -fn validate_cookie_url(url: &str) -> Result<()> { +pub(crate) fn validate_cookie_url(url: &str) -> Result<()> { if url.starts_with("data:") { Err(CdpError::msg("Data URL page can not have cookie")) } else if url == "about:blank" {