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     /// This function will be renamed to `authority` in the next semver release.
495     ///
496     /// # Examples
497     ///
498     /// Absolute URI
499     ///
500     /// ```
501     /// # use http::Uri;
502     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
503     ///
504     /// assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
505     /// ```
506     ///
507     ///
508     /// Relative URI
509     ///
510     /// ```
511     /// # use http::Uri;
512     /// let uri: Uri = "/hello/world".parse().unwrap();
513     ///
514     /// assert!(uri.authority().is_none());
515     /// ```
516     #[inline]
authority(&self) -> Option<&Authority>517     pub fn authority(&self) -> Option<&Authority> {
518         if self.authority.data.is_empty() {
519             None
520         } else {
521             Some(&self.authority)
522         }
523     }
524 
525     /// Get the host of this `Uri`.
526     ///
527     /// The host subcomponent of authority is identified by an IP literal
528     /// encapsulated within square brackets, an IPv4 address in dotted- decimal
529     /// form, or a registered name.  The host subcomponent is **case-insensitive**.
530     ///
531     /// ```notrust
532     /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
533     ///                         |---------|
534     ///                              |
535     ///                             host
536     /// ```
537     ///
538     /// # Examples
539     ///
540     /// Absolute URI
541     ///
542     /// ```
543     /// # use http::Uri;
544     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
545     ///
546     /// assert_eq!(uri.host(), Some("example.org"));
547     /// ```
548     ///
549     ///
550     /// Relative URI
551     ///
552     /// ```
553     /// # use http::Uri;
554     /// let uri: Uri = "/hello/world".parse().unwrap();
555     ///
556     /// assert!(uri.host().is_none());
557     /// ```
558     #[inline]
host(&self) -> Option<&str>559     pub fn host(&self) -> Option<&str> {
560         self.authority().map(|a| a.host())
561     }
562 
563     /// Get the port part of this `Uri`.
564     ///
565     /// The port subcomponent of authority is designated by an optional port
566     /// number following the host and delimited from it by a single colon (":")
567     /// character. It can be turned into a decimal port number with the `as_u16`
568     /// method or as a `str` with the `as_str` method.
569     ///
570     /// ```notrust
571     /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
572     ///                                     |-|
573     ///                                      |
574     ///                                     port
575     /// ```
576     ///
577     /// # Examples
578     ///
579     /// Absolute URI with port
580     ///
581     /// ```
582     /// # use http::Uri;
583     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
584     ///
585     /// let port = uri.port().unwrap();
586     /// assert_eq!(port.as_u16(), 80);
587     /// ```
588     ///
589     /// Absolute URI without port
590     ///
591     /// ```
592     /// # use http::Uri;
593     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
594     ///
595     /// assert!(uri.port().is_none());
596     /// ```
597     ///
598     /// Relative URI
599     ///
600     /// ```
601     /// # use http::Uri;
602     /// let uri: Uri = "/hello/world".parse().unwrap();
603     ///
604     /// assert!(uri.port().is_none());
605     /// ```
port(&self) -> Option<Port<&str>>606     pub fn port(&self) -> Option<Port<&str>> {
607         self.authority().and_then(|a| a.port())
608     }
609 
610     /// Get the port of this `Uri` as a `u16`.
611     ///
612     ///
613     /// # Example
614     ///
615     /// ```
616     /// # use http::{Uri, uri::Port};
617     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
618     ///
619     /// assert_eq!(uri.port_u16(), Some(80));
620     /// ```
port_u16(&self) -> Option<u16>621     pub fn port_u16(&self) -> Option<u16> {
622         self.port().and_then(|p| Some(p.as_u16()))
623     }
624 
625     /// Get the query string of this `Uri`, starting after the `?`.
626     ///
627     /// The query component contains non-hierarchical data that, along with data
628     /// in the path component, serves to identify a resource within the scope of
629     /// the URI's scheme and naming authority (if any). The query component is
630     /// indicated by the first question mark ("?") character and terminated by a
631     /// number sign ("#") character or by the end of the URI.
632     ///
633     /// ```notrust
634     /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
635     ///                                                   |-------------------|
636     ///                                                             |
637     ///                                                           query
638     /// ```
639     ///
640     /// # Examples
641     ///
642     /// Absolute URI
643     ///
644     /// ```
645     /// # use http::Uri;
646     /// let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
647     ///
648     /// assert_eq!(uri.query(), Some("key=value"));
649     /// ```
650     ///
651     /// Relative URI with a query string component
652     ///
653     /// ```
654     /// # use http::Uri;
655     /// let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
656     ///
657     /// assert_eq!(uri.query(), Some("key=value&foo=bar"));
658     /// ```
659     ///
660     /// Relative URI without a query string component
661     ///
662     /// ```
663     /// # use http::Uri;
664     /// let uri: Uri = "/hello/world".parse().unwrap();
665     ///
666     /// assert!(uri.query().is_none());
667     /// ```
668     #[inline]
query(&self) -> Option<&str>669     pub fn query(&self) -> Option<&str> {
670         self.path_and_query.query()
671     }
672 
has_path(&self) -> bool673     fn has_path(&self) -> bool {
674         !self.path_and_query.data.is_empty() || !self.scheme.inner.is_none()
675     }
676 }
677 
678 impl<'a> TryFrom<&'a [u8]> for Uri {
679     type Error = InvalidUri;
680 
681     #[inline]
try_from(t: &'a [u8]) -> Result<Self, Self::Error>682     fn try_from(t: &'a [u8]) -> Result<Self, Self::Error> {
683         Uri::from_shared(Bytes::copy_from_slice(t))
684     }
685 }
686 
687 impl<'a> TryFrom<&'a str> for Uri {
688     type Error = InvalidUri;
689 
690     #[inline]
try_from(t: &'a str) -> Result<Self, Self::Error>691     fn try_from(t: &'a str) -> Result<Self, Self::Error> {
692         t.parse()
693     }
694 }
695 
696 impl<'a> TryFrom<&'a String> for Uri {
697     type Error = InvalidUri;
698 
699     #[inline]
try_from(t: &'a String) -> Result<Self, Self::Error>700     fn try_from(t: &'a String) -> Result<Self, Self::Error> {
701         t.parse()
702     }
703 }
704 
705 impl TryFrom<String> for Uri {
706     type Error = InvalidUri;
707 
708     #[inline]
try_from(t: String) -> Result<Self, Self::Error>709     fn try_from(t: String) -> Result<Self, Self::Error> {
710         Uri::from_shared(Bytes::from(t))
711     }
712 }
713 
714 impl<'a> TryFrom<Vec<u8>> for Uri {
715     type Error = InvalidUri;
716 
717     #[inline]
try_from(vec: Vec<u8>) -> Result<Self, Self::Error>718     fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
719         Uri::from_shared(Bytes::from(vec))
720     }
721 }
722 
723 impl TryFrom<Parts> for Uri {
724     type Error = InvalidUriParts;
725 
726     #[inline]
try_from(src: Parts) -> Result<Self, Self::Error>727     fn try_from(src: Parts) -> Result<Self, Self::Error> {
728         Uri::from_parts(src)
729     }
730 }
731 
732 impl<'a> TryFrom<&'a Uri> for Uri {
733     type Error = crate::Error;
734 
735     #[inline]
try_from(src: &'a Uri) -> Result<Self, Self::Error>736     fn try_from(src: &'a Uri) -> Result<Self, Self::Error> {
737         Ok(src.clone())
738     }
739 }
740 
741 /// Convert a `Uri` from parts
742 ///
743 /// # Examples
744 ///
745 /// Relative URI
746 ///
747 /// ```
748 /// # use http::uri::*;
749 /// let mut parts = Parts::default();
750 /// parts.path_and_query = Some("/foo".parse().unwrap());
751 ///
752 /// let uri = Uri::from_parts(parts).unwrap();
753 ///
754 /// assert_eq!(uri.path(), "/foo");
755 ///
756 /// assert!(uri.scheme().is_none());
757 /// assert!(uri.authority().is_none());
758 /// ```
759 ///
760 /// Absolute URI
761 ///
762 /// ```
763 /// # use http::uri::*;
764 /// let mut parts = Parts::default();
765 /// parts.scheme = Some("http".parse().unwrap());
766 /// parts.authority = Some("foo.com".parse().unwrap());
767 /// parts.path_and_query = Some("/foo".parse().unwrap());
768 ///
769 /// let uri = Uri::from_parts(parts).unwrap();
770 ///
771 /// assert_eq!(uri.scheme().unwrap().as_str(), "http");
772 /// assert_eq!(uri.authority().unwrap(), "foo.com");
773 /// assert_eq!(uri.path(), "/foo");
774 /// ```
775 impl From<Uri> for Parts {
from(src: Uri) -> Self776     fn from(src: Uri) -> Self {
777         let path_and_query = if src.has_path() {
778             Some(src.path_and_query)
779         } else {
780             None
781         };
782 
783         let scheme = match src.scheme.inner {
784             Scheme2::None => None,
785             _ => Some(src.scheme),
786         };
787 
788         let authority = if src.authority.data.is_empty() {
789             None
790         } else {
791             Some(src.authority)
792         };
793 
794         Parts {
795             scheme: scheme,
796             authority: authority,
797             path_and_query: path_and_query,
798             _priv: (),
799         }
800     }
801 }
802 
parse_full(mut s: Bytes) -> Result<Uri, InvalidUri>803 fn parse_full(mut s: Bytes) -> Result<Uri, InvalidUri> {
804     // Parse the scheme
805     let scheme = match Scheme2::parse(&s[..])? {
806         Scheme2::None => Scheme2::None,
807         Scheme2::Standard(p) => {
808             // TODO: use truncate
809             let _ = s.split_to(p.len() + 3);
810             Scheme2::Standard(p)
811         }
812         Scheme2::Other(n) => {
813             // Grab the protocol
814             let mut scheme = s.split_to(n + 3);
815 
816             // Strip ://, TODO: truncate
817             let _ = scheme.split_off(n);
818 
819             // Allocate the ByteStr
820             let val = unsafe { ByteStr::from_utf8_unchecked(scheme) };
821 
822             Scheme2::Other(Box::new(val))
823         }
824     };
825 
826     // Find the end of the authority. The scheme will already have been
827     // extracted.
828     let authority_end = Authority::parse(&s[..])?;
829 
830     if scheme.is_none() {
831         if authority_end != s.len() {
832             return Err(ErrorKind::InvalidFormat.into());
833         }
834 
835         let authority = Authority {
836             data: unsafe { ByteStr::from_utf8_unchecked(s) },
837         };
838 
839         return Ok(Uri {
840             scheme: scheme.into(),
841             authority: authority,
842             path_and_query: PathAndQuery::empty(),
843         });
844     }
845 
846     // Authority is required when absolute
847     if authority_end == 0 {
848         return Err(ErrorKind::InvalidFormat.into());
849     }
850 
851     let authority = s.split_to(authority_end);
852     let authority = Authority {
853         data: unsafe { ByteStr::from_utf8_unchecked(authority) },
854     };
855 
856     Ok(Uri {
857         scheme: scheme.into(),
858         authority: authority,
859         path_and_query: PathAndQuery::from_shared(s)?,
860     })
861 }
862 
863 impl FromStr for Uri {
864     type Err = InvalidUri;
865 
866     #[inline]
from_str(s: &str) -> Result<Uri, InvalidUri>867     fn from_str(s: &str) -> Result<Uri, InvalidUri> {
868         Uri::try_from(s.as_bytes())
869     }
870 }
871 
872 impl PartialEq for Uri {
eq(&self, other: &Uri) -> bool873     fn eq(&self, other: &Uri) -> bool {
874         if self.scheme() != other.scheme() {
875             return false;
876         }
877 
878         if self.authority() != other.authority() {
879             return false;
880         }
881 
882         if self.path() != other.path() {
883             return false;
884         }
885 
886         if self.query() != other.query() {
887             return false;
888         }
889 
890         true
891     }
892 }
893 
894 impl PartialEq<str> for Uri {
eq(&self, other: &str) -> bool895     fn eq(&self, other: &str) -> bool {
896         let mut other = other.as_bytes();
897         let mut absolute = false;
898 
899         if let Some(scheme) = self.scheme() {
900             let scheme = scheme.as_str().as_bytes();
901             absolute = true;
902 
903             if other.len() < scheme.len() + 3 {
904                 return false;
905             }
906 
907             if !scheme.eq_ignore_ascii_case(&other[..scheme.len()]) {
908                 return false;
909             }
910 
911             other = &other[scheme.len()..];
912 
913             if &other[..3] != b"://" {
914                 return false;
915             }
916 
917             other = &other[3..];
918         }
919 
920         if let Some(auth) = self.authority() {
921             let len = auth.data.len();
922             absolute = true;
923 
924             if other.len() < len {
925                 return false;
926             }
927 
928             if !auth.data.as_bytes().eq_ignore_ascii_case(&other[..len]) {
929                 return false;
930             }
931 
932             other = &other[len..];
933         }
934 
935         let path = self.path();
936 
937         if other.len() < path.len() || path.as_bytes() != &other[..path.len()] {
938             if absolute && path == "/" {
939                 // PathAndQuery can be ommitted, fall through
940             } else {
941                 return false;
942             }
943         } else {
944             other = &other[path.len()..];
945         }
946 
947         if let Some(query) = self.query() {
948             if other.len() == 0 {
949                 return query.len() == 0;
950             }
951 
952             if other[0] != b'?' {
953                 return false;
954             }
955 
956             other = &other[1..];
957 
958             if other.len() < query.len() {
959                 return false;
960             }
961 
962             if query.as_bytes() != &other[..query.len()] {
963                 return false;
964             }
965 
966             other = &other[query.len()..];
967         }
968 
969         other.is_empty() || other[0] == b'#'
970     }
971 }
972 
973 impl PartialEq<Uri> for str {
eq(&self, uri: &Uri) -> bool974     fn eq(&self, uri: &Uri) -> bool {
975         uri == self
976     }
977 }
978 
979 impl<'a> PartialEq<&'a str> for Uri {
eq(&self, other: &&'a str) -> bool980     fn eq(&self, other: &&'a str) -> bool {
981         self == *other
982     }
983 }
984 
985 impl<'a> PartialEq<Uri> for &'a str {
eq(&self, uri: &Uri) -> bool986     fn eq(&self, uri: &Uri) -> bool {
987         uri == *self
988     }
989 }
990 
991 impl Eq for Uri {}
992 
993 /// Returns a `Uri` representing `/`
994 impl Default for Uri {
995     #[inline]
default() -> Uri996     fn default() -> Uri {
997         Uri {
998             scheme: Scheme::empty(),
999             authority: Authority::empty(),
1000             path_and_query: PathAndQuery::slash(),
1001         }
1002     }
1003 }
1004 
1005 impl fmt::Display for Uri {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1006     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1007         if let Some(scheme) = self.scheme() {
1008             write!(f, "{}://", scheme)?;
1009         }
1010 
1011         if let Some(authority) = self.authority() {
1012             write!(f, "{}", authority)?;
1013         }
1014 
1015         write!(f, "{}", self.path())?;
1016 
1017         if let Some(query) = self.query() {
1018             write!(f, "?{}", query)?;
1019         }
1020 
1021         Ok(())
1022     }
1023 }
1024 
1025 impl fmt::Debug for Uri {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1026     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027         fmt::Display::fmt(self, f)
1028     }
1029 }
1030 
1031 impl From<ErrorKind> for InvalidUri {
from(src: ErrorKind) -> InvalidUri1032     fn from(src: ErrorKind) -> InvalidUri {
1033         InvalidUri(src)
1034     }
1035 }
1036 
1037 impl From<ErrorKind> for InvalidUriParts {
from(src: ErrorKind) -> InvalidUriParts1038     fn from(src: ErrorKind) -> InvalidUriParts {
1039         InvalidUriParts(src.into())
1040     }
1041 }
1042 
1043 impl InvalidUri {
s(&self) -> &str1044     fn s(&self) -> &str {
1045         match self.0 {
1046             ErrorKind::InvalidUriChar => "invalid uri character",
1047             ErrorKind::InvalidScheme => "invalid scheme",
1048             ErrorKind::InvalidAuthority => "invalid authority",
1049             ErrorKind::InvalidPort => "invalid port",
1050             ErrorKind::InvalidFormat => "invalid format",
1051             ErrorKind::SchemeMissing => "scheme missing",
1052             ErrorKind::AuthorityMissing => "authority missing",
1053             ErrorKind::PathAndQueryMissing => "path missing",
1054             ErrorKind::TooLong => "uri too long",
1055             ErrorKind::Empty => "empty string",
1056             ErrorKind::SchemeTooLong => "scheme too long",
1057         }
1058     }
1059 }
1060 
1061 impl fmt::Display for InvalidUri {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1062     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1063         self.s().fmt(f)
1064     }
1065 }
1066 
1067 impl Error for InvalidUri {}
1068 
1069 impl fmt::Display for InvalidUriParts {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1070     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1071         self.0.fmt(f)
1072     }
1073 }
1074 
1075 impl Error for InvalidUriParts {}
1076 
1077 impl Hash for Uri {
hash<H>(&self, state: &mut H) where H: Hasher,1078     fn hash<H>(&self, state: &mut H)
1079     where
1080         H: Hasher,
1081     {
1082         if !self.scheme.inner.is_none() {
1083             self.scheme.hash(state);
1084             state.write_u8(0xff);
1085         }
1086 
1087         if let Some(auth) = self.authority() {
1088             auth.hash(state);
1089         }
1090 
1091         Hash::hash_slice(self.path().as_bytes(), state);
1092 
1093         if let Some(query) = self.query() {
1094             b'?'.hash(state);
1095             Hash::hash_slice(query.as_bytes(), state);
1096         }
1097     }
1098 }
1099