/rust/registry/src/index.crates.io-1949cf8c6b5b557f/url-2.5.7/src/origin.rs
Line | Count | Source |
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 | 0 | pub fn url_origin(url: &Url) -> Origin { |
18 | 0 | let scheme = url.scheme(); |
19 | 0 | match scheme { |
20 | 0 | "blob" => { |
21 | 0 | let result = Url::parse(url.path()); |
22 | 0 | match result { |
23 | 0 | Ok(ref url) => url_origin(url), |
24 | 0 | Err(_) => Origin::new_opaque(), |
25 | | } |
26 | | } |
27 | 0 | "ftp" | "http" | "https" | "ws" | "wss" => Origin::Tuple( |
28 | 0 | scheme.to_owned(), |
29 | 0 | url.host().unwrap().to_owned(), |
30 | 0 | url.port_or_known_default().unwrap(), |
31 | 0 | ), |
32 | | // TODO: Figure out what to do if the scheme is a file |
33 | 0 | "file" => Origin::new_opaque(), |
34 | 0 | _ => Origin::new_opaque(), |
35 | | } |
36 | 0 | } |
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 | 0 | pub fn new_opaque() -> Self { |
67 | | static COUNTER: AtomicUsize = AtomicUsize::new(0); |
68 | 0 | Self::Opaque(OpaqueOrigin(COUNTER.fetch_add(1, Ordering::SeqCst))) |
69 | 0 | } |
70 | | |
71 | | /// Return whether this origin is a (scheme, host, port) tuple |
72 | | /// (as opposed to an opaque origin). |
73 | 0 | pub fn is_tuple(&self) -> bool { |
74 | 0 | matches!(*self, Self::Tuple(..)) |
75 | 0 | } |
76 | | |
77 | | /// <https://html.spec.whatwg.org/multipage/#ascii-serialisation-of-an-origin> |
78 | 0 | pub fn ascii_serialization(&self) -> String { |
79 | 0 | match *self { |
80 | 0 | Self::Opaque(_) => "null".to_owned(), |
81 | 0 | Self::Tuple(ref scheme, ref host, port) => { |
82 | 0 | if default_port(scheme) == Some(port) { |
83 | 0 | format!("{scheme}://{host}") |
84 | | } else { |
85 | 0 | format!("{scheme}://{host}:{port}") |
86 | | } |
87 | | } |
88 | | } |
89 | 0 | } |
90 | | |
91 | | /// <https://html.spec.whatwg.org/multipage/#unicode-serialisation-of-an-origin> |
92 | 0 | pub fn unicode_serialization(&self) -> String { |
93 | 0 | match *self { |
94 | 0 | Self::Opaque(_) => "null".to_owned(), |
95 | 0 | Self::Tuple(ref scheme, ref host, port) => { |
96 | 0 | let host = match *host { |
97 | 0 | Host::Domain(ref domain) => { |
98 | 0 | let (domain, _errors) = idna::domain_to_unicode(domain); |
99 | 0 | Host::Domain(domain) |
100 | | } |
101 | 0 | _ => host.clone(), |
102 | | }; |
103 | 0 | if default_port(scheme) == Some(port) { |
104 | 0 | format!("{scheme}://{host}") |
105 | | } else { |
106 | 0 | format!("{scheme}://{host}:{port}") |
107 | | } |
108 | | } |
109 | | } |
110 | 0 | } |
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); |