1 | // Copyright 2016 The rust-url developers. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
4 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
5 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
6 | // option. This file may not be copied, modified, or distributed |
7 | // except according to those terms. |
8 | |
9 | use crate::host::Host; |
10 | use crate::parser::default_port; |
11 | use crate::Url; |
12 | use std::sync::atomic::{AtomicUsize, Ordering}; |
13 | |
14 | pub fn url_origin(url: &Url) -> Origin { |
15 | let scheme: &str = url.scheme(); |
16 | match scheme { |
17 | "blob" => { |
18 | let result: Result = Url::parse(input:url.path()); |
19 | match result { |
20 | Ok(ref url: &Url) => url_origin(url), |
21 | Err(_) => Origin::new_opaque(), |
22 | } |
23 | } |
24 | "ftp" | "http" | "https" | "ws" | "wss" => Origin::Tuple( |
25 | scheme.to_owned(), |
26 | url.host().unwrap().to_owned(), |
27 | url.port_or_known_default().unwrap(), |
28 | ), |
29 | // TODO: Figure out what to do if the scheme is a file |
30 | "file" => Origin::new_opaque(), |
31 | _ => Origin::new_opaque(), |
32 | } |
33 | } |
34 | |
35 | /// The origin of an URL |
36 | /// |
37 | /// Two URLs with the same origin are considered |
38 | /// to originate from the same entity and can therefore trust |
39 | /// each other. |
40 | /// |
41 | /// The origin is determined based on the scheme as follows: |
42 | /// |
43 | /// - If the scheme is "blob" the origin is the origin of the |
44 | /// URL contained in the path component. If parsing fails, |
45 | /// it is an opaque origin. |
46 | /// - If the scheme is "ftp", "http", "https", "ws", or "wss", |
47 | /// then the origin is a tuple of the scheme, host, and port. |
48 | /// - If the scheme is anything else, the origin is opaque, meaning |
49 | /// the URL does not have the same origin as any other URL. |
50 | /// |
51 | /// For more information see <https://url.spec.whatwg.org/#origin> |
52 | #[derive (PartialEq, Eq, Hash, Clone, Debug)] |
53 | pub enum Origin { |
54 | /// A globally unique identifier |
55 | Opaque(OpaqueOrigin), |
56 | |
57 | /// Consists of the URL's scheme, host and port |
58 | Tuple(String, Host<String>, u16), |
59 | } |
60 | |
61 | impl Origin { |
62 | /// Creates a new opaque origin that is only equal to itself. |
63 | pub fn new_opaque() -> Origin { |
64 | static COUNTER: AtomicUsize = AtomicUsize::new(0); |
65 | Origin::Opaque(OpaqueOrigin(COUNTER.fetch_add(1, Ordering::SeqCst))) |
66 | } |
67 | |
68 | /// Return whether this origin is a (scheme, host, port) tuple |
69 | /// (as opposed to an opaque origin). |
70 | pub fn is_tuple(&self) -> bool { |
71 | matches!(*self, Origin::Tuple(..)) |
72 | } |
73 | |
74 | /// <https://html.spec.whatwg.org/multipage/#ascii-serialisation-of-an-origin> |
75 | pub fn ascii_serialization(&self) -> String { |
76 | match *self { |
77 | Origin::Opaque(_) => "null" .to_owned(), |
78 | Origin::Tuple(ref scheme, ref host, port) => { |
79 | if default_port(scheme) == Some(port) { |
80 | format!(" {}:// {}" , scheme, host) |
81 | } else { |
82 | format!(" {}:// {}: {}" , scheme, host, port) |
83 | } |
84 | } |
85 | } |
86 | } |
87 | |
88 | /// <https://html.spec.whatwg.org/multipage/#unicode-serialisation-of-an-origin> |
89 | pub fn unicode_serialization(&self) -> String { |
90 | match *self { |
91 | Origin::Opaque(_) => "null" .to_owned(), |
92 | Origin::Tuple(ref scheme, ref host, port) => { |
93 | let host = match *host { |
94 | Host::Domain(ref domain) => { |
95 | let (domain, _errors) = idna::domain_to_unicode(domain); |
96 | Host::Domain(domain) |
97 | } |
98 | _ => host.clone(), |
99 | }; |
100 | if default_port(scheme) == Some(port) { |
101 | format!(" {}:// {}" , scheme, host) |
102 | } else { |
103 | format!(" {}:// {}: {}" , scheme, host, port) |
104 | } |
105 | } |
106 | } |
107 | } |
108 | } |
109 | |
110 | /// Opaque identifier for URLs that have file or other schemes |
111 | #[derive (Eq, PartialEq, Hash, Clone, Debug)] |
112 | pub struct OpaqueOrigin(usize); |
113 | |