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:[email protected]: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 `Parts` into a `Uri`.
205     ///
206     /// # Examples
207     ///
208     /// Relative URI
209     ///
210     /// ```
211     /// # use http::uri::*;
212     /// let mut parts = Parts::default();
213     /// parts.path_and_query = Some("/foo".parse().unwrap());
214     ///
215     /// let uri = Uri::from_parts(parts).unwrap();
216     ///
217     /// assert_eq!(uri.path(), "/foo");
218     ///
219     /// assert!(uri.scheme().is_none());
220     /// assert!(uri.authority().is_none());
221     /// ```
222     ///
223     /// Absolute URI
224     ///
225     /// ```
226     /// # use http::uri::*;
227     /// let mut parts = Parts::default();
228     /// parts.scheme = Some("http".parse().unwrap());
229     /// parts.authority = Some("foo.com".parse().unwrap());
230     /// parts.path_and_query = Some("/foo".parse().unwrap());
231     ///
232     /// let uri = Uri::from_parts(parts).unwrap();
233     ///
234     /// assert_eq!(uri.scheme().unwrap().as_str(), "http");
235     /// assert_eq!(uri.authority().unwrap(), "foo.com");
236     /// assert_eq!(uri.path(), "/foo");
237     /// ```
from_parts(src: Parts) -> Result<Uri, InvalidUriParts>238     pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts> {
239         if src.scheme.is_some() {
240             if src.authority.is_none() {
241                 return Err(ErrorKind::AuthorityMissing.into());
242             }
243 
244             if src.path_and_query.is_none() {
245                 return Err(ErrorKind::PathAndQueryMissing.into());
246             }
247         } else {
248             if src.authority.is_some() && src.path_and_query.is_some() {
249                 return Err(ErrorKind::SchemeMissing.into());
250             }
251         }
252 
253         let scheme = match src.scheme {
254             Some(scheme) => scheme,
255             None => Scheme {
256                 inner: Scheme2::None,
257             },
258         };
259 
260         let authority = match src.authority {
261             Some(authority) => authority,
262             None => Authority::empty(),
263         };
264 
265         let path_and_query = match src.path_and_query {
266             Some(path_and_query) => path_and_query,
267             None => PathAndQuery::empty(),
268         };
269 
270         Ok(Uri {
271             scheme: scheme,
272             authority: authority,
273             path_and_query: path_and_query,
274         })
275     }
276 
277     /// Attempt to convert a `Bytes` buffer to a `Uri`.
278     ///
279     /// This will try to prevent a copy if the type passed is the type used
280     /// internally, and will copy the data if it is not.
from_maybe_shared<T>(src: T) -> Result<Self, InvalidUri> where T: AsRef<[u8]> + 'static,281     pub fn from_maybe_shared<T>(src: T) -> Result<Self, InvalidUri>
282     where
283         T: AsRef<[u8]> + 'static,
284     {
285         if_downcast_into!(T, Bytes, src, {
286             return Uri::from_shared(src);
287         });
288 
289         Uri::try_from(src.as_ref())
290     }
291 
292     // Not public while `bytes` is unstable.
from_shared(s: Bytes) -> Result<Uri, InvalidUri>293     fn from_shared(s: Bytes) -> Result<Uri, InvalidUri> {
294         use self::ErrorKind::*;
295 
296         if s.len() > MAX_LEN {
297             return Err(TooLong.into());
298         }
299 
300         match s.len() {
301             0 => {
302                 return Err(Empty.into());
303             }
304             1 => match s[0] {
305                 b'/' => {
306                     return Ok(Uri {
307                         scheme: Scheme::empty(),
308                         authority: Authority::empty(),
309                         path_and_query: PathAndQuery::slash(),
310                     });
311                 }
312                 b'*' => {
313                     return Ok(Uri {
314                         scheme: Scheme::empty(),
315                         authority: Authority::empty(),
316                         path_and_query: PathAndQuery::star(),
317                     });
318                 }
319                 _ => {
320                     let authority = Authority::from_shared(s)?;
321 
322                     return Ok(Uri {
323                         scheme: Scheme::empty(),
324                         authority: authority,
325                         path_and_query: PathAndQuery::empty(),
326                     });
327                 }
328             },
329             _ => {}
330         }
331 
332         if s[0] == b'/' {
333             return Ok(Uri {
334                 scheme: Scheme::empty(),
335                 authority: Authority::empty(),
336                 path_and_query: PathAndQuery::from_shared(s)?,
337             });
338         }
339 
340         parse_full(s)
341     }
342 
343     /// Convert a `Uri` from a static string.
344     ///
345     /// This function will not perform any copying, however the string is
346     /// checked to ensure that it is valid.
347     ///
348     /// # Panics
349     ///
350     /// This function panics if the argument is an invalid URI.
351     ///
352     /// # Examples
353     ///
354     /// ```
355     /// # use http::uri::Uri;
356     /// let uri = Uri::from_static("http://example.com/foo");
357     ///
358     /// assert_eq!(uri.host().unwrap(), "example.com");
359     /// assert_eq!(uri.path(), "/foo");
360     /// ```
from_static(src: &'static str) -> Self361     pub fn from_static(src: &'static str) -> Self {
362         let s = Bytes::from_static(src.as_bytes());
363         match Uri::from_shared(s) {
364             Ok(uri) => uri,
365             Err(e) => panic!("static str is not valid URI: {}", e),
366         }
367     }
368 
369     /// Convert a `Uri` into `Parts`.
370     ///
371     /// # Note
372     ///
373     /// This is just an inherent method providing the same functionality as
374     /// `let parts: Parts = uri.into()`
375     ///
376     /// # Examples
377     ///
378     /// ```
379     /// # use http::uri::*;
380     /// let uri: Uri = "/foo".parse().unwrap();
381     ///
382     /// let parts = uri.into_parts();
383     ///
384     /// assert_eq!(parts.path_and_query.unwrap(), "/foo");
385     ///
386     /// assert!(parts.scheme.is_none());
387     /// assert!(parts.authority.is_none());
388     /// ```
389     #[inline]
into_parts(self) -> Parts390     pub fn into_parts(self) -> Parts {
391         self.into()
392     }
393 
394     /// Returns the path & query components of the Uri
395     #[inline]
path_and_query(&self) -> Option<&PathAndQuery>396     pub fn path_and_query(&self) -> Option<&PathAndQuery> {
397         if !self.scheme.inner.is_none() || self.authority.data.is_empty() {
398             Some(&self.path_and_query)
399         } else {
400             None
401         }
402     }
403 
404     /// Get the path of this `Uri`.
405     ///
406     /// Both relative and absolute URIs contain a path component, though it
407     /// might be the empty string. The path component is **case sensitive**.
408     ///
409     /// ```notrust
410     /// abc://username:[email protected]:123/path/data?key=value&key2=value2#fragid1
411     ///                                        |--------|
412     ///                                             |
413     ///                                           path
414     /// ```
415     ///
416     /// If the URI is `*` then the path component is equal to `*`.
417     ///
418     /// # Examples
419     ///
420     /// A relative URI
421     ///
422     /// ```
423     /// # use http::Uri;
424     ///
425     /// let uri: Uri = "/hello/world".parse().unwrap();
426     ///
427     /// assert_eq!(uri.path(), "/hello/world");
428     /// ```
429     ///
430     /// An absolute URI
431     ///
432     /// ```
433     /// # use http::Uri;
434     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
435     ///
436     /// assert_eq!(uri.path(), "/hello/world");
437     /// ```
438     #[inline]
path(&self) -> &str439     pub fn path(&self) -> &str {
440         if self.has_path() {
441             self.path_and_query.path()
442         } else {
443             ""
444         }
445     }
446 
447     /// Get the scheme of this `Uri`.
448     ///
449     /// The URI scheme refers to a specification for assigning identifiers
450     /// within that scheme. Only absolute URIs contain a scheme component, but
451     /// not all absolute URIs will contain a scheme component.  Although scheme
452     /// names are case-insensitive, the canonical form is lowercase.
453     ///
454     /// ```notrust
455     /// abc://username:[email protected]:123/path/data?key=value&key2=value2#fragid1
456     /// |-|
457     ///  |
458     /// scheme
459     /// ```
460     ///
461     /// # Examples
462     ///
463     /// Absolute URI
464     ///
465     /// ```
466     /// use http::uri::{Scheme, Uri};
467     ///
468     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
469     ///
470     /// assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
471     /// ```
472     ///
473     ///
474     /// Relative URI
475     ///
476     /// ```
477     /// # use http::Uri;
478     /// let uri: Uri = "/hello/world".parse().unwrap();
479     ///
480     /// assert!(uri.scheme().is_none());
481     /// ```
482     #[inline]
scheme(&self) -> Option<&Scheme>483     pub fn scheme(&self) -> Option<&Scheme> {
484         if self.scheme.inner.is_none() {
485             None
486         } else {
487             Some(&self.scheme)
488         }
489     }
490 
491     /// Get the scheme of this `Uri` as a `&str`.
492     ///
493     /// # Example
494     ///
495     /// ```
496     /// # use http::Uri;
497     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
498     ///
499     /// assert_eq!(uri.scheme_str(), Some("http"));
500     /// ```
501     #[inline]
scheme_str(&self) -> Option<&str>502     pub fn scheme_str(&self) -> Option<&str> {
503         if self.scheme.inner.is_none() {
504             None
505         } else {
506             Some(self.scheme.as_str())
507         }
508     }
509 
510     /// Get the authority of this `Uri`.
511     ///
512     /// The authority is a hierarchical element for naming authority such that
513     /// the remainder of the URI is delegated to that authority. For HTTP, the
514     /// authority consists of the host and port. The host portion of the
515     /// authority is **case-insensitive**.
516     ///
517     /// The authority also includes a `username:password` component, however
518     /// the use of this is deprecated and should be avoided.
519     ///
520     /// ```notrust
521     /// abc://username:[email protected]:123/path/data?key=value&key2=value2#fragid1
522     ///       |-------------------------------|
523     ///                     |
524     ///                 authority
525     /// ```
526     ///
527     /// # Examples
528     ///
529     /// Absolute URI
530     ///
531     /// ```
532     /// # use http::Uri;
533     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
534     ///
535     /// assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
536     /// ```
537     ///
538     ///
539     /// Relative URI
540     ///
541     /// ```
542     /// # use http::Uri;
543     /// let uri: Uri = "/hello/world".parse().unwrap();
544     ///
545     /// assert!(uri.authority().is_none());
546     /// ```
547     #[inline]
authority(&self) -> Option<&Authority>548     pub fn authority(&self) -> Option<&Authority> {
549         if self.authority.data.is_empty() {
550             None
551         } else {
552             Some(&self.authority)
553         }
554     }
555 
556     /// Get the host of this `Uri`.
557     ///
558     /// The host subcomponent of authority is identified by an IP literal
559     /// encapsulated within square brackets, an IPv4 address in dotted- decimal
560     /// form, or a registered name.  The host subcomponent is **case-insensitive**.
561     ///
562     /// ```notrust
563     /// abc://username:[email protected]:123/path/data?key=value&key2=value2#fragid1
564     ///                         |---------|
565     ///                              |
566     ///                             host
567     /// ```
568     ///
569     /// # Examples
570     ///
571     /// Absolute URI
572     ///
573     /// ```
574     /// # use http::Uri;
575     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
576     ///
577     /// assert_eq!(uri.host(), Some("example.org"));
578     /// ```
579     ///
580     ///
581     /// Relative URI
582     ///
583     /// ```
584     /// # use http::Uri;
585     /// let uri: Uri = "/hello/world".parse().unwrap();
586     ///
587     /// assert!(uri.host().is_none());
588     /// ```
589     #[inline]
host(&self) -> Option<&str>590     pub fn host(&self) -> Option<&str> {
591         self.authority().map(|a| a.host())
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:[email protected]: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().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().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().is_none());
636     /// ```
port(&self) -> Option<Port<&str>>637     pub fn port(&self) -> Option<Port<&str>> {
638         self.authority().and_then(|a| a.port())
639     }
640 
641     /// Get the port of this `Uri` as a `u16`.
642     ///
643     ///
644     /// # Example
645     ///
646     /// ```
647     /// # use http::{Uri, uri::Port};
648     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
649     ///
650     /// assert_eq!(uri.port_u16(), Some(80));
651     /// ```
port_u16(&self) -> Option<u16>652     pub fn port_u16(&self) -> Option<u16> {
653         self.port().and_then(|p| Some(p.as_u16()))
654     }
655 
656     /// Get the query string of this `Uri`, starting after the `?`.
657     ///
658     /// The query component contains non-hierarchical data that, along with data
659     /// in the path component, serves to identify a resource within the scope of
660     /// the URI's scheme and naming authority (if any). The query component is
661     /// indicated by the first question mark ("?") character and terminated by a
662     /// number sign ("#") character or by the end of the URI.
663     ///
664     /// ```notrust
665     /// abc://username:[email protected]:123/path/data?key=value&key2=value2#fragid1
666     ///                                                   |-------------------|
667     ///                                                             |
668     ///                                                           query
669     /// ```
670     ///
671     /// # Examples
672     ///
673     /// Absolute URI
674     ///
675     /// ```
676     /// # use http::Uri;
677     /// let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
678     ///
679     /// assert_eq!(uri.query(), Some("key=value"));
680     /// ```
681     ///
682     /// Relative URI with a query string component
683     ///
684     /// ```
685     /// # use http::Uri;
686     /// let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
687     ///
688     /// assert_eq!(uri.query(), Some("key=value&foo=bar"));
689     /// ```
690     ///
691     /// Relative URI without a query string component
692     ///
693     /// ```
694     /// # use http::Uri;
695     /// let uri: Uri = "/hello/world".parse().unwrap();
696     ///
697     /// assert!(uri.query().is_none());
698     /// ```
699     #[inline]
query(&self) -> Option<&str>700     pub fn query(&self) -> Option<&str> {
701         self.path_and_query.query()
702     }
703 
has_path(&self) -> bool704     fn has_path(&self) -> bool {
705         !self.path_and_query.data.is_empty() || !self.scheme.inner.is_none()
706     }
707 }
708 
709 impl<'a> TryFrom<&'a [u8]> for Uri {
710     type Error = InvalidUri;
711 
712     #[inline]
try_from(t: &'a [u8]) -> Result<Self, Self::Error>713     fn try_from(t: &'a [u8]) -> Result<Self, Self::Error> {
714         Uri::from_shared(Bytes::copy_from_slice(t))
715     }
716 }
717 
718 impl<'a> TryFrom<&'a str> for Uri {
719     type Error = InvalidUri;
720 
721     #[inline]
try_from(t: &'a str) -> Result<Self, Self::Error>722     fn try_from(t: &'a str) -> Result<Self, Self::Error> {
723         t.parse()
724     }
725 }
726 
727 impl<'a> TryFrom<&'a String> for Uri {
728     type Error = InvalidUri;
729 
730     #[inline]
try_from(t: &'a String) -> Result<Self, Self::Error>731     fn try_from(t: &'a String) -> Result<Self, Self::Error> {
732         t.parse()
733     }
734 }
735 
736 impl TryFrom<String> for Uri {
737     type Error = InvalidUri;
738 
739     #[inline]
try_from(t: String) -> Result<Self, Self::Error>740     fn try_from(t: String) -> Result<Self, Self::Error> {
741         Uri::from_shared(Bytes::from(t))
742     }
743 }
744 
745 impl<'a> TryFrom<Vec<u8>> for Uri {
746     type Error = InvalidUri;
747 
748     #[inline]
try_from(vec: Vec<u8>) -> Result<Self, Self::Error>749     fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
750         Uri::from_shared(Bytes::from(vec))
751     }
752 }
753 
754 impl TryFrom<Parts> for Uri {
755     type Error = InvalidUriParts;
756 
757     #[inline]
try_from(src: Parts) -> Result<Self, Self::Error>758     fn try_from(src: Parts) -> Result<Self, Self::Error> {
759         Uri::from_parts(src)
760     }
761 }
762 
763 impl<'a> TryFrom<&'a Uri> for Uri {
764     type Error = crate::Error;
765 
766     #[inline]
try_from(src: &'a Uri) -> Result<Self, Self::Error>767     fn try_from(src: &'a Uri) -> Result<Self, Self::Error> {
768         Ok(src.clone())
769     }
770 }
771 
772 /// Convert an `Authority` into a `Uri`.
773 impl From<Authority> for Uri {
from(authority: Authority) -> Self774     fn from(authority: Authority) -> Self {
775         Self {
776             scheme: Scheme::empty(),
777             authority,
778             path_and_query: PathAndQuery::empty(),
779         }
780     }
781 }
782 
783 /// Convert a `PathAndQuery` into a `Uri`.
784 impl From<PathAndQuery> for Uri {
from(path_and_query: PathAndQuery) -> Self785     fn from(path_and_query: PathAndQuery) -> Self {
786         Self {
787             scheme: Scheme::empty(),
788             authority: Authority::empty(),
789             path_and_query,
790         }
791     }
792 }
793 
794 /// Convert a `Uri` into `Parts`
795 impl From<Uri> for Parts {
from(src: Uri) -> Self796     fn from(src: Uri) -> Self {
797         let path_and_query = if src.has_path() {
798             Some(src.path_and_query)
799         } else {
800             None
801         };
802 
803         let scheme = match src.scheme.inner {
804             Scheme2::None => None,
805             _ => Some(src.scheme),
806         };
807 
808         let authority = if src.authority.data.is_empty() {
809             None
810         } else {
811             Some(src.authority)
812         };
813 
814         Parts {
815             scheme: scheme,
816             authority: authority,
817             path_and_query: path_and_query,
818             _priv: (),
819         }
820     }
821 }
822 
parse_full(mut s: Bytes) -> Result<Uri, InvalidUri>823 fn parse_full(mut s: Bytes) -> Result<Uri, InvalidUri> {
824     // Parse the scheme
825     let scheme = match Scheme2::parse(&s[..])? {
826         Scheme2::None => Scheme2::None,
827         Scheme2::Standard(p) => {
828             // TODO: use truncate
829             let _ = s.split_to(p.len() + 3);
830             Scheme2::Standard(p)
831         }
832         Scheme2::Other(n) => {
833             // Grab the protocol
834             let mut scheme = s.split_to(n + 3);
835 
836             // Strip ://, TODO: truncate
837             let _ = scheme.split_off(n);
838 
839             // Allocate the ByteStr
840             let val = unsafe { ByteStr::from_utf8_unchecked(scheme) };
841 
842             Scheme2::Other(Box::new(val))
843         }
844     };
845 
846     // Find the end of the authority. The scheme will already have been
847     // extracted.
848     let authority_end = Authority::parse(&s[..])?;
849 
850     if scheme.is_none() {
851         if authority_end != s.len() {
852             return Err(ErrorKind::InvalidFormat.into());
853         }
854 
855         let authority = Authority {
856             data: unsafe { ByteStr::from_utf8_unchecked(s) },
857         };
858 
859         return Ok(Uri {
860             scheme: scheme.into(),
861             authority: authority,
862             path_and_query: PathAndQuery::empty(),
863         });
864     }
865 
866     // Authority is required when absolute
867     if authority_end == 0 {
868         return Err(ErrorKind::InvalidFormat.into());
869     }
870 
871     let authority = s.split_to(authority_end);
872     let authority = Authority {
873         data: unsafe { ByteStr::from_utf8_unchecked(authority) },
874     };
875 
876     Ok(Uri {
877         scheme: scheme.into(),
878         authority: authority,
879         path_and_query: PathAndQuery::from_shared(s)?,
880     })
881 }
882 
883 impl FromStr for Uri {
884     type Err = InvalidUri;
885 
886     #[inline]
from_str(s: &str) -> Result<Uri, InvalidUri>887     fn from_str(s: &str) -> Result<Uri, InvalidUri> {
888         Uri::try_from(s.as_bytes())
889     }
890 }
891 
892 impl PartialEq for Uri {
eq(&self, other: &Uri) -> bool893     fn eq(&self, other: &Uri) -> bool {
894         if self.scheme() != other.scheme() {
895             return false;
896         }
897 
898         if self.authority() != other.authority() {
899             return false;
900         }
901 
902         if self.path() != other.path() {
903             return false;
904         }
905 
906         if self.query() != other.query() {
907             return false;
908         }
909 
910         true
911     }
912 }
913 
914 impl PartialEq<str> for Uri {
eq(&self, other: &str) -> bool915     fn eq(&self, other: &str) -> bool {
916         let mut other = other.as_bytes();
917         let mut absolute = false;
918 
919         if let Some(scheme) = self.scheme() {
920             let scheme = scheme.as_str().as_bytes();
921             absolute = true;
922 
923             if other.len() < scheme.len() + 3 {
924                 return false;
925             }
926 
927             if !scheme.eq_ignore_ascii_case(&other[..scheme.len()]) {
928                 return false;
929             }
930 
931             other = &other[scheme.len()..];
932 
933             if &other[..3] != b"://" {
934                 return false;
935             }
936 
937             other = &other[3..];
938         }
939 
940         if let Some(auth) = self.authority() {
941             let len = auth.data.len();
942             absolute = true;
943 
944             if other.len() < len {
945                 return false;
946             }
947 
948             if !auth.data.as_bytes().eq_ignore_ascii_case(&other[..len]) {
949                 return false;
950             }
951 
952             other = &other[len..];
953         }
954 
955         let path = self.path();
956 
957         if other.len() < path.len() || path.as_bytes() != &other[..path.len()] {
958             if absolute && path == "/" {
959                 // PathAndQuery can be ommitted, fall through
960             } else {
961                 return false;
962             }
963         } else {
964             other = &other[path.len()..];
965         }
966 
967         if let Some(query) = self.query() {
968             if other.len() == 0 {
969                 return query.len() == 0;
970             }
971 
972             if other[0] != b'?' {
973                 return false;
974             }
975 
976             other = &other[1..];
977 
978             if other.len() < query.len() {
979                 return false;
980             }
981 
982             if query.as_bytes() != &other[..query.len()] {
983                 return false;
984             }
985 
986             other = &other[query.len()..];
987         }
988 
989         other.is_empty() || other[0] == b'#'
990     }
991 }
992 
993 impl PartialEq<Uri> for str {
eq(&self, uri: &Uri) -> bool994     fn eq(&self, uri: &Uri) -> bool {
995         uri == self
996     }
997 }
998 
999 impl<'a> PartialEq<&'a str> for Uri {
eq(&self, other: &&'a str) -> bool1000     fn eq(&self, other: &&'a str) -> bool {
1001         self == *other
1002     }
1003 }
1004 
1005 impl<'a> PartialEq<Uri> for &'a str {
eq(&self, uri: &Uri) -> bool1006     fn eq(&self, uri: &Uri) -> bool {
1007         uri == *self
1008     }
1009 }
1010 
1011 impl Eq for Uri {}
1012 
1013 /// Returns a `Uri` representing `/`
1014 impl Default for Uri {
1015     #[inline]
default() -> Uri1016     fn default() -> Uri {
1017         Uri {
1018             scheme: Scheme::empty(),
1019             authority: Authority::empty(),
1020             path_and_query: PathAndQuery::slash(),
1021         }
1022     }
1023 }
1024 
1025 impl fmt::Display for Uri {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1026     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027         if let Some(scheme) = self.scheme() {
1028             write!(f, "{}://", scheme)?;
1029         }
1030 
1031         if let Some(authority) = self.authority() {
1032             write!(f, "{}", authority)?;
1033         }
1034 
1035         write!(f, "{}", self.path())?;
1036 
1037         if let Some(query) = self.query() {
1038             write!(f, "?{}", query)?;
1039         }
1040 
1041         Ok(())
1042     }
1043 }
1044 
1045 impl fmt::Debug for Uri {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1046     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1047         fmt::Display::fmt(self, f)
1048     }
1049 }
1050 
1051 impl From<ErrorKind> for InvalidUri {
from(src: ErrorKind) -> InvalidUri1052     fn from(src: ErrorKind) -> InvalidUri {
1053         InvalidUri(src)
1054     }
1055 }
1056 
1057 impl From<ErrorKind> for InvalidUriParts {
from(src: ErrorKind) -> InvalidUriParts1058     fn from(src: ErrorKind) -> InvalidUriParts {
1059         InvalidUriParts(src.into())
1060     }
1061 }
1062 
1063 impl InvalidUri {
s(&self) -> &str1064     fn s(&self) -> &str {
1065         match self.0 {
1066             ErrorKind::InvalidUriChar => "invalid uri character",
1067             ErrorKind::InvalidScheme => "invalid scheme",
1068             ErrorKind::InvalidAuthority => "invalid authority",
1069             ErrorKind::InvalidPort => "invalid port",
1070             ErrorKind::InvalidFormat => "invalid format",
1071             ErrorKind::SchemeMissing => "scheme missing",
1072             ErrorKind::AuthorityMissing => "authority missing",
1073             ErrorKind::PathAndQueryMissing => "path missing",
1074             ErrorKind::TooLong => "uri too long",
1075             ErrorKind::Empty => "empty string",
1076             ErrorKind::SchemeTooLong => "scheme too long",
1077         }
1078     }
1079 }
1080 
1081 impl fmt::Display for InvalidUri {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1082     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1083         self.s().fmt(f)
1084     }
1085 }
1086 
1087 impl Error for InvalidUri {}
1088 
1089 impl fmt::Display for InvalidUriParts {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1090     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1091         self.0.fmt(f)
1092     }
1093 }
1094 
1095 impl Error for InvalidUriParts {}
1096 
1097 impl Hash for Uri {
hash<H>(&self, state: &mut H) where H: Hasher,1098     fn hash<H>(&self, state: &mut H)
1099     where
1100         H: Hasher,
1101     {
1102         if !self.scheme.inner.is_none() {
1103             self.scheme.hash(state);
1104             state.write_u8(0xff);
1105         }
1106 
1107         if let Some(auth) = self.authority() {
1108             auth.hash(state);
1109         }
1110 
1111         Hash::hash_slice(self.path().as_bytes(), state);
1112 
1113         if let Some(query) = self.query() {
1114             b'?'.hash(state);
1115             Hash::hash_slice(query.as_bytes(), state);
1116         }
1117     }
1118 }
1119