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

Add webdriver commands for (Get|Add)Cookie #10826

Merged
merged 1 commit into from Jun 26, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -24,3 +24,4 @@ serde_macros = "0.7"
url = {version = "1.0.0", features = ["heap_size", "serde"]}
util = {path = "../util", features = ["servo"]}
webrender_traits = {git = "https://github.com/servo/webrender_traits"}
cookie = { version = "0.2.5", features = ["serialize-serde", "serialize-rustc" ] }
@@ -10,6 +10,7 @@
#[allow(unused_extern_crates)]
#[macro_use]
extern crate bitflags;
extern crate cookie as cookie_rs;
extern crate euclid;
extern crate heapsize;
extern crate hyper;
@@ -3,19 +3,23 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use constellation_msg::PipelineId;
use cookie_rs::Cookie;
use euclid::rect::Rect;
use ipc_channel::ipc::IpcSender;
use rustc_serialize::json::{Json, ToJson};
use url::Url;

#[derive(Deserialize, Serialize)]
pub enum WebDriverScriptCommand {
AddCookie(Cookie, IpcSender<Result<(), WebDriverCookieError>>),
ExecuteScript(String, IpcSender<WebDriverJSResult>),
ExecuteAsyncScript(String, IpcSender<WebDriverJSResult>),
FindElementCSS(String, IpcSender<Result<Option<String>, ()>>),
FindElementsCSS(String, IpcSender<Result<Vec<String>, ()>>),
FocusElement(String, IpcSender<Result<(), ()>>),
GetActiveElement(IpcSender<Option<String>>),
GetCookie(String, IpcSender<Vec<Cookie>>),
GetCookies(IpcSender<Vec<Cookie>>),
GetElementAttribute(String, String, IpcSender<Result<Option<String>, ()>>),
GetElementCSS(String, String, IpcSender<Result<String, ()>>),
GetElementRect(String, IpcSender<Result<Rect<f64>, ()>>),
@@ -28,6 +32,12 @@ pub enum WebDriverScriptCommand {
GetTitle(IpcSender<String>)
}

#[derive(Deserialize, Serialize)]
pub enum WebDriverCookieError {
InvalidDomain,
UnableToSetCookie
}

#[derive(Deserialize, Serialize)]
pub enum WebDriverJSValue {
Undefined,
@@ -12,7 +12,7 @@ path = "lib.rs"
bitflags = "0.7"
brotli = {git = "https://github.com/ende76/brotli-rs"}
content-blocker = "0.2"
cookie = {version = "0.2.4", features = ["serialize-rustc"]}
cookie = { version = "0.2.5", features = ["serialize-serde", "serialize-rustc" ] }
device = {git = "https://github.com/servo/devices"}
devtools_traits = {path = "../devtools_traits"}
flate2 = "0.2.0"
@@ -6,6 +6,7 @@
//! http://tools.ietf.org/html/rfc6265

use cookie::Cookie;
use cookie_rs;
use net_traits::CookieSource;
use std::cmp::Ordering;
use url::Url;
@@ -114,4 +115,12 @@ impl CookieStorage {
_ => Some(result)
}
}

pub fn cookies_data_for_url<'a>(&'a mut self, url: &'a Url,
source: CookieSource) -> Box<Iterator<Item=cookie_rs::Cookie> + 'a> {
Box::new(self.cookies.iter_mut().filter(move |c| { c.appropriate_for_url(url, source) }).map(|c| {
c.touch();
c.cookie.clone()
}))
}
}
@@ -8,6 +8,7 @@ use chrome_loader;
use connector::{Connector, create_http_connector};
use content_blocker::BLOCKED_CONTENT_RULES;
use cookie;
use cookie_rs;
use cookie_storage::CookieStorage;
use data_loader;
use devtools_traits::DevtoolsControlMsg;
@@ -277,10 +278,17 @@ impl ResourceChannelManager {
self.resource_manager.websocket_connect(connect, connect_data, group),
CoreResourceMsg::SetCookiesForUrl(request, cookie_list, source) =>
self.resource_manager.set_cookies_for_url(request, cookie_list, source, group),
CoreResourceMsg::SetCookiesForUrlWithData(request, cookie, source) =>
self.resource_manager.set_cookies_for_url_with_data(request, cookie, source, group),
CoreResourceMsg::GetCookiesForUrl(url, consumer, source) => {
let mut cookie_jar = group.cookie_jar.write().unwrap();
consumer.send(cookie_jar.cookies_for_url(&url, source)).unwrap();
}
CoreResourceMsg::GetCookiesDataForUrl(url, consumer, source) => {
let mut cookie_jar = group.cookie_jar.write().unwrap();
let cookies = cookie_jar.cookies_data_for_url(&url, source).collect();
consumer.send(cookies).unwrap();
}
CoreResourceMsg::Cancel(res_id) => {
if let Some(cancel_sender) = self.resource_manager.cancel_load_map.get(&res_id) {
let _ = cancel_sender.send(());
@@ -488,6 +496,14 @@ impl CoreResourceManager {
}
}

fn set_cookies_for_url_with_data(&mut self, request: Url, cookie: cookie_rs::Cookie, source: CookieSource,
resource_group: &ResourceGroup) {
if let Some(cookie) = cookie::Cookie::new_wrapped(cookie, &request, source) {
let mut cookie_jar = resource_group.cookie_jar.write().unwrap();
cookie_jar.push(cookie, source)
}
}

fn load(&mut self,
load_data: LoadData,
consumer: LoadConsumer,
@@ -23,3 +23,4 @@ serde_macros = "0.7"
url = {version = "1.0.0", features = ["heap_size"]}
websocket = "0.17"
uuid = { version = "0.2.2", features = ["v4", "serde"] }
cookie = { version = "0.2.5", features = ["serialize-serde", "serialize-rustc" ] }
@@ -12,6 +12,7 @@

#![deny(unsafe_code)]

extern crate cookie as cookie_rs;
extern crate heapsize;
extern crate hyper;
extern crate image as piston_image;
@@ -28,6 +29,7 @@ extern crate util;
extern crate uuid;
extern crate websocket;

use cookie_rs::Cookie;
use filemanager_thread::FileManagerThreadMsg;
use heapsize::HeapSizeOf;
use hyper::header::{ContentType, Headers};
@@ -423,8 +425,12 @@ pub enum CoreResourceMsg {
WebsocketConnect(WebSocketCommunicate, WebSocketConnectData),
/// Store a set of cookies for a given originating URL
SetCookiesForUrl(Url, String, CookieSource),
/// Store a set of cookies for a given originating URL
SetCookiesForUrlWithData(Url, Cookie, CookieSource),
/// Retrieve the stored cookies for a given URL
GetCookiesForUrl(Url, IpcSender<Option<String>>, CookieSource),
/// Get a cookie by name for a given originating URL
GetCookiesDataForUrl(Url, IpcSender<Vec<Cookie>>, CookieSource),
/// Cancel a network request corresponding to a given `ResourceId`
Cancel(ResourceId),
/// Synchronization message solely for knowing the state of the ResourceChannelManager loop
@@ -22,6 +22,7 @@ app_units = {version = "0.2.3", features = ["plugins"]}
bitflags = "0.7"
canvas_traits = {path = "../canvas_traits"}
caseless = "0.1.0"
cookie = { version = "0.2.5", features = ["serialize-serde", "serialize-rustc" ] }
cssparser = {version = "0.5.4", features = ["heap_size", "serde-serialization"]}
devtools_traits = {path = "../devtools_traits"}
encoding = "0.2"
@@ -1562,7 +1562,7 @@ impl Document {
}

/// https://html.spec.whatwg.org/multipage/#cookie-averse-document-object
fn is_cookie_averse(&self) -> bool {
pub fn is_cookie_averse(&self) -> bool {
self.browsing_context.is_none() || !url_has_network_scheme(&self.url)
}

@@ -36,6 +36,7 @@ extern crate app_units;
extern crate bitflags;
extern crate canvas_traits;
extern crate caseless;
extern crate cookie as cookie_rs;
extern crate core;
#[macro_use]
extern crate cssparser;
@@ -1059,6 +1059,8 @@ impl ScriptThread {
fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) {
let context = self.root_browsing_context();
match msg {
WebDriverScriptCommand::AddCookie(params, reply) =>
webdriver_handlers::handle_add_cookie(&context, pipeline_id, params, reply),
WebDriverScriptCommand::ExecuteScript(script, reply) =>
webdriver_handlers::handle_execute_script(&context, pipeline_id, script, reply),
WebDriverScriptCommand::FindElementCSS(selector, reply) =>
@@ -1069,6 +1071,10 @@ impl ScriptThread {
webdriver_handlers::handle_focus_element(&context, pipeline_id, element_id, reply),
WebDriverScriptCommand::GetActiveElement(reply) =>
webdriver_handlers::handle_get_active_element(&context, pipeline_id, reply),
WebDriverScriptCommand::GetCookies(reply) =>
webdriver_handlers::handle_get_cookies(&context, pipeline_id, reply),
WebDriverScriptCommand::GetCookie(name, reply) =>
webdriver_handlers::handle_get_cookie(&context, pipeline_id, name, reply),
WebDriverScriptCommand::GetElementTagName(node_id, reply) =>
webdriver_handlers::handle_get_name(&context, pipeline_id, node_id, reply),
WebDriverScriptCommand::GetElementAttribute(node_id, name, reply) =>
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use cookie_rs::Cookie;
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods;
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
@@ -26,12 +27,16 @@ use dom::window::ScriptHelpers;
use euclid::point::Point2D;
use euclid::rect::Rect;
use euclid::size::Size2D;
use ipc_channel::ipc::IpcSender;
use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::JSContext;
use js::jsapi::{HandleValue, RootedValue};
use js::jsval::UndefinedValue;
use msg::constellation_msg::PipelineId;
use msg::webdriver_msg::WebDriverCookieError;
use msg::webdriver_msg::{WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverJSValue};
use net_traits::CookieSource::{HTTP, NonHTTP};
use net_traits::CoreResourceMsg::{GetCookiesDataForUrl, SetCookiesForUrlWithData};
use net_traits::IpcSend;
use script_thread::get_browsing_context;
use url::Url;

@@ -177,6 +182,66 @@ pub fn handle_get_active_element(context: &BrowsingContext,
|elem| elem.upcast::<Node>().unique_id())).unwrap();
}

pub fn handle_get_cookies(context: &BrowsingContext,
_pipeline: PipelineId,
reply: IpcSender<Vec<Cookie>>) {
let document = context.active_document();
let url = document.url();
let (sender, receiver) = ipc::channel().unwrap();
let _ = document.window().resource_threads().send(
GetCookiesDataForUrl(url.clone(), sender, NonHTTP)
);
let cookies = receiver.recv().unwrap();
reply.send(cookies).unwrap();
}

// https://w3c.github.io/webdriver/webdriver-spec.html#get-cookie
pub fn handle_get_cookie(context: &BrowsingContext,
_pipeline: PipelineId,
name: String,
reply: IpcSender<Vec<Cookie>>) {
let document = context.active_document();
let url = document.url();
let (sender, receiver) = ipc::channel().unwrap();
let _ = document.window().resource_threads().send(
GetCookiesDataForUrl(url.clone(), sender, NonHTTP)
);
let cookies = receiver.recv().unwrap();
reply.send(cookies.into_iter().filter(|c| c.name == &*name).collect()).unwrap();
}

// https://w3c.github.io/webdriver/webdriver-spec.html#add-cookie
pub fn handle_add_cookie(context: &BrowsingContext,
_pipeline: PipelineId,
cookie: Cookie,
reply: IpcSender<Result<(), WebDriverCookieError>>) {
let document = context.active_document();
let url = document.url();
let method = if cookie.httponly {
HTTP
} else {
NonHTTP
};
reply.send(match (document.is_cookie_averse(), cookie.domain.clone()) {
(true, _) => Err(WebDriverCookieError::InvalidDomain),
(false, Some(ref domain)) if url.host_str().map(|x| { x == &**domain }).unwrap_or(false) => {
let _ = document.window().resource_threads().send(
SetCookiesForUrlWithData(url.clone(), cookie, method)
);
Ok(())
},
(false, None) => {
let _ = document.window().resource_threads().send(
SetCookiesForUrlWithData(url.clone(), cookie, method)
);
Ok(())
},
(_, _) => {
Err(WebDriverCookieError::UnableToSetCookie)
},
}).unwrap();
}

pub fn handle_get_title(context: &BrowsingContext, _pipeline: PipelineId, reply: IpcSender<String>) {
reply.send(String::from(context.active_document().Title())).unwrap();
}

Some generated files are not rendered by default. Learn more.

@@ -23,3 +23,4 @@ script_traits = {path = "../script_traits"}
url = {version = "1.0.0", features = ["heap_size"]}
uuid = { version = "0.2", features = ["v4"] }
webdriver = "0.9"
cookie = { version = "0.2.5", features = ["serialize-serde", "serialize-rustc" ] }
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.