1pub mod rfc2396;
2pub mod uri;
3
4#[derive(Debug, Clone, Copy)]
6pub enum ParseRIError {
7 InvalidAuthority,
8 InvalidPathAbsolute,
9 InvalidSegment,
10 InvalidSegmentNzNc,
11 InvalidPChar,
12 InvalidScheme,
13 InvalidSchemeSeparator,
14 InvalidIPLiteral,
15 InvalidIPvFuture,
16 InvalidIPv6address,
17 InvalidH16,
18 InvalidLS32,
19 InvalidIPv4address,
20 InvalidDecOctet,
21 InvalidPctEncoded,
22 NotTermination,
23 Unsupported,
24 Unknown,
25}
26
27#[cfg(test)]
28mod tests {
29 use crate::uri::URIString;
30
31 #[test]
35 fn uri_parse_tests() {
36 let uri = URIString::parse(r#"ftp://ftp.is.co.za/rfc/rfc1808.txt"#).unwrap();
37 assert_eq!(uri.scheme().unwrap(), "ftp");
38 assert_eq!(uri.authority().unwrap(), "ftp.is.co.za");
39 assert!(uri.userinfo().is_none());
40 assert_eq!(uri.host().unwrap(), "ftp.is.co.za");
41 assert!(uri.port().is_none());
42 assert_eq!(uri.path(), "/rfc/rfc1808.txt");
43 assert!(uri.query().is_none());
44 assert!(uri.fragment().is_none());
45
46 let uri = URIString::parse(r#"http://www.ietf.org/rfc/rfc2396.txt"#).unwrap();
47 assert_eq!(uri.scheme().unwrap(), "http");
48 assert_eq!(uri.authority().unwrap(), "www.ietf.org");
49 assert!(uri.userinfo().is_none());
50 assert_eq!(uri.host().unwrap(), "www.ietf.org");
51 assert!(uri.port().is_none());
52 assert_eq!(uri.path(), "/rfc/rfc2396.txt");
53 assert!(uri.query().is_none());
54 assert!(uri.fragment().is_none());
55
56 let uri = URIString::parse(r#"ldap://[2001:db8::7]/c=GB?objectClass?one"#).unwrap();
57 assert_eq!(uri.scheme().unwrap(), "ldap");
58 assert_eq!(uri.authority().unwrap(), "[2001:db8::7]");
59 assert!(uri.userinfo().is_none());
60 assert_eq!(uri.host().unwrap(), "[2001:db8::7]");
61 assert!(uri.port().is_none());
62 assert_eq!(uri.path(), "/c=GB");
63 assert_eq!(uri.query().unwrap(), "objectClass?one");
64 assert!(uri.fragment().is_none());
65
66 let uri = URIString::parse(r#"mailto:John.Doe@example.com"#).unwrap();
67 assert_eq!(uri.scheme().unwrap(), "mailto");
68 assert!(uri.authority().is_none());
69 assert!(uri.userinfo().is_none());
70 assert!(uri.host().is_none());
71 assert!(uri.port().is_none());
72 assert_eq!(uri.path(), "John.Doe@example.com");
73 assert!(uri.query().is_none());
74 assert!(uri.fragment().is_none());
75
76 let uri = URIString::parse(r#"news:comp.infosystems.www.servers.unix"#).unwrap();
77 assert_eq!(uri.scheme().unwrap(), "news");
78 assert!(uri.authority().is_none());
79 assert!(uri.userinfo().is_none());
80 assert!(uri.host().is_none());
81 assert!(uri.port().is_none());
82 assert_eq!(uri.path(), "comp.infosystems.www.servers.unix");
83 assert!(uri.query().is_none());
84 assert!(uri.fragment().is_none());
85
86 let uri = URIString::parse(r#"tel:+1-816-555-1212"#).unwrap();
87 assert_eq!(uri.scheme().unwrap(), "tel");
88 assert!(uri.authority().is_none());
89 assert!(uri.userinfo().is_none());
90 assert!(uri.host().is_none());
91 assert!(uri.port().is_none());
92 assert_eq!(uri.path(), "+1-816-555-1212");
93 assert!(uri.query().is_none());
94 assert!(uri.fragment().is_none());
95
96 let uri = URIString::parse(r#"telnet://192.0.2.16:80/"#).unwrap();
97 assert_eq!(uri.scheme().unwrap(), "telnet");
98 assert_eq!(uri.authority().unwrap(), "192.0.2.16:80");
99 assert!(uri.userinfo().is_none());
100 assert_eq!(uri.host().unwrap(), "192.0.2.16");
101 assert_eq!(uri.port().unwrap(), "80");
102 assert_eq!(uri.path(), "/");
103 assert!(uri.query().is_none());
104 assert!(uri.fragment().is_none());
105
106 let uri =
107 URIString::parse(r#"urn:oasis:names:specification:docbook:dtd:xml:4.1.2"#).unwrap();
108 assert_eq!(uri.scheme().unwrap(), "urn");
109 assert!(uri.authority().is_none());
110 assert!(uri.userinfo().is_none());
111 assert!(uri.host().is_none());
112 assert!(uri.port().is_none());
113 assert_eq!(
114 uri.path(),
115 "oasis:names:specification:docbook:dtd:xml:4.1.2"
116 );
117 assert!(uri.query().is_none());
118 assert!(uri.fragment().is_none());
119
120 let uri =
121 URIString::parse(r#"foo://example.com:8042/over/there?name=ferret#nose"#).unwrap();
122 assert_eq!(uri.scheme().unwrap(), "foo");
123 assert_eq!(uri.authority().unwrap(), "example.com:8042");
124 assert!(uri.userinfo().is_none());
125 assert_eq!(uri.host().unwrap(), "example.com");
126 assert_eq!(uri.port().unwrap(), "8042");
127 assert_eq!(uri.path(), "/over/there");
128 assert_eq!(uri.query().unwrap(), "name=ferret");
129 assert_eq!(uri.fragment().unwrap(), "nose");
130
131 let uri = URIString::parse(r#"foo:"#).unwrap();
133 assert_eq!(uri.scheme().unwrap(), "foo");
134 assert!(uri.authority().is_none());
135 assert!(uri.userinfo().is_none());
136 assert!(uri.host().is_none());
137 assert!(uri.port().is_none());
138 assert_eq!(uri.path(), "");
139 assert!(uri.query().is_none());
140 assert!(uri.fragment().is_none());
141
142 let uri = URIString::parse(r#"foo:/"#).unwrap();
143 assert_eq!(uri.scheme().unwrap(), "foo");
144 assert!(uri.authority().is_none());
145 assert!(uri.userinfo().is_none());
146 assert!(uri.host().is_none());
147 assert!(uri.port().is_none());
148 assert_eq!(uri.path(), "/");
149 assert!(uri.query().is_none());
150 assert!(uri.fragment().is_none());
151
152 let uri = URIString::parse(r#"foo://"#).unwrap();
153 assert_eq!(uri.scheme().unwrap(), "foo");
154 assert_eq!(uri.authority().unwrap(), "");
155 assert!(uri.userinfo().is_none());
156 assert_eq!(uri.host().unwrap(), "");
157 assert!(uri.port().is_none());
158 assert_eq!(uri.path(), "");
159 assert!(uri.query().is_none());
160 assert!(uri.fragment().is_none());
161
162 let uri = URIString::parse(r#"foo:///"#).unwrap();
163 assert_eq!(uri.scheme().unwrap(), "foo");
164 assert_eq!(uri.authority().unwrap(), "");
165 assert!(uri.userinfo().is_none());
166 assert_eq!(uri.host().unwrap(), "");
167 assert!(uri.port().is_none());
168 assert_eq!(uri.path(), "/");
169 assert!(uri.query().is_none());
170 assert!(uri.fragment().is_none());
171
172 let uri = URIString::parse(r#"foo:////"#).unwrap();
173 assert_eq!(uri.scheme().unwrap(), "foo");
174 assert_eq!(uri.authority().unwrap(), "");
175 assert!(uri.userinfo().is_none());
176 assert_eq!(uri.host().unwrap(), "");
177 assert!(uri.port().is_none());
178 assert_eq!(uri.path(), "//");
179 assert!(uri.query().is_none());
180 assert!(uri.fragment().is_none());
181 }
182
183 #[test]
185 fn uri_resolve_tests() {
186 let base = URIString::parse(r#"http://a/b/c/d;p?q"#).unwrap();
187 assert!(base.is_absolute());
188
189 let rel = URIString::parse("g:h").unwrap();
191 assert_eq!(base.resolve(&rel).as_escaped_str(), "g:h");
192 let rel = URIString::parse("g").unwrap();
193 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g");
194 let rel = URIString::parse("./g").unwrap();
195 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g");
196 let rel = URIString::parse("g/").unwrap();
197 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g/");
198 let rel = URIString::parse("/g").unwrap();
199 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
200 let rel = URIString::parse("//g").unwrap();
201 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://g");
202 let rel = URIString::parse("?y").unwrap();
203 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/d;p?y");
204 let rel = URIString::parse("g?y").unwrap();
205 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g?y");
206 let rel = URIString::parse("#s").unwrap();
207 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/d;p?q#s");
208 let rel = URIString::parse("g#s").unwrap();
209 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g#s");
210 let rel = URIString::parse("g?y#s").unwrap();
211 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g?y#s");
212 let rel = URIString::parse(";x").unwrap();
213 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/;x");
214 let rel = URIString::parse("g;x").unwrap();
215 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g;x");
216 let rel = URIString::parse("g;x?y#s").unwrap();
217 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g;x?y#s");
218 let rel = URIString::parse("").unwrap();
219 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/d;p?q");
220 let rel = URIString::parse(".").unwrap();
221 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/");
222 let rel = URIString::parse("./").unwrap();
223 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/");
224 let rel = URIString::parse("..").unwrap();
225 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/");
226 let rel = URIString::parse("../").unwrap();
227 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/");
228 let rel = URIString::parse("../g").unwrap();
229 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/g");
230 let rel = URIString::parse("../..").unwrap();
231 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/");
232 let rel = URIString::parse("../../").unwrap();
233 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/");
234 let rel = URIString::parse("../../g").unwrap();
235 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
236
237 let rel = URIString::parse("../../../g").unwrap();
239 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
240 let rel = URIString::parse("../../../../g").unwrap();
241 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
242 let rel = URIString::parse("/./g").unwrap();
243 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
244 let rel = URIString::parse("/../g").unwrap();
245 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/g");
246 let rel = URIString::parse("g.").unwrap();
247 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g.");
248 let rel = URIString::parse(".g").unwrap();
249 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/.g");
250 let rel = URIString::parse("g..").unwrap();
251 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g..");
252 let rel = URIString::parse("..g").unwrap();
253 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/..g");
254 let rel = URIString::parse("./../g").unwrap();
255 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/g");
256 let rel = URIString::parse("./g/.").unwrap();
257 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g/");
258 let rel = URIString::parse("g/./h").unwrap();
259 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g/h");
260 let rel = URIString::parse("g/../h").unwrap();
261 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/h");
262 let rel = URIString::parse("g;x=1/./y").unwrap();
263 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g;x=1/y");
264 let rel = URIString::parse("g;x=1/../y").unwrap();
265 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/y");
266 let rel = URIString::parse("g?y/./x").unwrap();
267 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g?y/./x");
268 let rel = URIString::parse("g?y/../x").unwrap();
269 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g?y/../x");
270 let rel = URIString::parse("g#s/./x").unwrap();
271 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g#s/./x");
272 let rel = URIString::parse("g#s/../x").unwrap();
273 assert_eq!(base.resolve(&rel).as_escaped_str(), "http://a/b/c/g#s/../x");
274
275 assert_eq!(
277 URIString::parse("http://www.example.org/one/two")
278 .unwrap()
279 .resolve(&URIString::parse("").unwrap())
280 .as_escaped_str(),
281 "http://www.example.org/one/two"
282 );
283 assert_eq!(
284 URIString::parse("http://www.example.org/one/two#frag")
285 .unwrap()
286 .resolve(&URIString::parse("").unwrap())
287 .as_escaped_str(),
288 "http://www.example.org/one/two"
289 );
290 }
291
292 #[cfg(target_family = "windows")]
293 #[test]
294 fn windows_path_test() {
295 assert_eq!(
296 URIString::parse_file_path("C:\\Windows\\System32\\")
297 .unwrap()
298 .as_escaped_str(),
299 "file:C:/Windows/System32/"
300 );
301 assert_eq!(
302 URIString::parse_file_path("\\\\localhost\\share\\")
303 .unwrap()
304 .as_escaped_str(),
305 "file://localhost/share/"
306 );
307
308 let test = URIString::parse_file_path("resources\\test.xml").unwrap();
309 assert_eq!(test.as_unescaped_str().unwrap(), "resources/test.xml");
310
311 let base = URIString::parse_file_path("C:\\Users\\someuser\\Document\\").unwrap();
312 assert_eq!(
313 base.as_unescaped_str().unwrap(),
314 "file:C:/Users/someuser/Document/"
315 );
316
317 let resolved = base.resolve(&test);
318 assert_eq!(
319 resolved.as_unescaped_str().unwrap(),
320 "file:C:/Users/someuser/Document/resources/test.xml"
321 );
322 }
323}