From 126f4b7e3708459c098ad3ffdc66b15ccc0f884f Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 17 May 2015 16:04:14 -0400 Subject: [PATCH 1/5] Implemented the origin method (fixes #54) --- src/lib.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index f947214b0..65d75b42b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -180,6 +180,16 @@ pub struct Url { pub fragment: Option, } +/// The origin of the URL +#[derive(PartialEq, Eq, Clone, Debug)] +pub enum Origin { + /// A globally unique identifier + UID(usize), + + /// Consists of the URL's scheme, host and port + Tuple(String, Host, u16) +} + /// The components of the URL whose representation depends on where the scheme is *relative*. #[derive(PartialEq, Eq, Clone, Debug)] pub enum SchemeData { @@ -557,6 +567,27 @@ impl Url { self.to_string() } + // Return the origin of this URL (https://url.spec.whatwg.org/#origin) + pub fn origin(&self) -> Origin { + match self.scheme { + "blob" => { + let result = self.parse(self.scheme_data); + match result { + Ok(url) => url.origin(), + // FIXME: Generate a globally unique identifier + Err(_) => Origin::UID(0) + } + }, + "ftp" | "gopher" | "http" | "https" | "ws" | "wss" => { + Origin::Tuple(self.scheme, self.host, self.port) + }, + // TODO: Figure out what to do if the scheme is a file + "file" => Origin::UID(0), + // FIXME: Generate a globally unique identifier + _ => Origin::UID(0) + } + } + /// Return the serialization of this URL, without the fragment identifier, as a string pub fn serialize_no_fragment(&self) -> String { UrlNoFragmentFormatter{ url: self }.to_string() From f056ebf98ed4b2c33266f87241496dcb145b998c Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 17 May 2015 16:47:36 -0400 Subject: [PATCH 2/5] Fixed compiler errors --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 65d75b42b..7ede18e1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -569,17 +569,17 @@ impl Url { // Return the origin of this URL (https://url.spec.whatwg.org/#origin) pub fn origin(&self) -> Origin { - match self.scheme { + match &*self.scheme { "blob" => { - let result = self.parse(self.scheme_data); + let result = Url::parse(self.non_relative_scheme_data().unwrap()); match result { - Ok(url) => url.origin(), + Ok(ref url) => url.origin(), // FIXME: Generate a globally unique identifier Err(_) => Origin::UID(0) } }, "ftp" | "gopher" | "http" | "https" | "ws" | "wss" => { - Origin::Tuple(self.scheme, self.host, self.port) + Origin::Tuple(self.scheme.clone(), self.host().unwrap().clone(), self.port().unwrap()) }, // TODO: Figure out what to do if the scheme is a file "file" => Origin::UID(0), From b63effc66a8b2da854dbf87fb9286cdb9001a93f Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 17 May 2015 22:38:26 -0400 Subject: [PATCH 3/5] Added the generation of UUIDs using uuid crate --- Cargo.toml | 1 + src/lib.rs | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 54d163e0b..695718e5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,5 +21,6 @@ version = "0.2" optional = true [dependencies] +uuid = "0.1.17" rustc-serialize = "0.3" matches = "0.1" diff --git a/src/lib.rs b/src/lib.rs index 7ede18e1e..b04185b4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -119,6 +119,7 @@ assert!(css_url.serialize() == "http://servo.github.io/rust-url/main.css".to_str */ extern crate rustc_serialize; +extern crate uuid; #[macro_use] extern crate matches; @@ -136,6 +137,8 @@ use percent_encoding::{percent_encode, lossy_utf8_percent_decode, DEFAULT_ENCODE use format::{PathFormatter, UserInfoFormatter, UrlNoFragmentFormatter}; use encoding::EncodingOverride; +use uuid::Uuid; + mod encoding; mod host; mod parser; @@ -184,7 +187,7 @@ pub struct Url { #[derive(PartialEq, Eq, Clone, Debug)] pub enum Origin { /// A globally unique identifier - UID(usize), + UID(String), /// Consists of the URL's scheme, host and port Tuple(String, Host, u16) @@ -574,17 +577,15 @@ impl Url { let result = Url::parse(self.non_relative_scheme_data().unwrap()); match result { Ok(ref url) => url.origin(), - // FIXME: Generate a globally unique identifier - Err(_) => Origin::UID(0) + Err(_) => Origin::UID(Uuid::new_v4().to_string()) } }, "ftp" | "gopher" | "http" | "https" | "ws" | "wss" => { Origin::Tuple(self.scheme.clone(), self.host().unwrap().clone(), self.port().unwrap()) }, // TODO: Figure out what to do if the scheme is a file - "file" => Origin::UID(0), - // FIXME: Generate a globally unique identifier - _ => Origin::UID(0) + "file" => Origin::UID(Uuid::new_v4().to_string()), + _ => Origin::UID(Uuid::new_v4().to_string()) } } From aec7d49de81222cab8205e2e83f7e25a8147548b Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 17 May 2015 23:57:48 -0400 Subject: [PATCH 4/5] Now using port_or_default to get the port of a URL for the origin method --- src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index b04185b4d..cc57425af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -581,7 +581,8 @@ impl Url { } }, "ftp" | "gopher" | "http" | "https" | "ws" | "wss" => { - Origin::Tuple(self.scheme.clone(), self.host().unwrap().clone(), self.port().unwrap()) + Origin::Tuple(self.scheme.clone(), self.host().unwrap().clone(), + self.port_or_default().unwrap()) }, // TODO: Figure out what to do if the scheme is a file "file" => Origin::UID(Uuid::new_v4().to_string()), From 08ea09ce04330f49906bb89d8fa2900666972046 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Fri, 22 May 2015 18:17:25 -0400 Subject: [PATCH 5/5] Using opaque identifiers --- src/lib.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cc57425af..efaef1488 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -183,11 +183,15 @@ pub struct Url { pub fragment: Option, } +/// Opaque identifier for URLs that have file or other schemes +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct OpaqueOrigin(Uuid); + /// The origin of the URL #[derive(PartialEq, Eq, Clone, Debug)] pub enum Origin { /// A globally unique identifier - UID(String), + UID(OpaqueOrigin), /// Consists of the URL's scheme, host and port Tuple(String, Host, u16) @@ -577,7 +581,7 @@ impl Url { let result = Url::parse(self.non_relative_scheme_data().unwrap()); match result { Ok(ref url) => url.origin(), - Err(_) => Origin::UID(Uuid::new_v4().to_string()) + Err(_) => Origin::UID(OpaqueOrigin(Uuid::new_v4())) } }, "ftp" | "gopher" | "http" | "https" | "ws" | "wss" => { @@ -585,8 +589,8 @@ impl Url { self.port_or_default().unwrap()) }, // TODO: Figure out what to do if the scheme is a file - "file" => Origin::UID(Uuid::new_v4().to_string()), - _ => Origin::UID(Uuid::new_v4().to_string()) + "file" => Origin::UID(OpaqueOrigin(Uuid::new_v4())), + _ => Origin::UID(OpaqueOrigin(Uuid::new_v4())) } }