1 //! URI component of request and response lines
2 //!
3 //! This module primarily contains the `Uri` type which is a component of all
4 //! HTTP requests and also reexports this type at the root of the crate. A URI
5 //! is not always a "full URL" in the sense of something you'd type into a web
6 //! browser, but HTTP requests may only have paths on servers but may have full
7 //! schemes and hostnames on clients.
8 //!
9 //! # Examples
10 //!
11 //! ```
12 //! use http::Uri;
13 //!
14 //! let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
15 //! assert_eq!(uri.path(), "/foo/bar");
16 //! assert_eq!(uri.query(), Some("baz"));
17 //! assert_eq!(uri.host(), None);
18 //!
19 //! let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
20 //! assert_eq!(uri.scheme_part().map(|s| s.as_str()), Some("https"));
21 //! assert_eq!(uri.host(), Some("www.rust-lang.org"));
22 //! assert_eq!(uri.path(), "/install.html");
23 //! ```
24
25 use HttpTryFrom;
26 use byte_str::ByteStr;
27
28 use bytes::Bytes;
29
30 use std::{fmt, u8, u16};
31 // Deprecated in 1.26, needed until our minimum version is >=1.23.
32 #[allow(unused, deprecated)]
33 use std::ascii::AsciiExt;
34 use std::hash::{Hash, Hasher};
35 use std::str::{self, FromStr};
36 use std::error::Error;
37
38 use self::scheme::Scheme2;
39
40 pub use self::authority::Authority;
41 pub use self::builder::Builder;
42 pub use self::path::PathAndQuery;
43 pub use self::scheme::Scheme;
44 pub use self::port::Port;
45
46 mod authority;
47 mod builder;
48 mod path;
49 mod port;
50 mod scheme;
51 #[cfg(test)]
52 mod tests;
53
54 /// The URI component of a request.
55 ///
56 /// For HTTP 1, this is included as part of the request line. From Section 5.3,
57 /// Request Target:
58 ///
59 /// > Once an inbound connection is obtained, the client sends an HTTP
60 /// > request message (Section 3) with a request-target derived from the
61 /// > target URI. There are four distinct formats for the request-target,
62 /// > depending on both the method being requested and whether the request
63 /// > is to a proxy.
64 /// >
65 /// > ```notrust
66 /// > request-target = origin-form
67 /// > / absolute-form
68 /// > / authority-form
69 /// > / asterisk-form
70 /// > ```
71 ///
72 /// The URI is structured as follows:
73 ///
74 /// ```notrust
75 /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
76 /// |-| |-------------------------------||--------| |-------------------| |-----|
77 /// | | | | |
78 /// scheme authority path query fragment
79 /// ```
80 ///
81 /// For HTTP 2.0, the URI is encoded using pseudoheaders.
82 ///
83 /// # Examples
84 ///
85 /// ```
86 /// use http::Uri;
87 ///
88 /// let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
89 /// assert_eq!(uri.path(), "/foo/bar");
90 /// assert_eq!(uri.query(), Some("baz"));
91 /// assert_eq!(uri.host(), None);
92 ///
93 /// let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
94 /// assert_eq!(uri.scheme_part().map(|s| s.as_str()), Some("https"));
95 /// assert_eq!(uri.host(), Some("www.rust-lang.org"));
96 /// assert_eq!(uri.path(), "/install.html");
97 /// ```
98 #[derive(Clone)]
99 pub struct Uri {
100 scheme: Scheme,
101 authority: Authority,
102 path_and_query: PathAndQuery,
103 }
104
105 /// The various parts of a URI.
106 ///
107 /// This struct is used to provide to and retrieve from a URI.
108 #[derive(Debug, Default)]
109 pub struct Parts {
110 /// The scheme component of a URI
111 pub scheme: Option<Scheme>,
112
113 /// The authority component of a URI
114 pub authority: Option<Authority>,
115
116 /// The origin-form component of a URI
117 pub path_and_query: Option<PathAndQuery>,
118
119 /// Allow extending in the future
120 _priv: (),
121 }
122
123 /// An error resulting from a failed attempt to construct a URI.
124 #[derive(Debug)]
125 pub struct InvalidUri(ErrorKind);
126
127 /// An error resulting from a failed attempt to construct a URI.
128 #[derive(Debug)]
129 pub struct InvalidUriBytes(InvalidUri);
130
131 /// An error resulting from a failed attempt to construct a URI.
132 #[derive(Debug)]
133 pub struct InvalidUriParts(InvalidUri);
134
135 #[derive(Debug, Eq, PartialEq)]
136 enum ErrorKind {
137 InvalidUriChar,
138 InvalidScheme,
139 InvalidAuthority,
140 InvalidPort,
141 InvalidFormat,
142 SchemeMissing,
143 AuthorityMissing,
144 PathAndQueryMissing,
145 TooLong,
146 Empty,
147 SchemeTooLong,
148 }
149
150 // u16::MAX is reserved for None
151 const MAX_LEN: usize = (u16::MAX - 1) as usize;
152
153 const URI_CHARS: [u8; 256] = [
154 // 0 1 2 3 4 5 6 7 8 9
155 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // x
156 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
157 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
158 0, 0, 0, b'!', 0, b'#', b'$', 0, b'&', b'\'', // 3x
159 b'(', b')', b'*', b'+', b',', b'-', b'.', b'/', b'0', b'1', // 4x
160 b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b':', b';', // 5x
161 0, b'=', 0, b'?', b'@', b'A', b'B', b'C', b'D', b'E', // 6x
162 b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', // 7x
163 b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', // 8x
164 b'Z', b'[', 0, b']', 0, b'_', 0, b'a', b'b', b'c', // 9x
165 b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x
166 b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x
167 b'x', b'y', b'z', 0, 0, 0, b'~', 0, 0, 0, // 12x
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13x
169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14x
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15x
171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16x
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x
173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 18x
174 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 19x
175 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20x
176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21x
177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 22x
178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x
179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24x
180 0, 0, 0, 0, 0, 0 // 25x
181 ];
182
183 impl Uri {
184 /// Creates a new builder-style object to manufacture a `Uri`.
185 ///
186 /// This method returns an instance of `Builder` which can be usd to
187 /// create a `Uri`.
188 ///
189 /// # Examples
190 ///
191 /// ```
192 /// use http::Uri;
193 ///
194 /// let uri = Uri::builder()
195 /// .scheme("https")
196 /// .authority("hyper.rs")
197 /// .path_and_query("/")
198 /// .build()
199 /// .unwrap();
200 /// ```
builder() -> Builder201 pub fn builder() -> Builder {
202 Builder::new()
203 }
204
205 /// Attempt to convert a `Uri` from `Parts`
from_parts(src: Parts) -> Result<Uri, InvalidUriParts>206 pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts> {
207 if src.scheme.is_some() {
208 if src.authority.is_none() {
209 return Err(ErrorKind::AuthorityMissing.into());
210 }
211
212 if src.path_and_query.is_none() {
213 return Err(ErrorKind::PathAndQueryMissing.into());
214 }
215 } else {
216 if src.authority.is_some() && src.path_and_query.is_some() {
217 return Err(ErrorKind::SchemeMissing.into());
218 }
219 }
220
221 let scheme = match src.scheme {
222 Some(scheme) => scheme,
223 None => Scheme { inner: Scheme2::None },
224 };
225
226 let authority = match src.authority {
227 Some(authority) => authority,
228 None => Authority::empty(),
229 };
230
231 let path_and_query = match src.path_and_query {
232 Some(path_and_query) => path_and_query,
233 None => PathAndQuery::empty(),
234 };
235
236 Ok(Uri {
237 scheme: scheme,
238 authority: authority,
239 path_and_query: path_and_query,
240 })
241 }
242
243 /// Attempt to convert a `Uri` from `Bytes`
244 ///
245 /// This function will be replaced by a `TryFrom` implementation once the
246 /// trait lands in stable.
247 ///
248 /// # Examples
249 ///
250 /// ```
251 /// # extern crate http;
252 /// # use http::uri::*;
253 /// extern crate bytes;
254 ///
255 /// use bytes::Bytes;
256 ///
257 /// # pub fn main() {
258 /// let bytes = Bytes::from("http://example.com/foo");
259 /// let uri = Uri::from_shared(bytes).unwrap();
260 ///
261 /// assert_eq!(uri.host().unwrap(), "example.com");
262 /// assert_eq!(uri.path(), "/foo");
263 /// # }
264 /// ```
from_shared(s: Bytes) -> Result<Uri, InvalidUriBytes>265 pub fn from_shared(s: Bytes) -> Result<Uri, InvalidUriBytes> {
266 use self::ErrorKind::*;
267
268 if s.len() > MAX_LEN {
269 return Err(TooLong.into());
270 }
271
272 match s.len() {
273 0 => {
274 return Err(Empty.into());
275 }
276 1 => {
277 match s[0] {
278 b'/' => {
279 return Ok(Uri {
280 scheme: Scheme::empty(),
281 authority: Authority::empty(),
282 path_and_query: PathAndQuery::slash(),
283 });
284 }
285 b'*' => {
286 return Ok(Uri {
287 scheme: Scheme::empty(),
288 authority: Authority::empty(),
289 path_and_query: PathAndQuery::star(),
290 });
291 }
292 _ => {
293 let authority = Authority::from_shared(s)?;
294
295 return Ok(Uri {
296 scheme: Scheme::empty(),
297 authority: authority,
298 path_and_query: PathAndQuery::empty(),
299 });
300 }
301 }
302 }
303 _ => {}
304 }
305
306 if s[0] == b'/' {
307 return Ok(Uri {
308 scheme: Scheme::empty(),
309 authority: Authority::empty(),
310 path_and_query: PathAndQuery::from_shared(s)?,
311 });
312 }
313
314 parse_full(s)
315 }
316
317 /// Convert a `Uri` from a static string.
318 ///
319 /// This function will not perform any copying, however the string is
320 /// checked to ensure that it is valid.
321 ///
322 /// # Panics
323 ///
324 /// This function panics if the argument is an invalid URI.
325 ///
326 /// # Examples
327 ///
328 /// ```
329 /// # use http::uri::Uri;
330 /// let uri = Uri::from_static("http://example.com/foo");
331 ///
332 /// assert_eq!(uri.host().unwrap(), "example.com");
333 /// assert_eq!(uri.path(), "/foo");
334 /// ```
from_static(src: &'static str) -> Self335 pub fn from_static(src: &'static str) -> Self {
336 let s = Bytes::from_static(src.as_bytes());
337 match Uri::from_shared(s) {
338 Ok(uri) => uri,
339 Err(e) => panic!("static str is not valid URI: {}", e),
340 }
341 }
342
343 /// Convert a `Uri` into `Parts`.
344 ///
345 /// # Note
346 ///
347 /// This is just an inherent method providing the same functionality as
348 /// `let parts: Parts = uri.into()`
349 ///
350 /// # Examples
351 ///
352 /// ```
353 /// # use http::uri::*;
354 /// let uri: Uri = "/foo".parse().unwrap();
355 ///
356 /// let parts = uri.into_parts();
357 ///
358 /// assert_eq!(parts.path_and_query.unwrap(), "/foo");
359 ///
360 /// assert!(parts.scheme.is_none());
361 /// assert!(parts.authority.is_none());
362 /// ```
363 #[inline]
into_parts(self) -> Parts364 pub fn into_parts(self) -> Parts {
365 self.into()
366 }
367
368 /// Returns the path & query components of the Uri
369 #[inline]
path_and_query(&self) -> Option<&PathAndQuery>370 pub fn path_and_query(&self) -> Option<&PathAndQuery> {
371 if !self.scheme.inner.is_none() || self.authority.data.is_empty() {
372 Some(&self.path_and_query)
373 } else {
374 None
375 }
376 }
377
378 /// Get the path of this `Uri`.
379 ///
380 /// Both relative and absolute URIs contain a path component, though it
381 /// might be the empty string. The path component is **case sensitive**.
382 ///
383 /// ```notrust
384 /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
385 /// |--------|
386 /// |
387 /// path
388 /// ```
389 ///
390 /// If the URI is `*` then the path component is equal to `*`.
391 ///
392 /// # Examples
393 ///
394 /// A relative URI
395 ///
396 /// ```
397 /// # use http::Uri;
398 ///
399 /// let uri: Uri = "/hello/world".parse().unwrap();
400 ///
401 /// assert_eq!(uri.path(), "/hello/world");
402 /// ```
403 ///
404 /// An absolute URI
405 ///
406 /// ```
407 /// # use http::Uri;
408 /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
409 ///
410 /// assert_eq!(uri.path(), "/hello/world");
411 /// ```
412 #[inline]
path(&self) -> &str413 pub fn path(&self) -> &str {
414 if self.has_path() {
415 self.path_and_query.path()
416 } else {
417 ""
418 }
419 }
420
421 /// Get the scheme of this `Uri`.
422 ///
423 /// The URI scheme refers to a specification for assigning identifiers
424 /// within that scheme. Only absolute URIs contain a scheme component, but
425 /// not all absolute URIs will contain a scheme component. Although scheme
426 /// names are case-insensitive, the canonical form is lowercase.
427 ///
428 /// ```notrust
429 /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
430 /// |-|
431 /// |
432 /// scheme
433 /// ```
434 ///
435 /// # Examples
436 ///
437 /// Absolute URI
438 ///
439 /// ```
440 /// use http::uri::{Scheme, Uri};
441 ///
442 /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
443 ///
444 /// assert_eq!(uri.scheme_part(), Some(&Scheme::HTTP));
445 /// ```
446 ///
447 ///
448 /// Relative URI
449 ///
450 /// ```
451 /// # use http::Uri;
452 /// let uri: Uri = "/hello/world".parse().unwrap();
453 ///
454 /// assert!(uri.scheme_part().is_none());
455 /// ```
456 #[inline]
scheme_part(&self) -> Option<&Scheme>457 pub fn scheme_part(&self) -> Option<&Scheme> {
458 if self.scheme.inner.is_none() {
459 None
460 } else {
461 Some(&self.scheme)
462 }
463 }
464
465 #[deprecated(since = "0.1.2", note = "use scheme_part or scheme_str instead")]
466 #[doc(hidden)]
467 #[inline]
scheme(&self) -> Option<&str>468 pub fn scheme(&self) -> Option<&str> {
469 self.scheme_str()
470 }
471
472 /// Get the scheme of this `Uri` as a `&str`.
473 ///
474 /// # Example
475 ///
476 /// ```
477 /// # use http::Uri;
478 /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
479 ///
480 /// assert_eq!(uri.scheme_str(), Some("http"));
481 /// ```
482 #[inline]
scheme_str(&self) -> Option<&str>483 pub fn scheme_str(&self) -> Option<&str> {
484 if self.scheme.inner.is_none() {
485 None
486 } else {
487 Some(self.scheme.as_str())
488 }
489 }
490
491 /// Get the authority of this `Uri`.
492 ///
493 /// The authority is a hierarchical element for naming authority such that
494 /// the remainder of the URI is delegated to that authority. For HTTP, the
495 /// authority consists of the host and port. The host portion of the
496 /// authority is **case-insensitive**.
497 ///
498 /// The authority also includes a `username:password` component, however
499 /// the use of this is deprecated and should be avoided.
500 ///
501 /// ```notrust
502 /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
503 /// |-------------------------------|
504 /// |
505 /// authority
506 /// ```
507 ///
508 /// This function will be renamed to `authority` in the next semver release.
509 ///
510 /// # Examples
511 ///
512 /// Absolute URI
513 ///
514 /// ```
515 /// # use http::Uri;
516 /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
517 ///
518 /// assert_eq!(uri.authority_part().map(|a| a.as_str()), Some("example.org:80"));
519 /// ```
520 ///
521 ///
522 /// Relative URI
523 ///
524 /// ```
525 /// # use http::Uri;
526 /// let uri: Uri = "/hello/world".parse().unwrap();
527 ///
528 /// assert!(uri.authority_part().is_none());
529 /// ```
530 #[inline]
authority_part(&self) -> Option<&Authority>531 pub fn authority_part(&self) -> Option<&Authority> {
532 if self.authority.data.is_empty() {
533 None
534 } else {
535 Some(&self.authority)
536 }
537 }
538
539 #[deprecated(since = "0.1.1", note = "use authority_part instead")]
540 #[doc(hidden)]
541 #[inline]
authority(&self) -> Option<&str>542 pub fn authority(&self) -> Option<&str> {
543 if self.authority.data.is_empty() {
544 None
545 } else {
546 Some(self.authority.as_str())
547 }
548 }
549
550 /// Get the host of this `Uri`.
551 ///
552 /// The host subcomponent of authority is identified by an IP literal
553 /// encapsulated within square brackets, an IPv4 address in dotted- decimal
554 /// form, or a registered name. The host subcomponent is **case-insensitive**.
555 ///
556 /// ```notrust
557 /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
558 /// |---------|
559 /// |
560 /// host
561 /// ```
562 ///
563 /// # Examples
564 ///
565 /// Absolute URI
566 ///
567 /// ```
568 /// # use http::Uri;
569 /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
570 ///
571 /// assert_eq!(uri.host(), Some("example.org"));
572 /// ```
573 ///
574 ///
575 /// Relative URI
576 ///
577 /// ```
578 /// # use http::Uri;
579 /// let uri: Uri = "/hello/world".parse().unwrap();
580 ///
581 /// assert!(uri.host().is_none());
582 /// ```
583 #[inline]
host(&self) -> Option<&str>584 pub fn host(&self) -> Option<&str> {
585 self.authority_part().map(|a| a.host())
586 }
587
588 #[deprecated(since="0.1.14", note="use `port_part` or `port_u16` instead")]
589 #[doc(hidden)]
port(&self) -> Option<u16>590 pub fn port(&self) -> Option<u16> {
591 self.port_u16()
592 }
593
594 /// Get the port part of this `Uri`.
595 ///
596 /// The port subcomponent of authority is designated by an optional port
597 /// number following the host and delimited from it by a single colon (":")
598 /// character. It can be turned into a decimal port number with the `as_u16`
599 /// method or as a `str` with the `as_str` method.
600 ///
601 /// ```notrust
602 /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
603 /// |-|
604 /// |
605 /// port
606 /// ```
607 ///
608 /// # Examples
609 ///
610 /// Absolute URI with port
611 ///
612 /// ```
613 /// # use http::Uri;
614 /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
615 ///
616 /// let port = uri.port_part().unwrap();
617 /// assert_eq!(port.as_u16(), 80);
618 /// ```
619 ///
620 /// Absolute URI without port
621 ///
622 /// ```
623 /// # use http::Uri;
624 /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
625 ///
626 /// assert!(uri.port_part().is_none());
627 /// ```
628 ///
629 /// Relative URI
630 ///
631 /// ```
632 /// # use http::Uri;
633 /// let uri: Uri = "/hello/world".parse().unwrap();
634 ///
635 /// assert!(uri.port_part().is_none());
636 /// ```
port_part(&self) -> Option<Port<&str>>637 pub fn port_part(&self) -> Option<Port<&str>> {
638 self.authority_part()
639 .and_then(|a| a.port_part())
640 }
641
642 /// Get the port of this `Uri` as a `u16`.
643 ///
644 ///
645 /// # Example
646 ///
647 /// ```
648 /// # use http::{Uri, uri::Port};
649 /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
650 ///
651 /// assert_eq!(uri.port_u16(), Some(80));
652 /// ```
port_u16(&self) -> Option<u16>653 pub fn port_u16(&self) -> Option<u16> {
654 self.port_part().and_then(|p| Some(p.as_u16()))
655 }
656
657 /// Get the query string of this `Uri`, starting after the `?`.
658 ///
659 /// The query component contains non-hierarchical data that, along with data
660 /// in the path component, serves to identify a resource within the scope of
661 /// the URI's scheme and naming authority (if any). The query component is
662 /// indicated by the first question mark ("?") character and terminated by a
663 /// number sign ("#") character or by the end of the URI.
664 ///
665 /// ```notrust
666 /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
667 /// |-------------------|
668 /// |
669 /// query
670 /// ```
671 ///
672 /// # Examples
673 ///
674 /// Absolute URI
675 ///
676 /// ```
677 /// # use http::Uri;
678 /// let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
679 ///
680 /// assert_eq!(uri.query(), Some("key=value"));
681 /// ```
682 ///
683 /// Relative URI with a query string component
684 ///
685 /// ```
686 /// # use http::Uri;
687 /// let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
688 ///
689 /// assert_eq!(uri.query(), Some("key=value&foo=bar"));
690 /// ```
691 ///
692 /// Relative URI without a query string component
693 ///
694 /// ```
695 /// # use http::Uri;
696 /// let uri: Uri = "/hello/world".parse().unwrap();
697 ///
698 /// assert!(uri.query().is_none());
699 /// ```
700 #[inline]
query(&self) -> Option<&str>701 pub fn query(&self) -> Option<&str> {
702 self.path_and_query.query()
703 }
704
has_path(&self) -> bool705 fn has_path(&self) -> bool {
706 !self.path_and_query.data.is_empty() || !self.scheme.inner.is_none()
707 }
708 }
709
710 impl<'a> HttpTryFrom<&'a str> for Uri {
711 type Error = InvalidUri;
712
713 #[inline]
try_from(t: &'a str) -> Result<Self, Self::Error>714 fn try_from(t: &'a str) -> Result<Self, Self::Error> {
715 t.parse()
716 }
717 }
718
719 impl<'a> HttpTryFrom<&'a String> for Uri {
720 type Error = InvalidUri;
721
722 #[inline]
try_from(t: &'a String) -> Result<Self, Self::Error>723 fn try_from(t: &'a String) -> Result<Self, Self::Error> {
724 t.parse()
725 }
726 }
727
728 impl HttpTryFrom<String> for Uri {
729 type Error = InvalidUriBytes;
730
731 #[inline]
try_from(t: String) -> Result<Self, Self::Error>732 fn try_from(t: String) -> Result<Self, Self::Error> {
733 Uri::from_shared(Bytes::from(t))
734 }
735 }
736
737 impl HttpTryFrom<Bytes> for Uri {
738 type Error = InvalidUriBytes;
739
740 #[inline]
try_from(t: Bytes) -> Result<Self, Self::Error>741 fn try_from(t: Bytes) -> Result<Self, Self::Error> {
742 Uri::from_shared(t)
743 }
744 }
745
746 impl HttpTryFrom<Parts> for Uri {
747 type Error = InvalidUriParts;
748
749 #[inline]
try_from(src: Parts) -> Result<Self, Self::Error>750 fn try_from(src: Parts) -> Result<Self, Self::Error> {
751 Uri::from_parts(src)
752 }
753 }
754
755 impl<'a> HttpTryFrom<&'a Uri> for Uri {
756 type Error = ::Error;
757
758 #[inline]
try_from(src: &'a Uri) -> Result<Self, Self::Error>759 fn try_from(src: &'a Uri) -> Result<Self, Self::Error> {
760 Ok(src.clone())
761 }
762 }
763
764 /// Convert a `Uri` from parts
765 ///
766 /// # Examples
767 ///
768 /// Relative URI
769 ///
770 /// ```
771 /// # use http::uri::*;
772 /// let mut parts = Parts::default();
773 /// parts.path_and_query = Some("/foo".parse().unwrap());
774 ///
775 /// let uri = Uri::from_parts(parts).unwrap();
776 ///
777 /// assert_eq!(uri.path(), "/foo");
778 ///
779 /// assert!(uri.scheme_part().is_none());
780 /// assert!(uri.authority().is_none());
781 /// ```
782 ///
783 /// Absolute URI
784 ///
785 /// ```
786 /// # use http::uri::*;
787 /// let mut parts = Parts::default();
788 /// parts.scheme = Some("http".parse().unwrap());
789 /// parts.authority = Some("foo.com".parse().unwrap());
790 /// parts.path_and_query = Some("/foo".parse().unwrap());
791 ///
792 /// let uri = Uri::from_parts(parts).unwrap();
793 ///
794 /// assert_eq!(uri.scheme_part().unwrap().as_str(), "http");
795 /// assert_eq!(uri.authority().unwrap(), "foo.com");
796 /// assert_eq!(uri.path(), "/foo");
797 /// ```
798 impl From<Uri> for Parts {
from(src: Uri) -> Self799 fn from(src: Uri) -> Self {
800 let path_and_query = if src.has_path() {
801 Some(src.path_and_query)
802 } else {
803 None
804 };
805
806 let scheme = match src.scheme.inner {
807 Scheme2::None => None,
808 _ => Some(src.scheme),
809 };
810
811 let authority = if src.authority.data.is_empty() {
812 None
813 } else {
814 Some(src.authority)
815 };
816
817 Parts {
818 scheme: scheme,
819 authority: authority,
820 path_and_query: path_and_query,
821 _priv: (),
822 }
823 }
824 }
825
parse_full(mut s: Bytes) -> Result<Uri, InvalidUriBytes>826 fn parse_full(mut s: Bytes) -> Result<Uri, InvalidUriBytes> {
827 // Parse the scheme
828 let scheme = match Scheme2::parse(&s[..]).map_err(InvalidUriBytes)? {
829 Scheme2::None => Scheme2::None,
830 Scheme2::Standard(p) => {
831 // TODO: use truncate
832 let _ = s.split_to(p.len() + 3);
833 Scheme2::Standard(p)
834 }
835 Scheme2::Other(n) => {
836 // Grab the protocol
837 let mut scheme = s.split_to(n + 3);
838
839 // Strip ://, TODO: truncate
840 let _ = scheme.split_off(n);
841
842 // Allocate the ByteStr
843 let val = unsafe { ByteStr::from_utf8_unchecked(scheme) };
844
845 Scheme2::Other(Box::new(val))
846 }
847 };
848
849 // Find the end of the authority. The scheme will already have been
850 // extracted.
851 let authority_end = Authority::parse(&s[..]).map_err(InvalidUriBytes)?;
852
853 if scheme.is_none() {
854 if authority_end != s.len() {
855 return Err(ErrorKind::InvalidFormat.into());
856 }
857
858 let authority = Authority {
859 data: unsafe { ByteStr::from_utf8_unchecked(s) },
860 };
861
862 return Ok(Uri {
863 scheme: scheme.into(),
864 authority: authority,
865 path_and_query: PathAndQuery::empty(),
866 });
867 }
868
869 // Authority is required when absolute
870 if authority_end == 0 {
871 return Err(ErrorKind::InvalidFormat.into());
872 }
873
874 let authority = s.split_to(authority_end);
875 let authority = Authority {
876 data: unsafe { ByteStr::from_utf8_unchecked(authority) },
877 };
878
879 Ok(Uri {
880 scheme: scheme.into(),
881 authority: authority,
882 path_and_query: PathAndQuery::from_shared(s)?,
883 })
884 }
885
886 impl FromStr for Uri {
887 type Err = InvalidUri;
888
889 #[inline]
from_str(s: &str) -> Result<Uri, InvalidUri>890 fn from_str(s: &str) -> Result<Uri, InvalidUri> {
891 Uri::from_shared(s.into()).map_err(|e| e.0)
892 }
893 }
894
895 impl PartialEq for Uri {
eq(&self, other: &Uri) -> bool896 fn eq(&self, other: &Uri) -> bool {
897 if self.scheme_part() != other.scheme_part() {
898 return false;
899 }
900
901 if self.authority_part() != other.authority_part() {
902 return false;
903 }
904
905 if self.path() != other.path() {
906 return false;
907 }
908
909 if self.query() != other.query() {
910 return false;
911 }
912
913 true
914 }
915 }
916
917 impl PartialEq<str> for Uri {
eq(&self, other: &str) -> bool918 fn eq(&self, other: &str) -> bool {
919 let mut other = other.as_bytes();
920 let mut absolute = false;
921
922 if let Some(scheme) = self.scheme_part() {
923 let scheme = scheme.as_str().as_bytes();
924 absolute = true;
925
926 if other.len() < scheme.len() + 3 {
927 return false;
928 }
929
930 if !scheme.eq_ignore_ascii_case(&other[..scheme.len()]) {
931 return false;
932 }
933
934 other = &other[scheme.len()..];
935
936 if &other[..3] != b"://" {
937 return false;
938 }
939
940 other = &other[3..];
941 }
942
943 if let Some(auth) = self.authority_part() {
944 let len = auth.data.len();
945 absolute = true;
946
947 if other.len() < len {
948 return false;
949 }
950
951 if !auth.data.as_bytes().eq_ignore_ascii_case(&other[..len]) {
952 return false;
953 }
954
955 other = &other[len..];
956 }
957
958 let path = self.path();
959
960 if other.len() < path.len() || path.as_bytes() != &other[..path.len()] {
961 if absolute && path == "/" {
962 // PathAndQuery can be ommitted, fall through
963 } else {
964 return false;
965 }
966 } else {
967 other = &other[path.len()..];
968 }
969
970 if let Some(query) = self.query() {
971 if other.len() == 0 {
972 return query.len() == 0;
973 }
974
975 if other[0] != b'?' {
976 return false;
977 }
978
979 other = &other[1..];
980
981 if other.len() < query.len() {
982 return false;
983 }
984
985 if query.as_bytes() != &other[..query.len()] {
986 return false;
987 }
988
989 other = &other[query.len()..];
990 }
991
992 other.is_empty() || other[0] == b'#'
993 }
994 }
995
996 impl PartialEq<Uri> for str {
eq(&self, uri: &Uri) -> bool997 fn eq(&self, uri: &Uri) -> bool {
998 uri == self
999 }
1000 }
1001
1002 impl<'a> PartialEq<&'a str> for Uri {
eq(&self, other: & &'a str) -> bool1003 fn eq(&self, other: & &'a str) -> bool {
1004 self == *other
1005 }
1006 }
1007
1008 impl<'a> PartialEq<Uri> for &'a str {
eq(&self, uri: &Uri) -> bool1009 fn eq(&self, uri: &Uri) -> bool {
1010 uri == *self
1011 }
1012 }
1013
1014 impl Eq for Uri {}
1015
1016 /// Returns a `Uri` representing `/`
1017 impl Default for Uri {
1018 #[inline]
default() -> Uri1019 fn default() -> Uri {
1020 Uri {
1021 scheme: Scheme::empty(),
1022 authority: Authority::empty(),
1023 path_and_query: PathAndQuery::slash(),
1024 }
1025 }
1026 }
1027
1028 impl fmt::Display for Uri {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1029 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1030 if let Some(scheme) = self.scheme_part() {
1031 write!(f, "{}://", scheme)?;
1032 }
1033
1034 if let Some(authority) = self.authority_part() {
1035 write!(f, "{}", authority)?;
1036 }
1037
1038 write!(f, "{}", self.path())?;
1039
1040 if let Some(query) = self.query() {
1041 write!(f, "?{}", query)?;
1042 }
1043
1044 Ok(())
1045 }
1046 }
1047
1048 impl fmt::Debug for Uri {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1049 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1050 fmt::Display::fmt(self, f)
1051 }
1052 }
1053
1054 impl From<ErrorKind> for InvalidUri {
from(src: ErrorKind) -> InvalidUri1055 fn from(src: ErrorKind) -> InvalidUri {
1056 InvalidUri(src)
1057 }
1058 }
1059
1060 impl From<ErrorKind> for InvalidUriBytes {
from(src: ErrorKind) -> InvalidUriBytes1061 fn from(src: ErrorKind) -> InvalidUriBytes {
1062 InvalidUriBytes(src.into())
1063 }
1064 }
1065
1066 impl From<ErrorKind> for InvalidUriParts {
from(src: ErrorKind) -> InvalidUriParts1067 fn from(src: ErrorKind) -> InvalidUriParts {
1068 InvalidUriParts(src.into())
1069 }
1070 }
1071
1072 impl fmt::Display for InvalidUri {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1073 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1074 self.description().fmt(f)
1075 }
1076 }
1077
1078 impl Error for InvalidUri {
description(&self) -> &str1079 fn description(&self) -> &str {
1080 match self.0 {
1081 ErrorKind::InvalidUriChar => "invalid uri character",
1082 ErrorKind::InvalidScheme => "invalid scheme",
1083 ErrorKind::InvalidAuthority => "invalid authority",
1084 ErrorKind::InvalidPort => "invalid port",
1085 ErrorKind::InvalidFormat => "invalid format",
1086 ErrorKind::SchemeMissing => "scheme missing",
1087 ErrorKind::AuthorityMissing => "authority missing",
1088 ErrorKind::PathAndQueryMissing => "path missing",
1089 ErrorKind::TooLong => "uri too long",
1090 ErrorKind::Empty => "empty string",
1091 ErrorKind::SchemeTooLong => "scheme too long",
1092 }
1093 }
1094 }
1095
1096 impl fmt::Display for InvalidUriBytes {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1097 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1098 self.0.fmt(f)
1099 }
1100 }
1101
1102 impl fmt::Display for InvalidUriParts {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1104 self.0.fmt(f)
1105 }
1106 }
1107
1108 impl Error for InvalidUriBytes {
description(&self) -> &str1109 fn description(&self) -> &str {
1110 self.0.description()
1111 }
1112 }
1113
1114 impl Error for InvalidUriParts {
description(&self) -> &str1115 fn description(&self) -> &str {
1116 self.0.description()
1117 }
1118 }
1119
1120 impl Hash for Uri {
hash<H>(&self, state: &mut H) where H: Hasher1121 fn hash<H>(&self, state: &mut H) where H: Hasher {
1122 if !self.scheme.inner.is_none() {
1123 self.scheme.hash(state);
1124 state.write_u8(0xff);
1125 }
1126
1127 if let Some(auth) = self.authority_part() {
1128 auth.hash(state);
1129 }
1130
1131 Hash::hash_slice(self.path().as_bytes(), state);
1132
1133 if let Some(query) = self.query() {
1134 b'?'.hash(state);
1135 Hash::hash_slice(query.as_bytes(), state);
1136 }
1137 }
1138 }
1139