mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Implement origin concept.
This commit is contained in:
parent
e8e354d5d3
commit
a8233a135e
8 changed files with 215 additions and 9 deletions
|
@ -89,6 +89,7 @@ use style::properties::PropertyDeclarationBlock;
|
||||||
use style::restyle_hints::ElementSnapshot;
|
use style::restyle_hints::ElementSnapshot;
|
||||||
use style::selector_impl::PseudoElement;
|
use style::selector_impl::PseudoElement;
|
||||||
use style::values::specified::Length;
|
use style::values::specified::Length;
|
||||||
|
use url::Origin as UrlOrigin;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::str::{DOMString, LengthOrPercentageOrAuto};
|
use util::str::{DOMString, LengthOrPercentageOrAuto};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -276,7 +277,7 @@ impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, B, C) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
no_jsmanaged_fields!(bool, f32, f64, String, Url, AtomicBool, AtomicUsize, Uuid);
|
no_jsmanaged_fields!(bool, f32, f64, String, Url, AtomicBool, AtomicUsize, UrlOrigin, Uuid);
|
||||||
no_jsmanaged_fields!(usize, u8, u16, u32, u64);
|
no_jsmanaged_fields!(usize, u8, u16, u32, u64);
|
||||||
no_jsmanaged_fields!(isize, i8, i16, i32, i64);
|
no_jsmanaged_fields!(isize, i8, i16, i32, i64);
|
||||||
no_jsmanaged_fields!(Sender<T>);
|
no_jsmanaged_fields!(Sender<T>);
|
||||||
|
|
|
@ -94,6 +94,7 @@ use net_traits::CookieSource::NonHTTP;
|
||||||
use net_traits::response::HttpsState;
|
use net_traits::response::HttpsState;
|
||||||
use net_traits::{AsyncResponseTarget, PendingAsyncLoad};
|
use net_traits::{AsyncResponseTarget, PendingAsyncLoad};
|
||||||
use num::ToPrimitive;
|
use num::ToPrimitive;
|
||||||
|
use origin::Origin;
|
||||||
use script_runtime::ScriptChan;
|
use script_runtime::ScriptChan;
|
||||||
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable};
|
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable};
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
|
@ -223,6 +224,8 @@ pub struct Document {
|
||||||
/// https://html.spec.whatwg.org/multipage/#concept-document-https-state
|
/// https://html.spec.whatwg.org/multipage/#concept-document-https-state
|
||||||
https_state: Cell<HttpsState>,
|
https_state: Cell<HttpsState>,
|
||||||
touchpad_pressure_phase: Cell<TouchpadPressurePhase>,
|
touchpad_pressure_phase: Cell<TouchpadPressurePhase>,
|
||||||
|
/// The document's origin.
|
||||||
|
origin: Origin,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(JSTraceable, HeapSizeOf)]
|
#[derive(JSTraceable, HeapSizeOf)]
|
||||||
|
@ -1544,14 +1547,6 @@ impl Document {
|
||||||
|
|
||||||
/// https://html.spec.whatwg.org/multipage/#cookie-averse-document-object
|
/// https://html.spec.whatwg.org/multipage/#cookie-averse-document-object
|
||||||
fn is_cookie_averse(&self) -> bool {
|
fn is_cookie_averse(&self) -> bool {
|
||||||
/// https://url.spec.whatwg.org/#network-scheme
|
|
||||||
fn url_has_network_scheme(url: &Url) -> bool {
|
|
||||||
match &*url.scheme {
|
|
||||||
"ftp" | "http" | "https" => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.browsing_context.is_none() || !url_has_network_scheme(&self.url)
|
self.browsing_context.is_none() || !url_has_network_scheme(&self.url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1590,6 +1585,14 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://url.spec.whatwg.org/#network-scheme
|
||||||
|
fn url_has_network_scheme(url: &Url) -> bool {
|
||||||
|
match &*url.scheme {
|
||||||
|
"ftp" | "http" | "https" => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Document {
|
impl Document {
|
||||||
pub fn new_inherited(window: &Window,
|
pub fn new_inherited(window: &Window,
|
||||||
browsing_context: Option<&BrowsingContext>,
|
browsing_context: Option<&BrowsingContext>,
|
||||||
|
@ -1608,6 +1611,15 @@ impl Document {
|
||||||
(DocumentReadyState::Complete, true)
|
(DocumentReadyState::Complete, true)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Incomplete implementation of Document origin specification at
|
||||||
|
// https://html.spec.whatwg.org/multipage/#origin:document
|
||||||
|
let origin = if url_has_network_scheme(&url) {
|
||||||
|
Origin::new(&url)
|
||||||
|
} else {
|
||||||
|
// Default to DOM standard behaviour
|
||||||
|
Origin::opaque_identifier()
|
||||||
|
};
|
||||||
|
|
||||||
Document {
|
Document {
|
||||||
node: Node::new_document_node(),
|
node: Node::new_document_node(),
|
||||||
window: JS::from_ref(window),
|
window: JS::from_ref(window),
|
||||||
|
@ -1673,6 +1685,7 @@ impl Document {
|
||||||
css_errors_store: DOMRefCell::new(vec![]),
|
css_errors_store: DOMRefCell::new(vec![]),
|
||||||
https_state: Cell::new(HttpsState::None),
|
https_state: Cell::new(HttpsState::None),
|
||||||
touchpad_pressure_phase: Cell::new(TouchpadPressurePhase::BeforeClick),
|
touchpad_pressure_phase: Cell::new(TouchpadPressurePhase::BeforeClick),
|
||||||
|
origin: origin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ pub mod dom;
|
||||||
pub mod layout_interface;
|
pub mod layout_interface;
|
||||||
mod mem;
|
mod mem;
|
||||||
mod network_listener;
|
mod network_listener;
|
||||||
|
pub mod origin;
|
||||||
pub mod page;
|
pub mod page;
|
||||||
pub mod parse;
|
pub mod parse;
|
||||||
pub mod reporter;
|
pub mod reporter;
|
||||||
|
|
73
components/script/origin.rs
Normal file
73
components/script/origin.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* 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 std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use url::{OpaqueOrigin, Origin as UrlOrigin};
|
||||||
|
use url::{Url, Host};
|
||||||
|
|
||||||
|
/// A representation of an [origin](https://html.spec.whatwg.org/multipage/#origin-2).
|
||||||
|
#[derive(HeapSizeOf)]
|
||||||
|
pub struct Origin {
|
||||||
|
#[ignore_heap_size_of = "Rc<T> has unclear ownership semantics"]
|
||||||
|
inner: Rc<RefCell<UrlOrigin>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can't use RefCell inside JSTraceable, but Origin doesn't contain JS values and
|
||||||
|
// DOMRefCell makes it much harder to write unit tests (due to setting up required TLS).
|
||||||
|
no_jsmanaged_fields!(Origin);
|
||||||
|
|
||||||
|
impl Origin {
|
||||||
|
/// Create a new origin comprising a unique, opaque identifier.
|
||||||
|
pub fn opaque_identifier() -> Origin {
|
||||||
|
let opaque = UrlOrigin::UID(OpaqueOrigin::new());
|
||||||
|
Origin {
|
||||||
|
inner: Rc::new(RefCell::new(opaque)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new origin for the given URL.
|
||||||
|
pub fn new(url: &Url) -> Origin {
|
||||||
|
Origin {
|
||||||
|
inner: Rc::new(RefCell::new(url.origin())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&self, origin: UrlOrigin) {
|
||||||
|
*self.inner.borrow_mut() = origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Does this origin represent a host/scheme/port tuple?
|
||||||
|
pub fn is_scheme_host_port_tuple(&self) -> bool {
|
||||||
|
match *self.inner.borrow() {
|
||||||
|
UrlOrigin::Tuple(..) => true,
|
||||||
|
UrlOrigin::UID(..) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the host associated with this origin.
|
||||||
|
pub fn host(&self) -> Option<Host> {
|
||||||
|
match *self.inner.borrow() {
|
||||||
|
UrlOrigin::Tuple(_, ref host, _) => Some(host.clone()),
|
||||||
|
UrlOrigin::UID(..) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://html.spec.whatwg.org/multipage/#same-origin
|
||||||
|
pub fn same_origin(&self, other: &Origin) -> bool {
|
||||||
|
*self.inner.borrow() == *other.inner.borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy(&self) -> Origin {
|
||||||
|
Origin {
|
||||||
|
inner: Rc::new(RefCell::new(self.inner.borrow().clone())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alias(&self) -> Origin {
|
||||||
|
Origin {
|
||||||
|
inner: self.inner.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
components/servo/Cargo.lock
generated
2
components/servo/Cargo.lock
generated
|
@ -1752,7 +1752,9 @@ name = "script_tests"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
|
"plugins 0.0.1",
|
||||||
"script 0.0.1",
|
"script 0.0.1",
|
||||||
|
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"util 0.0.1",
|
"util 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,14 @@ doctest = false
|
||||||
[dependencies.msg]
|
[dependencies.msg]
|
||||||
path = "../../../components/msg"
|
path = "../../../components/msg"
|
||||||
|
|
||||||
|
[dependencies.plugins]
|
||||||
|
path = "../../../components/plugins"
|
||||||
|
|
||||||
[dependencies.script]
|
[dependencies.script]
|
||||||
path = "../../../components/script"
|
path = "../../../components/script"
|
||||||
|
|
||||||
[dependencies.util]
|
[dependencies.util]
|
||||||
path = "../../../components/util"
|
path = "../../../components/util"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
url = {version = "0.5.8", features = ["heap_size"]}
|
||||||
|
|
|
@ -2,10 +2,15 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#![feature(plugin)]
|
||||||
|
#![plugin(plugins)]
|
||||||
|
|
||||||
extern crate msg;
|
extern crate msg;
|
||||||
extern crate script;
|
extern crate script;
|
||||||
|
extern crate url;
|
||||||
extern crate util;
|
extern crate util;
|
||||||
|
|
||||||
|
#[cfg(test)] mod origin;
|
||||||
#[cfg(all(test, target_pointer_width = "64"))] mod size_of;
|
#[cfg(all(test, target_pointer_width = "64"))] mod size_of;
|
||||||
#[cfg(test)] mod textinput;
|
#[cfg(test)] mod textinput;
|
||||||
#[cfg(test)] mod dom {
|
#[cfg(test)] mod dom {
|
||||||
|
|
105
tests/unit/script/origin.rs
Normal file
105
tests/unit/script/origin.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* 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 script::origin::Origin;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn same_origin() {
|
||||||
|
let a = Origin::new(&url!("http://example.com/a.html"));
|
||||||
|
let b = Origin::new(&url!("http://example.com/b.html"));
|
||||||
|
assert!(a.same_origin(&b));
|
||||||
|
assert_eq!(a.is_scheme_host_port_tuple(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn identical_origin() {
|
||||||
|
let a = Origin::new(&url!("http://example.com/a.html"));
|
||||||
|
assert!(a.same_origin(&a));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cross_origin() {
|
||||||
|
let a = Origin::new(&url!("http://example.com/a.html"));
|
||||||
|
let b = Origin::new(&url!("http://example.org/b.html"));
|
||||||
|
assert!(!a.same_origin(&b));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alias_same_origin() {
|
||||||
|
let a = Origin::new(&url!("http://example.com/a.html"));
|
||||||
|
let b = Origin::new(&url!("http://example.com/b.html"));
|
||||||
|
let c = b.alias();
|
||||||
|
assert!(a.same_origin(&c));
|
||||||
|
assert!(b.same_origin(&b));
|
||||||
|
assert!(c.same_origin(&b));
|
||||||
|
assert_eq!(c.is_scheme_host_port_tuple(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alias_cross_origin() {
|
||||||
|
let a = Origin::new(&url!("http://example.com/a.html"));
|
||||||
|
let b = Origin::new(&url!("http://example.org/b.html"));
|
||||||
|
let c = b.alias();
|
||||||
|
assert!(!a.same_origin(&c));
|
||||||
|
assert!(b.same_origin(&c));
|
||||||
|
assert!(c.same_origin(&c));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alias_update_same_origin() {
|
||||||
|
let a = Origin::new(&url!("http://example.com/a.html"));
|
||||||
|
let b = Origin::new(&url!("http://example.org/b.html"));
|
||||||
|
let c = b.alias();
|
||||||
|
b.set(url!("http://example.com/c.html").origin());
|
||||||
|
assert!(a.same_origin(&c));
|
||||||
|
assert!(b.same_origin(&c));
|
||||||
|
assert!(c.same_origin(&c));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alias_update_cross_origin() {
|
||||||
|
let a = Origin::new(&url!("http://example.com/a.html"));
|
||||||
|
let b = Origin::new(&url!("http://example.com/b.html"));
|
||||||
|
let c = b.alias();
|
||||||
|
b.set(url!("http://example.org/c.html").origin());
|
||||||
|
assert!(!a.same_origin(&c));
|
||||||
|
assert!(b.same_origin(&c));
|
||||||
|
assert!(c.same_origin(&c));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn alias_chain() {
|
||||||
|
let a = Origin::new(&url!("http://example.com/a.html"));
|
||||||
|
let b = Origin::new(&url!("http://example.com/b.html"));
|
||||||
|
let c = b.copy();
|
||||||
|
let d = c.alias();
|
||||||
|
let e = d.alias();
|
||||||
|
assert!(a.same_origin(&e));
|
||||||
|
assert!(b.same_origin(&e));
|
||||||
|
assert!(c.same_origin(&e));
|
||||||
|
assert!(d.same_origin(&e));
|
||||||
|
assert!(e.same_origin(&e));
|
||||||
|
c.set(url!("http://example.org/c.html").origin());
|
||||||
|
assert!(a.same_origin(&b));
|
||||||
|
assert!(!b.same_origin(&c));
|
||||||
|
assert!(c.same_origin(&d));
|
||||||
|
assert!(d.same_origin(&e));
|
||||||
|
assert!(!e.same_origin(&a));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn opaque() {
|
||||||
|
let a = Origin::opaque_identifier();
|
||||||
|
let b = Origin::opaque_identifier();
|
||||||
|
assert!(!a.same_origin(&b));
|
||||||
|
assert_eq!(a.is_scheme_host_port_tuple(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn opaque_clone() {
|
||||||
|
let a = Origin::opaque_identifier();
|
||||||
|
let b = a.alias();
|
||||||
|
assert!(a.same_origin(&b));
|
||||||
|
assert_eq!(a.is_scheme_host_port_tuple(), false);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue