aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-02-04 11:57:54 -0700
committerbors-servo <metajack+bors@gmail.com>2015-02-04 11:57:54 -0700
commit7e3f504d94ffb77ec6148166d2ab73978e1c71c8 (patch)
treec3d04d3b52e8f83197819565c867b52df167b2a5 /components/script/dom
parent58a3cdcbef30e04199d33dc83cea0ace3e2cfcf1 (diff)
parent0557f8592cb965658be471d8807a2404483c0806 (diff)
downloadservo-7e3f504d94ffb77ec6148166d2ab73978e1c71c8.tar.gz
servo-7e3f504d94ffb77ec6148166d2ab73978e1c71c8.zip
auto merge of #4519 : jdm/servo/cookies, r=Ms2ger
As specified in http://tools.ietf.org/html/rfc6265. Requires https://github.com/servo/cookie-rs/pull/1. Tested against http://www.joshmatthews.net/cookie.php, http://www.html-kit.com/tools/cookietester/, https://github.com/login, and https://mobile.twitter.com/session/new .
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/document.rs43
-rw-r--r--components/script/dom/element.rs4
-rw-r--r--components/script/dom/htmlformelement.rs13
-rw-r--r--components/script/dom/node.rs2
-rw-r--r--components/script/dom/webidls/Document.webidl2
-rw-r--r--components/script/dom/xmlhttprequest.rs62
6 files changed, 83 insertions, 43 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index b6a5659a88a..3734527bc09 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -19,7 +19,7 @@ use dom::bindings::codegen::InheritTypes::{HTMLAreaElementDerived, HTMLEmbedElem
use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, HTMLImageElementDerived};
use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived};
use dom::bindings::error::{ErrorResult, Fallible};
-use dom::bindings::error::Error::{NotSupported, InvalidCharacter};
+use dom::bindings::error::Error::{NotSupported, InvalidCharacter, Security};
use dom::bindings::error::Error::{HierarchyRequest, NamespaceError};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable};
@@ -54,6 +54,8 @@ use dom::range::Range;
use dom::treewalker::TreeWalker;
use dom::uievent::UIEvent;
use dom::window::{Window, WindowHelpers};
+use net::resource_task::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl};
+use net::cookie_storage::CookieSource::NonHTTP;
use util::namespace;
use util::str::{DOMString, split_html_space_chars};
@@ -68,6 +70,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::ascii::AsciiExt;
use std::cell::{Cell, Ref};
use std::default::Default;
+use std::sync::mpsc::channel;
use time;
#[derive(PartialEq)]
@@ -170,7 +173,7 @@ pub trait DocumentHelpers<'a> {
fn window(self) -> Temporary<Window>;
fn encoding_name(self) -> Ref<'a, DOMString>;
fn is_html_document(self) -> bool;
- fn url(self) -> &'a Url;
+ fn url(self) -> Url;
fn quirks_mode(self) -> QuirksMode;
fn set_quirks_mode(self, mode: QuirksMode);
fn set_last_modified(self, value: DOMString);
@@ -206,8 +209,9 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
self.is_html_document
}
- fn url(self) -> &'a Url {
- &self.extended_deref().url
+ // http://dom.spec.whatwg.org/#dom-document-url
+ fn url(self) -> Url {
+ self.url.clone()
}
fn quirks_mode(self) -> QuirksMode {
@@ -1003,7 +1007,38 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
Temporary::new(self.window)
}
+ // https://html.spec.whatwg.org/multipage/dom.html#dom-document-cookie
+ fn GetCookie(self) -> Fallible<DOMString> {
+ //TODO: return empty string for cookie-averse Document
+ let url = self.url();
+ if !is_scheme_host_port_tuple(&url) {
+ return Err(Security);
+ }
+ let window = self.window.root();
+ let page = window.page();
+ let (tx, rx) = channel();
+ let _ = page.resource_task.send(GetCookiesForUrl(url, tx, NonHTTP));
+ let cookies = rx.recv().unwrap();
+ Ok(cookies.unwrap_or("".to_owned()))
+ }
+
+ // https://html.spec.whatwg.org/multipage/dom.html#dom-document-cookie
+ fn SetCookie(self, cookie: DOMString) -> ErrorResult {
+ //TODO: ignore for cookie-averse Document
+ let url = self.url();
+ if !is_scheme_host_port_tuple(&url) {
+ return Err(Security);
+ }
+ let window = self.window.root();
+ let page = window.page();
+ let _ = page.resource_task.send(SetCookiesForUrl(url, cookie, NonHTTP));
+ Ok(())
+ }
+
global_event_handlers!();
event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange);
}
+fn is_scheme_host_port_tuple(url: &Url) -> bool {
+ url.host().is_some() && url.port_or_default().is_some()
+}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index b1b458bad40..69eb3f2ee23 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -777,7 +777,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
let base = doc.r().url();
// https://html.spec.whatwg.org/multipage/infrastructure.html#reflect
// XXXManishearth this doesn't handle `javascript:` urls properly
- match UrlParser::new().base_url(base).parse(url.as_slice()) {
+ match UrlParser::new().base_url(&base).parse(url.as_slice()) {
Ok(parsed) => parsed.serialize(),
Err(_) => "".to_owned()
}
@@ -1174,7 +1174,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
// Modifying the `style` attribute might change style.
let node: JSRef<Node> = NodeCast::from_ref(*self);
let doc = document_from_node(*self).root();
- let base_url = doc.r().url().clone();
+ let base_url = doc.r().url();
let value = attr.value();
let style = Some(parse_style_attribute(value.as_slice(), &base_url));
*self.style_attribute.borrow_mut() = style;
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 5f0ec3f212a..74f789ab491 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -23,6 +23,8 @@ use dom::htmlbuttonelement::{HTMLButtonElement};
use dom::htmltextareaelement::{HTMLTextAreaElement, HTMLTextAreaElementHelpers};
use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node};
use hyper::method::Method;
+use hyper::header::common::ContentType;
+use hyper::mime;
use servo_msg::constellation_msg::LoadData;
use util::str::DOMString;
use script_task::{ScriptChan, ScriptMsg};
@@ -178,7 +180,7 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
}
// TODO: Resolve the url relative to the submitter element
// Step 10-15
- let action_components = UrlParser::new().base_url(base).parse(action.as_slice()).unwrap_or(base.clone());
+ let action_components = UrlParser::new().base_url(&base).parse(action.as_slice()).unwrap_or(base);
let _action = action_components.serialize();
let scheme = action_components.scheme.clone();
let enctype = submitter.enctype();
@@ -186,12 +188,17 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
let _target = submitter.target();
// TODO: Handle browsing contexts, partially loaded documents (step 16-17)
+ let mut load_data = LoadData::new(action_components);
+
let parsed_data = match enctype {
- FormEncType::UrlEncoded => serialize(form_data.iter().map(|d| (d.name.as_slice(), d.value.as_slice()))),
+ FormEncType::UrlEncoded => {
+ let mime: mime::Mime = "application/x-www-form-urlencoded".parse().unwrap();
+ load_data.headers.set(ContentType(mime));
+ serialize(form_data.iter().map(|d| (d.name.as_slice(), d.value.as_slice())))
+ }
_ => "".to_owned() // TODO: Add serializers for the other encoding types
};
- let mut load_data = LoadData::new(action_components);
// Step 18
match (scheme.as_slice(), method) {
(_, FormMethod::FormDialog) => return, // Unimplemented
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 745c5a3a135..cdd52e78855 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -1574,7 +1574,7 @@ impl Node {
false => IsHTMLDocument::NonHTMLDocument,
};
let window = document.window().root();
- let document = Document::new(window.r(), Some(document.url().clone()),
+ let document = Document::new(window.r(), Some(document.url()),
is_html_doc, None,
DocumentSource::NotFromParser);
NodeCast::from_temporary(document)
diff --git a/components/script/dom/webidls/Document.webidl b/components/script/dom/webidls/Document.webidl
index 92b7f35c34b..26d2fa03163 100644
--- a/components/script/dom/webidls/Document.webidl
+++ b/components/script/dom/webidls/Document.webidl
@@ -65,6 +65,8 @@ partial interface Document {
readonly attribute DocumentReadyState readyState;
readonly attribute DOMString lastModified;
readonly attribute Location location;
+ [Throws]
+ attribute DOMString cookie;
// DOM tree accessors
[SetterThrows]
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index a32045cff75..f9f75fbbf7e 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -561,41 +561,35 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
let mut load_data = LoadData::new(self.request_url.borrow().clone().unwrap(), start_chan);
load_data.data = extracted;
- // Default headers
- {
- #[inline]
- fn join_raw(a: &str, b: &str) -> Vec<u8> {
- let len = a.len() + b.len();
- let mut vec = Vec::with_capacity(len);
- vec.push_all(a.as_bytes());
- vec.push_all(b.as_bytes());
- vec
- }
- let ref mut request_headers = self.request_headers.borrow_mut();
- if !request_headers.has::<ContentType>() {
- // XHR spec differs from http, and says UTF-8 should be in capitals,
- // instead of "utf-8", which is what Hyper defaults to.
- let params = ";charset=UTF-8";
- let n = "content-type";
- match data {
- Some(eString(_)) =>
- request_headers.set_raw(n.to_owned(), vec![join_raw("text/plain", params)]),
- Some(eURLSearchParams(_)) =>
- request_headers.set_raw(
- n.to_owned(), vec![join_raw("application/x-www-form-urlencoded", params)]),
- None => ()
- }
- }
+ #[inline]
+ fn join_raw(a: &str, b: &str) -> Vec<u8> {
+ let len = a.len() + b.len();
+ let mut vec = Vec::with_capacity(len);
+ vec.push_all(a.as_bytes());
+ vec.push_all(b.as_bytes());
+ vec
+ }
+ // XHR spec differs from http, and says UTF-8 should be in capitals,
+ // instead of "utf-8", which is what Hyper defaults to.
+ let params = ";charset=UTF-8";
+ let n = "content-type";
+ match data {
+ Some(eString(_)) =>
+ load_data.headers.set_raw(n.to_owned(), vec![join_raw("text/plain", params)]),
+ Some(eURLSearchParams(_)) =>
+ load_data.headers.set_raw(
+ n.to_owned(), vec![join_raw("application/x-www-form-urlencoded", params)]),
+ None => ()
+ }
- if !request_headers.has::<Accept>() {
- let mime = Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![]);
- request_headers.set(
- Accept(vec![QualityItem::new(mime, 1.0)]));
- }
- } // drops the borrow_mut
+ load_data.preserved_headers = (*self.request_headers.borrow()).clone();
+
+ if !load_data.preserved_headers.has::<Accept>() {
+ let mime = Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![]);
+ load_data.preserved_headers.set(Accept(vec![QualityItem::new(mime, 1.0)]));
+ }
- load_data.headers = (*self.request_headers.borrow()).clone();
load_data.method = (*self.request_method.borrow()).clone();
let (terminate_sender, terminate_receiver) = channel();
*self.terminate_sender.borrow_mut() = Some(terminate_sender);
@@ -607,8 +601,10 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
} else {
RequestMode::CORS
};
+ let mut combined_headers = load_data.headers.clone();
+ combined_headers.extend(load_data.preserved_headers.iter());
let cors_request = CORSRequest::maybe_new(referer_url.clone(), load_data.url.clone(), mode,
- load_data.method.clone(), load_data.headers.clone());
+ load_data.method.clone(), combined_headers);
match cors_request {
Ok(None) => {
let mut buf = String::new();