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_part().map(|s| s.as_str()), Some("https"));
21 //! assert_eq!(uri.host(), Some("www.rust-lang.org"));
22 //! assert_eq!(uri.path(), "/install.html");
23 //! ```
24 
25 use HttpTryFrom;
26 use byte_str::ByteStr;
27 
28 use bytes::Bytes;
29 
30 use std::{fmt, u8, u16};
31 // Deprecated in 1.26, needed until our minimum version is >=1.23.
32 #[allow(unused, deprecated)]
33 use std::ascii::AsciiExt;
34 use std::hash::{Hash, Hasher};
35 use std::str::{self, FromStr};
36 use std::error::Error;
37 
38 use self::scheme::Scheme2;
39 
40 pub use self::authority::Authority;
41 pub use self::builder::Builder;
42 pub use self::path::PathAndQuery;
43 pub use self::scheme::Scheme;
44 pub use self::port::Port;
45 
46 mod authority;
47 mod builder;
48 mod path;
49 mod port;
50 mod scheme;
51 #[cfg(test)]
52 mod tests;
53 
54 /// The URI component of a request.
55 ///
56 /// For HTTP 1, this is included as part of the request line. From Section 5.3,
57 /// Request Target:
58 ///
59 /// > Once an inbound connection is obtained, the client sends an HTTP
60 /// > request message (Section 3) with a request-target derived from the
61 /// > target URI.  There are four distinct formats for the request-target,
62 /// > depending on both the method being requested and whether the request
63 /// > is to a proxy.
64 /// >
65 /// > ```notrust
66 /// > request-target = origin-form
67 /// >                / absolute-form
68 /// >                / authority-form
69 /// >                / asterisk-form
70 /// > ```
71 ///
72 /// The URI is structured as follows:
73 ///
74 /// ```notrust
75 /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
76 /// |-|   |-------------------------------||--------| |-------------------| |-----|
77 ///  |                  |                       |               |              |
78 /// scheme          authority                 path            query         fragment
79 /// ```
80 ///
81 /// For HTTP 2.0, the URI is encoded using pseudoheaders.
82 ///
83 /// # Examples
84 ///
85 /// ```
86 /// use http::Uri;
87 ///
88 /// let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
89 /// assert_eq!(uri.path(), "/foo/bar");
90 /// assert_eq!(uri.query(), Some("baz"));
91 /// assert_eq!(uri.host(), None);
92 ///
93 /// let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
94 /// assert_eq!(uri.scheme_part().map(|s| s.as_str()), Some("https"));
95 /// assert_eq!(uri.host(), Some("www.rust-lang.org"));
96 /// assert_eq!(uri.path(), "/install.html");
97 /// ```
98 #[derive(Clone)]
99 pub struct Uri {
100     scheme: Scheme,
101     authority: Authority,
102     path_and_query: PathAndQuery,
103 }
104 
105 /// The various parts of a URI.
106 ///
107 /// This struct is used to provide to and retrieve from a URI.
108 #[derive(Debug, Default)]
109 pub struct Parts {
110     /// The scheme component of a URI
111     pub scheme: Option<Scheme>,
112 
113     /// The authority component of a URI
114     pub authority: Option<Authority>,
115 
116     /// The origin-form component of a URI
117     pub path_and_query: Option<PathAndQuery>,
118 
119     /// Allow extending in the future
120     _priv: (),
121 }
122 
123 /// An error resulting from a failed attempt to construct a URI.
124 #[derive(Debug)]
125 pub struct InvalidUri(ErrorKind);
126 
127 /// An error resulting from a failed attempt to construct a URI.
128 #[derive(Debug)]
129 pub struct InvalidUriBytes(InvalidUri);
130 
131 /// An error resulting from a failed attempt to construct a URI.
132 #[derive(Debug)]
133 pub struct InvalidUriParts(InvalidUri);
134 
135 #[derive(Debug, Eq, PartialEq)]
136 enum ErrorKind {
137     InvalidUriChar,
138     InvalidScheme,
139     InvalidAuthority,
140     InvalidPort,
141     InvalidFormat,
142     SchemeMissing,
143     AuthorityMissing,
144     PathAndQueryMissing,
145     TooLong,
146     Empty,
147     SchemeTooLong,
148 }
149 
150 // u16::MAX is reserved for None
151 const MAX_LEN: usize = (u16::MAX - 1) as usize;
152 
153 const 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 
183 impl 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     /// ```
builder() -> Builder201     pub fn builder() -> Builder {
202         Builder::new()
203     }
204 
205     /// Attempt to convert a `Uri` from `Parts`
from_parts(src: Parts) -> Result<Uri, InvalidUriParts>206     pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts> {
207         if src.scheme.is_some() {
208             if src.authority.is_none() {
209                 return Err(ErrorKind::AuthorityMissing.into());
210             }
211 
212             if src.path_and_query.is_none() {
213                 return Err(ErrorKind::PathAndQueryMissing.into());
214             }
215         } else {
216             if src.authority.is_some() && src.path_and_query.is_some() {
217                 return Err(ErrorKind::SchemeMissing.into());
218             }
219         }
220 
221         let scheme = match src.scheme {
222             Some(scheme) => scheme,
223             None => Scheme { inner: Scheme2::None },
224         };
225 
226         let authority = match src.authority {
227             Some(authority) => authority,
228             None => Authority::empty(),
229         };
230 
231         let path_and_query = match src.path_and_query {
232             Some(path_and_query) => path_and_query,
233             None => PathAndQuery::empty(),
234         };
235 
236         Ok(Uri {
237             scheme: scheme,
238             authority: authority,
239             path_and_query: path_and_query,
240         })
241     }
242 
243     /// Attempt to convert a `Uri` from `Bytes`
244     ///
245     /// This function will be replaced by a `TryFrom` implementation once the
246     /// trait lands in stable.
247     ///
248     /// # Examples
249     ///
250     /// ```
251     /// # extern crate http;
252     /// # use http::uri::*;
253     /// extern crate bytes;
254     ///
255     /// use bytes::Bytes;
256     ///
257     /// # pub fn main() {
258     /// let bytes = Bytes::from("http://example.com/foo");
259     /// let uri = Uri::from_shared(bytes).unwrap();
260     ///
261     /// assert_eq!(uri.host().unwrap(), "example.com");
262     /// assert_eq!(uri.path(), "/foo");
263     /// # }
264     /// ```
from_shared(s: Bytes) -> Result<Uri, InvalidUriBytes>265     pub fn from_shared(s: Bytes) -> Result<Uri, InvalidUriBytes> {
266         use self::ErrorKind::*;
267 
268         if s.len() > MAX_LEN {
269             return Err(TooLong.into());
270         }
271 
272         match s.len() {
273             0 => {
274                 return Err(Empty.into());
275             }
276             1 => {
277                 match s[0] {
278                     b'/' => {
279                         return Ok(Uri {
280                             scheme: Scheme::empty(),
281                             authority: Authority::empty(),
282                             path_and_query: PathAndQuery::slash(),
283                         });
284                     }
285                     b'*' => {
286                         return Ok(Uri {
287                             scheme: Scheme::empty(),
288                             authority: Authority::empty(),
289                             path_and_query: PathAndQuery::star(),
290                         });
291                     }
292                     _ => {
293                         let authority = Authority::from_shared(s)?;
294 
295                         return Ok(Uri {
296                             scheme: Scheme::empty(),
297                             authority: authority,
298                             path_and_query: PathAndQuery::empty(),
299                         });
300                     }
301                 }
302             }
303             _ => {}
304         }
305 
306         if s[0] == b'/' {
307             return Ok(Uri {
308                 scheme: Scheme::empty(),
309                 authority: Authority::empty(),
310                 path_and_query: PathAndQuery::from_shared(s)?,
311             });
312         }
313 
314         parse_full(s)
315     }
316 
317     /// Convert a `Uri` from a static string.
318     ///
319     /// This function will not perform any copying, however the string is
320     /// checked to ensure that it is valid.
321     ///
322     /// # Panics
323     ///
324     /// This function panics if the argument is an invalid URI.
325     ///
326     /// # Examples
327     ///
328     /// ```
329     /// # use http::uri::Uri;
330     /// let uri = Uri::from_static("http://example.com/foo");
331     ///
332     /// assert_eq!(uri.host().unwrap(), "example.com");
333     /// assert_eq!(uri.path(), "/foo");
334     /// ```
from_static(src: &'static str) -> Self335     pub fn from_static(src: &'static str) -> Self {
336         let s = Bytes::from_static(src.as_bytes());
337         match Uri::from_shared(s) {
338             Ok(uri) => uri,
339             Err(e) => panic!("static str is not valid URI: {}", e),
340         }
341     }
342 
343     /// Convert a `Uri` into `Parts`.
344     ///
345     /// # Note
346     ///
347     /// This is just an inherent method providing the same functionality as
348     /// `let parts: Parts = uri.into()`
349     ///
350     /// # Examples
351     ///
352     /// ```
353     /// # use http::uri::*;
354     /// let uri: Uri = "/foo".parse().unwrap();
355     ///
356     /// let parts = uri.into_parts();
357     ///
358     /// assert_eq!(parts.path_and_query.unwrap(), "/foo");
359     ///
360     /// assert!(parts.scheme.is_none());
361     /// assert!(parts.authority.is_none());
362     /// ```
363     #[inline]
into_parts(self) -> Parts364     pub fn into_parts(self) -> Parts {
365         self.into()
366     }
367 
368     /// Returns the path & query components of the Uri
369     #[inline]
path_and_query(&self) -> Option<&PathAndQuery>370     pub fn path_and_query(&self) -> Option<&PathAndQuery> {
371         if !self.scheme.inner.is_none() || self.authority.data.is_empty() {
372             Some(&self.path_and_query)
373         } else {
374             None
375         }
376     }
377 
378     /// Get the path of this `Uri`.
379     ///
380     /// Both relative and absolute URIs contain a path component, though it
381     /// might be the empty string. The path component is **case sensitive**.
382     ///
383     /// ```notrust
384     /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
385     ///                                        |--------|
386     ///                                             |
387     ///                                           path
388     /// ```
389     ///
390     /// If the URI is `*` then the path component is equal to `*`.
391     ///
392     /// # Examples
393     ///
394     /// A relative URI
395     ///
396     /// ```
397     /// # use http::Uri;
398     ///
399     /// let uri: Uri = "/hello/world".parse().unwrap();
400     ///
401     /// assert_eq!(uri.path(), "/hello/world");
402     /// ```
403     ///
404     /// An absolute URI
405     ///
406     /// ```
407     /// # use http::Uri;
408     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
409     ///
410     /// assert_eq!(uri.path(), "/hello/world");
411     /// ```
412     #[inline]
path(&self) -> &str413     pub fn path(&self) -> &str {
414         if self.has_path() {
415             self.path_and_query.path()
416         } else {
417             ""
418         }
419     }
420 
421     /// Get the scheme of this `Uri`.
422     ///
423     /// The URI scheme refers to a specification for assigning identifiers
424     /// within that scheme. Only absolute URIs contain a scheme component, but
425     /// not all absolute URIs will contain a scheme component.  Although scheme
426     /// names are case-insensitive, the canonical form is lowercase.
427     ///
428     /// ```notrust
429     /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
430     /// |-|
431     ///  |
432     /// scheme
433     /// ```
434     ///
435     /// # Examples
436     ///
437     /// Absolute URI
438     ///
439     /// ```
440     /// use http::uri::{Scheme, Uri};
441     ///
442     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
443     ///
444     /// assert_eq!(uri.scheme_part(), Some(&Scheme::HTTP));
445     /// ```
446     ///
447     ///
448     /// Relative URI
449     ///
450     /// ```
451     /// # use http::Uri;
452     /// let uri: Uri = "/hello/world".parse().unwrap();
453     ///
454     /// assert!(uri.scheme_part().is_none());
455     /// ```
456     #[inline]
scheme_part(&self) -> Option<&Scheme>457     pub fn scheme_part(&self) -> Option<&Scheme> {
458         if self.scheme.inner.is_none() {
459             None
460         } else {
461             Some(&self.scheme)
462         }
463     }
464 
465     #[deprecated(since = "0.1.2", note = "use scheme_part or scheme_str instead")]
466     #[doc(hidden)]
467     #[inline]
scheme(&self) -> Option<&str>468     pub fn scheme(&self) -> Option<&str> {
469         self.scheme_str()
470     }
471 
472     /// Get the scheme of this `Uri` as a `&str`.
473     ///
474     /// # Example
475     ///
476     /// ```
477     /// # use http::Uri;
478     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
479     ///
480     /// assert_eq!(uri.scheme_str(), Some("http"));
481     /// ```
482     #[inline]
scheme_str(&self) -> Option<&str>483     pub fn scheme_str(&self) -> Option<&str> {
484         if self.scheme.inner.is_none() {
485             None
486         } else {
487             Some(self.scheme.as_str())
488         }
489     }
490 
491     /// Get the authority of this `Uri`.
492     ///
493     /// The authority is a hierarchical element for naming authority such that
494     /// the remainder of the URI is delegated to that authority. For HTTP, the
495     /// authority consists of the host and port. The host portion of the
496     /// authority is **case-insensitive**.
497     ///
498     /// The authority also includes a `username:password` component, however
499     /// the use of this is deprecated and should be avoided.
500     ///
501     /// ```notrust
502     /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
503     ///       |-------------------------------|
504     ///                     |
505     ///                 authority
506     /// ```
507     ///
508     /// This function will be renamed to `authority` in the next semver release.
509     ///
510     /// # Examples
511     ///
512     /// Absolute URI
513     ///
514     /// ```
515     /// # use http::Uri;
516     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
517     ///
518     /// assert_eq!(uri.authority_part().map(|a| a.as_str()), Some("example.org:80"));
519     /// ```
520     ///
521     ///
522     /// Relative URI
523     ///
524     /// ```
525     /// # use http::Uri;
526     /// let uri: Uri = "/hello/world".parse().unwrap();
527     ///
528     /// assert!(uri.authority_part().is_none());
529     /// ```
530     #[inline]
authority_part(&self) -> Option<&Authority>531     pub fn authority_part(&self) -> Option<&Authority> {
532         if self.authority.data.is_empty() {
533             None
534         } else {
535             Some(&self.authority)
536         }
537     }
538 
539     #[deprecated(since = "0.1.1", note = "use authority_part instead")]
540     #[doc(hidden)]
541     #[inline]
authority(&self) -> Option<&str>542     pub fn authority(&self) -> Option<&str> {
543         if self.authority.data.is_empty() {
544             None
545         } else {
546             Some(self.authority.as_str())
547         }
548     }
549 
550     /// Get the host of this `Uri`.
551     ///
552     /// The host subcomponent of authority is identified by an IP literal
553     /// encapsulated within square brackets, an IPv4 address in dotted- decimal
554     /// form, or a registered name.  The host subcomponent is **case-insensitive**.
555     ///
556     /// ```notrust
557     /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
558     ///                         |---------|
559     ///                              |
560     ///                             host
561     /// ```
562     ///
563     /// # Examples
564     ///
565     /// Absolute URI
566     ///
567     /// ```
568     /// # use http::Uri;
569     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
570     ///
571     /// assert_eq!(uri.host(), Some("example.org"));
572     /// ```
573     ///
574     ///
575     /// Relative URI
576     ///
577     /// ```
578     /// # use http::Uri;
579     /// let uri: Uri = "/hello/world".parse().unwrap();
580     ///
581     /// assert!(uri.host().is_none());
582     /// ```
583     #[inline]
host(&self) -> Option<&str>584     pub fn host(&self) -> Option<&str> {
585         self.authority_part().map(|a| a.host())
586     }
587 
588     #[deprecated(since="0.1.14", note="use `port_part` or `port_u16` instead")]
589     #[doc(hidden)]
port(&self) -> Option<u16>590     pub fn port(&self) -> Option<u16> {
591         self.port_u16()
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_part().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_part().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_part().is_none());
636     /// ```
port_part(&self) -> Option<Port<&str>>637     pub fn port_part(&self) -> Option<Port<&str>> {
638         self.authority_part()
639             .and_then(|a| a.port_part())
640     }
641 
642     /// Get the port of this `Uri` as a `u16`.
643     ///
644     ///
645     /// # Example
646     ///
647     /// ```
648     /// # use http::{Uri, uri::Port};
649     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
650     ///
651     /// assert_eq!(uri.port_u16(), Some(80));
652     /// ```
port_u16(&self) -> Option<u16>653     pub fn port_u16(&self) -> Option<u16> {
654         self.port_part().and_then(|p| Some(p.as_u16()))
655     }
656 
657     /// Get the query string of this `Uri`, starting after the `?`.
658     ///
659     /// The query component contains non-hierarchical data that, along with data
660     /// in the path component, serves to identify a resource within the scope of
661     /// the URI's scheme and naming authority (if any). The query component is
662     /// indicated by the first question mark ("?") character and terminated by a
663     /// number sign ("#") character or by the end of the URI.
664     ///
665     /// ```notrust
666     /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
667     ///                                                   |-------------------|
668     ///                                                             |
669     ///                                                           query
670     /// ```
671     ///
672     /// # Examples
673     ///
674     /// Absolute URI
675     ///
676     /// ```
677     /// # use http::Uri;
678     /// let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
679     ///
680     /// assert_eq!(uri.query(), Some("key=value"));
681     /// ```
682     ///
683     /// Relative URI with a query string component
684     ///
685     /// ```
686     /// # use http::Uri;
687     /// let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
688     ///
689     /// assert_eq!(uri.query(), Some("key=value&foo=bar"));
690     /// ```
691     ///
692     /// Relative URI without a query string component
693     ///
694     /// ```
695     /// # use http::Uri;
696     /// let uri: Uri = "/hello/world".parse().unwrap();
697     ///
698     /// assert!(uri.query().is_none());
699     /// ```
700     #[inline]
query(&self) -> Option<&str>701     pub fn query(&self) -> Option<&str> {
702         self.path_and_query.query()
703     }
704 
has_path(&self) -> bool705     fn has_path(&self) -> bool {
706         !self.path_and_query.data.is_empty() || !self.scheme.inner.is_none()
707     }
708 }
709 
710 impl<'a> HttpTryFrom<&'a str> for Uri {
711     type Error = InvalidUri;
712 
713     #[inline]
try_from(t: &'a str) -> Result<Self, Self::Error>714     fn try_from(t: &'a str) -> Result<Self, Self::Error> {
715         t.parse()
716     }
717 }
718 
719 impl<'a> HttpTryFrom<&'a String> for Uri {
720     type Error = InvalidUri;
721 
722     #[inline]
try_from(t: &'a String) -> Result<Self, Self::Error>723     fn try_from(t: &'a String) -> Result<Self, Self::Error> {
724         t.parse()
725     }
726 }
727 
728 impl HttpTryFrom<String> for Uri {
729     type Error = InvalidUriBytes;
730 
731     #[inline]
try_from(t: String) -> Result<Self, Self::Error>732     fn try_from(t: String) -> Result<Self, Self::Error> {
733         Uri::from_shared(Bytes::from(t))
734     }
735 }
736 
737 impl HttpTryFrom<Bytes> for Uri {
738     type Error = InvalidUriBytes;
739 
740     #[inline]
try_from(t: Bytes) -> Result<Self, Self::Error>741     fn try_from(t: Bytes) -> Result<Self, Self::Error> {
742         Uri::from_shared(t)
743     }
744 }
745 
746 impl HttpTryFrom<Parts> for Uri {
747     type Error = InvalidUriParts;
748 
749     #[inline]
try_from(src: Parts) -> Result<Self, Self::Error>750     fn try_from(src: Parts) -> Result<Self, Self::Error> {
751         Uri::from_parts(src)
752     }
753 }
754 
755 impl<'a> HttpTryFrom<&'a Uri> for Uri {
756     type Error = ::Error;
757 
758     #[inline]
try_from(src: &'a Uri) -> Result<Self, Self::Error>759     fn try_from(src: &'a Uri) -> Result<Self, Self::Error> {
760         Ok(src.clone())
761     }
762 }
763 
764 /// Convert a `Uri` from parts
765 ///
766 /// # Examples
767 ///
768 /// Relative URI
769 ///
770 /// ```
771 /// # use http::uri::*;
772 /// let mut parts = Parts::default();
773 /// parts.path_and_query = Some("/foo".parse().unwrap());
774 ///
775 /// let uri = Uri::from_parts(parts).unwrap();
776 ///
777 /// assert_eq!(uri.path(), "/foo");
778 ///
779 /// assert!(uri.scheme_part().is_none());
780 /// assert!(uri.authority().is_none());
781 /// ```
782 ///
783 /// Absolute URI
784 ///
785 /// ```
786 /// # use http::uri::*;
787 /// let mut parts = Parts::default();
788 /// parts.scheme = Some("http".parse().unwrap());
789 /// parts.authority = Some("foo.com".parse().unwrap());
790 /// parts.path_and_query = Some("/foo".parse().unwrap());
791 ///
792 /// let uri = Uri::from_parts(parts).unwrap();
793 ///
794 /// assert_eq!(uri.scheme_part().unwrap().as_str(), "http");
795 /// assert_eq!(uri.authority().unwrap(), "foo.com");
796 /// assert_eq!(uri.path(), "/foo");
797 /// ```
798 impl From<Uri> for Parts {
from(src: Uri) -> Self799     fn from(src: Uri) -> Self {
800         let path_and_query = if src.has_path() {
801             Some(src.path_and_query)
802         } else {
803             None
804         };
805 
806         let scheme = match src.scheme.inner {
807             Scheme2::None => None,
808             _ => Some(src.scheme),
809         };
810 
811         let authority = if src.authority.data.is_empty() {
812             None
813         } else {
814             Some(src.authority)
815         };
816 
817         Parts {
818             scheme: scheme,
819             authority: authority,
820             path_and_query: path_and_query,
821             _priv: (),
822         }
823     }
824 }
825 
parse_full(mut s: Bytes) -> Result<Uri, InvalidUriBytes>826 fn parse_full(mut s: Bytes) -> Result<Uri, InvalidUriBytes> {
827     // Parse the scheme
828     let scheme = match Scheme2::parse(&s[..]).map_err(InvalidUriBytes)? {
829         Scheme2::None => Scheme2::None,
830         Scheme2::Standard(p) => {
831             // TODO: use truncate
832             let _ = s.split_to(p.len() + 3);
833             Scheme2::Standard(p)
834         }
835         Scheme2::Other(n) => {
836             // Grab the protocol
837             let mut scheme = s.split_to(n + 3);
838 
839             // Strip ://, TODO: truncate
840             let _ = scheme.split_off(n);
841 
842             // Allocate the ByteStr
843             let val = unsafe { ByteStr::from_utf8_unchecked(scheme) };
844 
845             Scheme2::Other(Box::new(val))
846         }
847     };
848 
849     // Find the end of the authority. The scheme will already have been
850     // extracted.
851     let authority_end = Authority::parse(&s[..]).map_err(InvalidUriBytes)?;
852 
853     if scheme.is_none() {
854         if authority_end != s.len() {
855             return Err(ErrorKind::InvalidFormat.into());
856         }
857 
858         let authority = Authority {
859             data: unsafe { ByteStr::from_utf8_unchecked(s) },
860         };
861 
862         return Ok(Uri {
863             scheme: scheme.into(),
864             authority: authority,
865             path_and_query: PathAndQuery::empty(),
866         });
867     }
868 
869     // Authority is required when absolute
870     if authority_end == 0 {
871         return Err(ErrorKind::InvalidFormat.into());
872     }
873 
874     let authority = s.split_to(authority_end);
875     let authority = Authority {
876         data: unsafe { ByteStr::from_utf8_unchecked(authority) },
877     };
878 
879     Ok(Uri {
880         scheme: scheme.into(),
881         authority: authority,
882         path_and_query: PathAndQuery::from_shared(s)?,
883     })
884 }
885 
886 impl FromStr for Uri {
887     type Err = InvalidUri;
888 
889     #[inline]
from_str(s: &str) -> Result<Uri, InvalidUri>890     fn from_str(s: &str) -> Result<Uri, InvalidUri> {
891         Uri::from_shared(s.into()).map_err(|e| e.0)
892     }
893 }
894 
895 impl PartialEq for Uri {
eq(&self, other: &Uri) -> bool896     fn eq(&self, other: &Uri) -> bool {
897         if self.scheme_part() != other.scheme_part() {
898             return false;
899         }
900 
901         if self.authority_part() != other.authority_part() {
902             return false;
903         }
904 
905         if self.path() != other.path() {
906             return false;
907         }
908 
909         if self.query() != other.query() {
910             return false;
911         }
912 
913         true
914     }
915 }
916 
917 impl PartialEq<str> for Uri {
eq(&self, other: &str) -> bool918     fn eq(&self, other: &str) -> bool {
919         let mut other = other.as_bytes();
920         let mut absolute = false;
921 
922         if let Some(scheme) = self.scheme_part() {
923             let scheme = scheme.as_str().as_bytes();
924             absolute = true;
925 
926             if other.len() < scheme.len() + 3 {
927                 return false;
928             }
929 
930             if !scheme.eq_ignore_ascii_case(&other[..scheme.len()]) {
931                 return false;
932             }
933 
934             other = &other[scheme.len()..];
935 
936             if &other[..3] != b"://" {
937                 return false;
938             }
939 
940             other = &other[3..];
941         }
942 
943         if let Some(auth) = self.authority_part() {
944             let len = auth.data.len();
945             absolute = true;
946 
947             if other.len() < len {
948                 return false;
949             }
950 
951             if !auth.data.as_bytes().eq_ignore_ascii_case(&other[..len]) {
952                 return false;
953             }
954 
955             other = &other[len..];
956         }
957 
958         let path = self.path();
959 
960         if other.len() < path.len() || path.as_bytes() != &other[..path.len()] {
961             if absolute && path == "/" {
962                 // PathAndQuery can be ommitted, fall through
963             } else {
964                 return false;
965             }
966         } else {
967             other = &other[path.len()..];
968         }
969 
970         if let Some(query) = self.query() {
971             if other.len() == 0 {
972                 return query.len() == 0;
973             }
974 
975             if other[0] != b'?' {
976                 return false;
977             }
978 
979             other = &other[1..];
980 
981             if other.len() < query.len() {
982                 return false;
983             }
984 
985             if query.as_bytes() != &other[..query.len()] {
986                 return false;
987             }
988 
989             other = &other[query.len()..];
990         }
991 
992         other.is_empty() || other[0] == b'#'
993     }
994 }
995 
996 impl PartialEq<Uri> for str {
eq(&self, uri: &Uri) -> bool997     fn eq(&self, uri: &Uri) -> bool {
998         uri == self
999     }
1000 }
1001 
1002 impl<'a> PartialEq<&'a str> for Uri {
eq(&self, other: & &'a str) -> bool1003     fn eq(&self, other: & &'a str) -> bool {
1004         self == *other
1005     }
1006 }
1007 
1008 impl<'a> PartialEq<Uri> for &'a str {
eq(&self, uri: &Uri) -> bool1009     fn eq(&self, uri: &Uri) -> bool {
1010         uri == *self
1011     }
1012 }
1013 
1014 impl Eq for Uri {}
1015 
1016 /// Returns a `Uri` representing `/`
1017 impl Default for Uri {
1018     #[inline]
default() -> Uri1019     fn default() -> Uri {
1020         Uri {
1021             scheme: Scheme::empty(),
1022             authority: Authority::empty(),
1023             path_and_query: PathAndQuery::slash(),
1024         }
1025     }
1026 }
1027 
1028 impl fmt::Display for Uri {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1029     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1030         if let Some(scheme) = self.scheme_part() {
1031             write!(f, "{}://", scheme)?;
1032         }
1033 
1034         if let Some(authority) = self.authority_part() {
1035             write!(f, "{}", authority)?;
1036         }
1037 
1038         write!(f, "{}", self.path())?;
1039 
1040         if let Some(query) = self.query() {
1041             write!(f, "?{}", query)?;
1042         }
1043 
1044         Ok(())
1045     }
1046 }
1047 
1048 impl fmt::Debug for Uri {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1049     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1050         fmt::Display::fmt(self, f)
1051     }
1052 }
1053 
1054 impl From<ErrorKind> for InvalidUri {
from(src: ErrorKind) -> InvalidUri1055     fn from(src: ErrorKind) -> InvalidUri {
1056         InvalidUri(src)
1057     }
1058 }
1059 
1060 impl From<ErrorKind> for InvalidUriBytes {
from(src: ErrorKind) -> InvalidUriBytes1061     fn from(src: ErrorKind) -> InvalidUriBytes {
1062         InvalidUriBytes(src.into())
1063     }
1064 }
1065 
1066 impl From<ErrorKind> for InvalidUriParts {
from(src: ErrorKind) -> InvalidUriParts1067     fn from(src: ErrorKind) -> InvalidUriParts {
1068         InvalidUriParts(src.into())
1069     }
1070 }
1071 
1072 impl fmt::Display for InvalidUri {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1073     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1074         self.description().fmt(f)
1075     }
1076 }
1077 
1078 impl Error for InvalidUri {
description(&self) -> &str1079     fn description(&self) -> &str {
1080         match self.0 {
1081             ErrorKind::InvalidUriChar => "invalid uri character",
1082             ErrorKind::InvalidScheme => "invalid scheme",
1083             ErrorKind::InvalidAuthority => "invalid authority",
1084             ErrorKind::InvalidPort => "invalid port",
1085             ErrorKind::InvalidFormat => "invalid format",
1086             ErrorKind::SchemeMissing => "scheme missing",
1087             ErrorKind::AuthorityMissing => "authority missing",
1088             ErrorKind::PathAndQueryMissing => "path missing",
1089             ErrorKind::TooLong => "uri too long",
1090             ErrorKind::Empty => "empty string",
1091             ErrorKind::SchemeTooLong => "scheme too long",
1092         }
1093     }
1094 }
1095 
1096 impl fmt::Display for InvalidUriBytes {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1097     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1098         self.0.fmt(f)
1099     }
1100 }
1101 
1102 impl fmt::Display for InvalidUriParts {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1103     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1104         self.0.fmt(f)
1105     }
1106 }
1107 
1108 impl Error for InvalidUriBytes {
description(&self) -> &str1109     fn description(&self) -> &str {
1110         self.0.description()
1111     }
1112 }
1113 
1114 impl Error for InvalidUriParts {
description(&self) -> &str1115     fn description(&self) -> &str {
1116         self.0.description()
1117     }
1118 }
1119 
1120 impl Hash for Uri {
hash<H>(&self, state: &mut H) where H: Hasher1121     fn hash<H>(&self, state: &mut H) where H: Hasher {
1122         if !self.scheme.inner.is_none() {
1123             self.scheme.hash(state);
1124             state.write_u8(0xff);
1125         }
1126 
1127         if let Some(auth) = self.authority_part() {
1128             auth.hash(state);
1129         }
1130 
1131         Hash::hash_slice(self.path().as_bytes(), state);
1132 
1133         if let Some(query) = self.query() {
1134             b'?'.hash(state);
1135             Hash::hash_slice(query.as_bytes(), state);
1136         }
1137     }
1138 }
1139