1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#[cfg(feature = "heapsize")] use heapsize::HeapSizeOf;
use host::Host;
use idna::domain_to_unicode;
use parser::default_port;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, 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())
},
"file" => Origin::new_opaque(),
_ => Origin::new_opaque()
}
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Origin {
Opaque(OpaqueOrigin),
Tuple(String, Host<String>, u16)
}
#[cfg(feature = "heapsize")]
impl HeapSizeOf for Origin {
fn heap_size_of_children(&self) -> usize {
match *self {
Origin::Tuple(ref scheme, ref host, _) => {
scheme.heap_size_of_children() +
host.heap_size_of_children()
},
_ => 0,
}
}
}
impl Origin {
pub fn new_opaque() -> Origin {
static COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
Origin::Opaque(OpaqueOrigin(COUNTER.fetch_add(1, Ordering::SeqCst)))
}
pub fn is_tuple(&self) -> bool {
matches!(*self, Origin::Tuple(..))
}
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)
}
}
}
}
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)
}
}
}
}
}
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct OpaqueOrigin(usize);
#[cfg(feature = "heapsize")]
known_heap_size!(0, OpaqueOrigin);