Browse Source

Auto merge of #111 - KiChjang:url-origin, r=SimonSapin

Implemented the origin method (fixes #54)

Fixes #54, but still need some clarafication as to how to generate a GUID for schemes such as blob, file and others.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/rust-url/111)
<!-- Reviewable:end -->
bors-servo 11 years ago
parent
commit
a3cd772026
2 changed files with 38 additions and 0 deletions
  1. 1 0
      Cargo.toml
  2. 37 0
      src/lib.rs

+ 1 - 0
Cargo.toml

@@ -33,5 +33,6 @@ version = "*"
 optional = true
 
 [dependencies]
+uuid = "0.1.17"
 rustc-serialize = "0.3"
 matches = "0.1"

+ 37 - 0
src/lib.rs

@@ -122,6 +122,7 @@ assert!(css_url.serialize() == "http://servo.github.io/rust-url/main.css".to_str
 #![cfg_attr(feature="heap_size", plugin(heapsize_plugin))]
 
 extern crate rustc_serialize;
+extern crate uuid;
 
 #[macro_use]
 extern crate matches;
@@ -148,6 +149,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;
@@ -193,6 +196,20 @@ pub struct Url {
     pub fragment: Option<String>,
 }
 
+/// 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(OpaqueOrigin),
+
+    /// 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, Hash, PartialOrd, Ord)]
 #[cfg_attr(feature="heap_size", derive(HeapSizeOf))]
@@ -570,6 +587,26 @@ 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 = Url::parse(self.non_relative_scheme_data().unwrap());
+                match result {
+                    Ok(ref url) => url.origin(),
+                    Err(_)  => Origin::UID(OpaqueOrigin(Uuid::new_v4()))
+                }
+            },
+            "ftp" | "gopher" | "http" | "https" | "ws" | "wss" => {
+                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(OpaqueOrigin(Uuid::new_v4())),
+            _ => Origin::UID(OpaqueOrigin(Uuid::new_v4()))
+        }
+    }
+
     /// 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()