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