summaryrefslogtreecommitdiffstats
path: root/third_party/rust/url/src/origin.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/url/src/origin.rs')
-rw-r--r--third_party/rust/url/src/origin.rs113
1 files changed, 113 insertions, 0 deletions
diff --git a/third_party/rust/url/src/origin.rs b/third_party/rust/url/src/origin.rs
new file mode 100644
index 0000000000..3223709dde
--- /dev/null
+++ b/third_party/rust/url/src/origin.rs
@@ -0,0 +1,113 @@
+// Copyright 2016 The rust-url developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use host::Host;
+use idna::domain_to_unicode;
+use parser::default_port;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use Url;
+
+pub fn url_origin(url: &Url) -> Origin {
+ let scheme = url.scheme();
+ match scheme {
+ "blob" => {
+ let result = Url::parse(url.path());
+ match result {
+ Ok(ref url) => url_origin(url),
+ Err(_) => Origin::new_opaque(),
+ }
+ }
+ "ftp" | "gopher" | "http" | "https" | "ws" | "wss" => Origin::Tuple(
+ scheme.to_owned(),
+ url.host().unwrap().to_owned(),
+ url.port_or_known_default().unwrap(),
+ ),
+ // TODO: Figure out what to do if the scheme is a file
+ "file" => Origin::new_opaque(),
+ _ => Origin::new_opaque(),
+ }
+}
+
+/// The origin of an URL
+///
+/// Two URLs with the same origin are considered
+/// to originate from the same entity and can therefore trust
+/// each other.
+///
+/// The origin is determined based on the scheme as follows:
+///
+/// - If the scheme is "blob" the origin is the origin of the
+/// URL contained in the path component. If parsing fails,
+/// it is an opaque origin.
+/// - If the scheme is "ftp", "gopher", "http", "https", "ws", or "wss",
+/// then the origin is a tuple of the scheme, host, and port.
+/// - If the scheme is anything else, the origin is opaque, meaning
+/// the URL does not have the same origin as any other URL.
+///
+/// For more information see <https://url.spec.whatwg.org/#origin>
+#[derive(PartialEq, Eq, Hash, Clone, Debug)]
+pub enum Origin {
+ /// A globally unique identifier
+ Opaque(OpaqueOrigin),
+
+ /// Consists of the URL's scheme, host and port
+ Tuple(String, Host<String>, u16),
+}
+
+impl Origin {
+ /// Creates a new opaque origin that is only equal to itself.
+ pub fn new_opaque() -> Origin {
+ static COUNTER: AtomicUsize = AtomicUsize::new(0);
+ Origin::Opaque(OpaqueOrigin(COUNTER.fetch_add(1, Ordering::SeqCst)))
+ }
+
+ /// Return whether this origin is a (scheme, host, port) tuple
+ /// (as opposed to an opaque origin).
+ pub fn is_tuple(&self) -> bool {
+ matches!(*self, Origin::Tuple(..))
+ }
+
+ /// <https://html.spec.whatwg.org/multipage/#ascii-serialisation-of-an-origin>
+ pub fn ascii_serialization(&self) -> String {
+ match *self {
+ Origin::Opaque(_) => "null".to_owned(),
+ Origin::Tuple(ref scheme, ref host, port) => {
+ if default_port(scheme) == Some(port) {
+ format!("{}://{}", scheme, host)
+ } else {
+ format!("{}://{}:{}", scheme, host, port)
+ }
+ }
+ }
+ }
+
+ /// <https://html.spec.whatwg.org/multipage/#unicode-serialisation-of-an-origin>
+ pub fn unicode_serialization(&self) -> String {
+ match *self {
+ Origin::Opaque(_) => "null".to_owned(),
+ Origin::Tuple(ref scheme, ref host, port) => {
+ let host = match *host {
+ Host::Domain(ref domain) => {
+ let (domain, _errors) = domain_to_unicode(domain);
+ Host::Domain(domain)
+ }
+ _ => host.clone(),
+ };
+ if default_port(scheme) == Some(port) {
+ format!("{}://{}", scheme, host)
+ } else {
+ format!("{}://{}:{}", scheme, host, port)
+ }
+ }
+ }
+ }
+}
+
+/// Opaque identifier for URLs that have file or other schemes
+#[derive(Eq, PartialEq, Hash, Clone, Debug)]
+pub struct OpaqueOrigin(usize);