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