http/uri/
mod.rs

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
25use crate::byte_str::ByteStr;
26use std::convert::TryFrom;
27
28use bytes::Bytes;
29
30use std::error::Error;
31use std::hash::{Hash, Hasher};
32use std::str::{self, FromStr};
33use std::{fmt, u16, u8};
34
35use self::scheme::Scheme2;
36
37pub use self::authority::Authority;
38pub use self::builder::Builder;
39pub use self::path::PathAndQuery;
40pub use self::port::Port;
41pub use self::scheme::Scheme;
42
43mod authority;
44mod builder;
45mod path;
46mod port;
47mod scheme;
48#[cfg(test)]
49mod 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)]
96pub 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)]
106pub 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)]
122pub struct InvalidUri(ErrorKind);
123
124/// An error resulting from a failed attempt to construct a URI.
125#[derive(Debug)]
126pub struct InvalidUriParts(InvalidUri);
127
128#[derive(Debug, Eq, PartialEq)]
129enum 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
144const 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.
152const 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
182impl 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    /// ```
200    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    /// ```
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.
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.
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    /// ```
361    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]
390    pub fn into_parts(self) -> Parts {
391        self.into()
392    }
393
394    /// Returns the path & query components of the Uri
395    #[inline]
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:password@example.com: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]
439    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:password@example.com: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]
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]
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:password@example.com: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]
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:password@example.com: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]
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:password@example.com:123/path/data?key=value&key2=value2#fragid1
603    ///                                     |-|
604    ///                                      |
605    ///                                     port
606    /// ```
607    ///
608    /// # Examples
609    ///
610    /// Absolute URI with port
611    ///
612    /// ```
613    /// # use http::Uri;
614    /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
615    ///
616    /// let port = uri.port().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    /// ```
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    /// ```
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:password@example.com: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]
700    pub fn query(&self) -> Option<&str> {
701        self.path_and_query.query()
702    }
703
704    fn has_path(&self) -> bool {
705        !self.path_and_query.data.is_empty() || !self.scheme.inner.is_none()
706    }
707}
708
709impl<'a> TryFrom<&'a [u8]> for Uri {
710    type Error = InvalidUri;
711
712    #[inline]
713    fn try_from(t: &'a [u8]) -> Result<Self, Self::Error> {
714        Uri::from_shared(Bytes::copy_from_slice(t))
715    }
716}
717
718impl<'a> TryFrom<&'a str> for Uri {
719    type Error = InvalidUri;
720
721    #[inline]
722    fn try_from(t: &'a str) -> Result<Self, Self::Error> {
723        t.parse()
724    }
725}
726
727impl<'a> TryFrom<&'a String> for Uri {
728    type Error = InvalidUri;
729
730    #[inline]
731    fn try_from(t: &'a String) -> Result<Self, Self::Error> {
732        t.parse()
733    }
734}
735
736impl TryFrom<String> for Uri {
737    type Error = InvalidUri;
738
739    #[inline]
740    fn try_from(t: String) -> Result<Self, Self::Error> {
741        Uri::from_shared(Bytes::from(t))
742    }
743}
744
745impl<'a> TryFrom<Vec<u8>> for Uri {
746    type Error = InvalidUri;
747
748    #[inline]
749    fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
750        Uri::from_shared(Bytes::from(vec))
751    }
752}
753
754impl TryFrom<Parts> for Uri {
755    type Error = InvalidUriParts;
756
757    #[inline]
758    fn try_from(src: Parts) -> Result<Self, Self::Error> {
759        Uri::from_parts(src)
760    }
761}
762
763impl<'a> TryFrom<&'a Uri> for Uri {
764    type Error = crate::Error;
765
766    #[inline]
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`.
773impl From<Authority> for Uri {
774    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`.
784impl From<PathAndQuery> for Uri {
785    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`
795impl From<Uri> for Parts {
796    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
823fn 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
883impl FromStr for Uri {
884    type Err = InvalidUri;
885
886    #[inline]
887    fn from_str(s: &str) -> Result<Uri, InvalidUri> {
888        Uri::try_from(s.as_bytes())
889    }
890}
891
892impl PartialEq for Uri {
893    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
914impl PartialEq<str> for Uri {
915    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 omitted, 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
993impl PartialEq<Uri> for str {
994    fn eq(&self, uri: &Uri) -> bool {
995        uri == self
996    }
997}
998
999impl<'a> PartialEq<&'a str> for Uri {
1000    fn eq(&self, other: &&'a str) -> bool {
1001        self == *other
1002    }
1003}
1004
1005impl<'a> PartialEq<Uri> for &'a str {
1006    fn eq(&self, uri: &Uri) -> bool {
1007        uri == *self
1008    }
1009}
1010
1011impl Eq for Uri {}
1012
1013/// Returns a `Uri` representing `/`
1014impl Default for Uri {
1015    #[inline]
1016    fn default() -> Uri {
1017        Uri {
1018            scheme: Scheme::empty(),
1019            authority: Authority::empty(),
1020            path_and_query: PathAndQuery::slash(),
1021        }
1022    }
1023}
1024
1025impl fmt::Display for Uri {
1026    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
1045impl fmt::Debug for Uri {
1046    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1047        fmt::Display::fmt(self, f)
1048    }
1049}
1050
1051impl From<ErrorKind> for InvalidUri {
1052    fn from(src: ErrorKind) -> InvalidUri {
1053        InvalidUri(src)
1054    }
1055}
1056
1057impl From<ErrorKind> for InvalidUriParts {
1058    fn from(src: ErrorKind) -> InvalidUriParts {
1059        InvalidUriParts(src.into())
1060    }
1061}
1062
1063impl InvalidUri {
1064    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
1081impl fmt::Display for InvalidUri {
1082    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1083        self.s().fmt(f)
1084    }
1085}
1086
1087impl Error for InvalidUri {}
1088
1089impl fmt::Display for InvalidUriParts {
1090    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1091        self.0.fmt(f)
1092    }
1093}
1094
1095impl Error for InvalidUriParts {}
1096
1097impl Hash for Uri {
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}