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