summaryrefslogtreecommitdiff
path: root/vendor/http/src/uri
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/http/src/uri')
-rw-r--r--vendor/http/src/uri/authority.rs684
-rw-r--r--vendor/http/src/uri/builder.rs211
-rw-r--r--vendor/http/src/uri/mod.rs1117
-rw-r--r--vendor/http/src/uri/path.rs604
-rw-r--r--vendor/http/src/uri/port.rs151
-rw-r--r--vendor/http/src/uri/scheme.rs361
-rw-r--r--vendor/http/src/uri/tests.rs519
7 files changed, 0 insertions, 3647 deletions
diff --git a/vendor/http/src/uri/authority.rs b/vendor/http/src/uri/authority.rs
deleted file mode 100644
index 07aa6795..00000000
--- a/vendor/http/src/uri/authority.rs
+++ /dev/null
@@ -1,684 +0,0 @@
-use std::convert::TryFrom;
-use std::hash::{Hash, Hasher};
-use std::str::FromStr;
-use std::{cmp, fmt, str};
-
-use bytes::Bytes;
-
-use super::{ErrorKind, InvalidUri, Port, URI_CHARS};
-use crate::byte_str::ByteStr;
-
-/// Represents the authority component of a URI.
-#[derive(Clone)]
-pub struct Authority {
- pub(super) data: ByteStr,
-}
-
-impl Authority {
- pub(super) fn empty() -> Self {
- Authority {
- data: ByteStr::new(),
- }
- }
-
- // Not public while `bytes` is unstable.
- pub(super) fn from_shared(s: Bytes) -> Result<Self, InvalidUri> {
- // Precondition on create_authority: trivially satisfied by the
- // identity closure
- create_authority(s, |s| s)
- }
-
- /// Attempt to convert an `Authority` from a static string.
- ///
- /// This function will not perform any copying, and the string will be
- /// checked if it is empty or contains an invalid character.
- ///
- /// # Panics
- ///
- /// This function panics if the argument contains invalid characters or
- /// is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::uri::Authority;
- /// let authority = Authority::from_static("example.com");
- /// assert_eq!(authority.host(), "example.com");
- /// ```
- pub fn from_static(src: &'static str) -> Self {
- Authority::from_shared(Bytes::from_static(src.as_bytes()))
- .expect("static str is not valid authority")
- }
-
- /// Attempt to convert a `Bytes` buffer to a `Authority`.
- ///
- /// This will try to prevent a copy if the type passed is the type used
- /// internally, and will copy the data if it is not.
- pub fn from_maybe_shared<T>(src: T) -> Result<Self, InvalidUri>
- where
- T: AsRef<[u8]> + 'static,
- {
- if_downcast_into!(T, Bytes, src, {
- return Authority::from_shared(src);
- });
-
- Authority::try_from(src.as_ref())
- }
-
- // Note: this may return an *empty* Authority. You might want `parse_non_empty`.
- // Postcondition: for all Ok() returns, s[..ret.unwrap()] is valid UTF-8 where
- // ret is the return value.
- pub(super) fn parse(s: &[u8]) -> Result<usize, InvalidUri> {
- let mut colon_cnt = 0u32;
- let mut start_bracket = false;
- let mut end_bracket = false;
- let mut has_percent = false;
- let mut end = s.len();
- let mut at_sign_pos = None;
- const MAX_COLONS: u32 = 8; // e.g., [FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80
-
- // Among other things, this loop checks that every byte in s up to the
- // first '/', '?', or '#' is a valid URI character (or in some contexts,
- // a '%'). This means that each such byte is a valid single-byte UTF-8
- // code point.
- for (i, &b) in s.iter().enumerate() {
- match URI_CHARS[b as usize] {
- b'/' | b'?' | b'#' => {
- end = i;
- break;
- }
- b':' => {
- if colon_cnt >= MAX_COLONS {
- return Err(ErrorKind::InvalidAuthority.into());
- }
- colon_cnt += 1;
- }
- b'[' => {
- if has_percent || start_bracket {
- // Something other than the userinfo has a `%`, so reject it.
- return Err(ErrorKind::InvalidAuthority.into());
- }
- start_bracket = true;
- }
- b']' => {
- if (!start_bracket) || end_bracket {
- return Err(ErrorKind::InvalidAuthority.into());
- }
- end_bracket = true;
-
- // Those were part of an IPv6 hostname, so forget them...
- colon_cnt = 0;
- has_percent = false;
- }
- b'@' => {
- at_sign_pos = Some(i);
-
- // Those weren't a port colon, but part of the
- // userinfo, so it needs to be forgotten.
- colon_cnt = 0;
- has_percent = false;
- }
- 0 if b == b'%' => {
- // Per https://tools.ietf.org/html/rfc3986#section-3.2.1 and
- // https://url.spec.whatwg.org/#authority-state
- // the userinfo can have a percent-encoded username and password,
- // so record that a `%` was found. If this turns out to be
- // part of the userinfo, this flag will be cleared.
- // Also per https://tools.ietf.org/html/rfc6874, percent-encoding can
- // be used to indicate a zone identifier.
- // If the flag hasn't been cleared at the end, that means this
- // was part of the hostname (and not part of an IPv6 address), and
- // will fail with an error.
- has_percent = true;
- }
- 0 => {
- return Err(ErrorKind::InvalidUriChar.into());
- }
- _ => {}
- }
- }
-
- if start_bracket ^ end_bracket {
- return Err(ErrorKind::InvalidAuthority.into());
- }
-
- if colon_cnt > 1 {
- // Things like 'localhost:8080:3030' are rejected.
- return Err(ErrorKind::InvalidAuthority.into());
- }
-
- if end > 0 && at_sign_pos == Some(end - 1) {
- // If there's nothing after an `@`, this is bonkers.
- return Err(ErrorKind::InvalidAuthority.into());
- }
-
- if has_percent {
- // Something after the userinfo has a `%`, so reject it.
- return Err(ErrorKind::InvalidAuthority.into());
- }
-
- Ok(end)
- }
-
- // Parse bytes as an Authority, not allowing an empty string.
- //
- // This should be used by functions that allow a user to parse
- // an `Authority` by itself.
- //
- // Postcondition: for all Ok() returns, s[..ret.unwrap()] is valid UTF-8 where
- // ret is the return value.
- fn parse_non_empty(s: &[u8]) -> Result<usize, InvalidUri> {
- if s.is_empty() {
- return Err(ErrorKind::Empty.into());
- }
- Authority::parse(s)
- }
-
- /// Get the host of this `Authority`.
- ///
- /// The host subcomponent of authority is identified by an IP literal
- /// encapsulated within square brackets, an IPv4 address in dotted- decimal
- /// form, or a registered name. The host subcomponent is **case-insensitive**.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |---------|
- /// |
- /// host
- /// ```
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::uri::*;
- /// let authority: Authority = "example.org:80".parse().unwrap();
- ///
- /// assert_eq!(authority.host(), "example.org");
- /// ```
- #[inline]
- pub fn host(&self) -> &str {
- host(self.as_str())
- }
-
- /// Get the port part of this `Authority`.
- ///
- /// The port subcomponent of authority is designated by an optional port
- /// number following the host and delimited from it by a single colon (":")
- /// character. It can be turned into a decimal port number with the `as_u16`
- /// method or as a `str` with the `as_str` method.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |-|
- /// |
- /// port
- /// ```
- ///
- /// # Examples
- ///
- /// Authority with port
- ///
- /// ```
- /// # use http::uri::Authority;
- /// let authority: Authority = "example.org:80".parse().unwrap();
- ///
- /// let port = authority.port().unwrap();
- /// assert_eq!(port.as_u16(), 80);
- /// assert_eq!(port.as_str(), "80");
- /// ```
- ///
- /// Authority without port
- ///
- /// ```
- /// # use http::uri::Authority;
- /// let authority: Authority = "example.org".parse().unwrap();
- ///
- /// assert!(authority.port().is_none());
- /// ```
- pub fn port(&self) -> Option<Port<&str>> {
- let bytes = self.as_str();
- bytes
- .rfind(':')
- .and_then(|i| Port::from_str(&bytes[i + 1..]).ok())
- }
-
- /// Get the port of this `Authority` as a `u16`.
- ///
- /// # Example
- ///
- /// ```
- /// # use http::uri::Authority;
- /// let authority: Authority = "example.org:80".parse().unwrap();
- ///
- /// assert_eq!(authority.port_u16(), Some(80));
- /// ```
- pub fn port_u16(&self) -> Option<u16> {
- self.port().map(|p| p.as_u16())
- }
-
- /// Return a str representation of the authority
- #[inline]
- pub fn as_str(&self) -> &str {
- &self.data[..]
- }
-}
-
-// Purposefully not public while `bytes` is unstable.
-// impl TryFrom<Bytes> for Authority
-
-impl AsRef<str> for Authority {
- fn as_ref(&self) -> &str {
- self.as_str()
- }
-}
-
-impl PartialEq for Authority {
- fn eq(&self, other: &Authority) -> bool {
- self.data.eq_ignore_ascii_case(&other.data)
- }
-}
-
-impl Eq for Authority {}
-
-/// Case-insensitive equality
-///
-/// # Examples
-///
-/// ```
-/// # use http::uri::Authority;
-/// let authority: Authority = "HELLO.com".parse().unwrap();
-/// assert_eq!(authority, "hello.coM");
-/// assert_eq!("hello.com", authority);
-/// ```
-impl PartialEq<str> for Authority {
- fn eq(&self, other: &str) -> bool {
- self.data.eq_ignore_ascii_case(other)
- }
-}
-
-impl PartialEq<Authority> for str {
- fn eq(&self, other: &Authority) -> bool {
- self.eq_ignore_ascii_case(other.as_str())
- }
-}
-
-impl<'a> PartialEq<Authority> for &'a str {
- fn eq(&self, other: &Authority) -> bool {
- self.eq_ignore_ascii_case(other.as_str())
- }
-}
-
-impl<'a> PartialEq<&'a str> for Authority {
- fn eq(&self, other: &&'a str) -> bool {
- self.data.eq_ignore_ascii_case(other)
- }
-}
-
-impl PartialEq<String> for Authority {
- fn eq(&self, other: &String) -> bool {
- self.data.eq_ignore_ascii_case(other.as_str())
- }
-}
-
-impl PartialEq<Authority> for String {
- fn eq(&self, other: &Authority) -> bool {
- self.as_str().eq_ignore_ascii_case(other.as_str())
- }
-}
-
-/// Case-insensitive ordering
-///
-/// # Examples
-///
-/// ```
-/// # use http::uri::Authority;
-/// let authority: Authority = "DEF.com".parse().unwrap();
-/// assert!(authority < "ghi.com");
-/// assert!(authority > "abc.com");
-/// ```
-impl PartialOrd for Authority {
- fn partial_cmp(&self, other: &Authority) -> Option<cmp::Ordering> {
- let left = self.data.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- let right = other.data.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- left.partial_cmp(right)
- }
-}
-
-impl PartialOrd<str> for Authority {
- fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
- let left = self.data.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- let right = other.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- left.partial_cmp(right)
- }
-}
-
-impl PartialOrd<Authority> for str {
- fn partial_cmp(&self, other: &Authority) -> Option<cmp::Ordering> {
- let left = self.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- let right = other.data.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- left.partial_cmp(right)
- }
-}
-
-impl<'a> PartialOrd<Authority> for &'a str {
- fn partial_cmp(&self, other: &Authority) -> Option<cmp::Ordering> {
- let left = self.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- let right = other.data.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- left.partial_cmp(right)
- }
-}
-
-impl<'a> PartialOrd<&'a str> for Authority {
- fn partial_cmp(&self, other: &&'a str) -> Option<cmp::Ordering> {
- let left = self.data.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- let right = other.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- left.partial_cmp(right)
- }
-}
-
-impl PartialOrd<String> for Authority {
- fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
- let left = self.data.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- let right = other.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- left.partial_cmp(right)
- }
-}
-
-impl PartialOrd<Authority> for String {
- fn partial_cmp(&self, other: &Authority) -> Option<cmp::Ordering> {
- let left = self.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- let right = other.data.as_bytes().iter().map(|b| b.to_ascii_lowercase());
- left.partial_cmp(right)
- }
-}
-
-/// Case-insensitive hashing
-///
-/// # Examples
-///
-/// ```
-/// # use http::uri::Authority;
-/// # use std::hash::{Hash, Hasher};
-/// # use std::collections::hash_map::DefaultHasher;
-///
-/// let a: Authority = "HELLO.com".parse().unwrap();
-/// let b: Authority = "hello.coM".parse().unwrap();
-///
-/// let mut s = DefaultHasher::new();
-/// a.hash(&mut s);
-/// let a = s.finish();
-///
-/// let mut s = DefaultHasher::new();
-/// b.hash(&mut s);
-/// let b = s.finish();
-///
-/// assert_eq!(a, b);
-/// ```
-impl Hash for Authority {
- fn hash<H>(&self, state: &mut H)
- where
- H: Hasher,
- {
- self.data.len().hash(state);
- for &b in self.data.as_bytes() {
- state.write_u8(b.to_ascii_lowercase());
- }
- }
-}
-
-impl<'a> TryFrom<&'a [u8]> for Authority {
- type Error = InvalidUri;
- #[inline]
- fn try_from(s: &'a [u8]) -> Result<Self, Self::Error> {
- // parse first, and only turn into Bytes if valid
-
- // Preconditon on create_authority: copy_from_slice() copies all of
- // bytes from the [u8] parameter into a new Bytes
- create_authority(s, Bytes::copy_from_slice)
- }
-}
-
-impl<'a> TryFrom<&'a str> for Authority {
- type Error = InvalidUri;
- #[inline]
- fn try_from(s: &'a str) -> Result<Self, Self::Error> {
- TryFrom::try_from(s.as_bytes())
- }
-}
-
-impl TryFrom<Vec<u8>> for Authority {
- type Error = InvalidUri;
-
- #[inline]
- fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
- Authority::from_shared(vec.into())
- }
-}
-
-impl TryFrom<String> for Authority {
- type Error = InvalidUri;
-
- #[inline]
- fn try_from(t: String) -> Result<Self, Self::Error> {
- Authority::from_shared(t.into())
- }
-}
-
-impl FromStr for Authority {
- type Err = InvalidUri;
-
- fn from_str(s: &str) -> Result<Self, InvalidUri> {
- TryFrom::try_from(s)
- }
-}
-
-impl fmt::Debug for Authority {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.as_str())
- }
-}
-
-impl fmt::Display for Authority {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.as_str())
- }
-}
-
-fn host(auth: &str) -> &str {
- let host_port = auth
- .rsplit('@')
- .next()
- .expect("split always has at least 1 item");
-
- if host_port.as_bytes()[0] == b'[' {
- let i = host_port
- .find(']')
- .expect("parsing should validate brackets");
- // ..= ranges aren't available in 1.20, our minimum Rust version...
- &host_port[0..i + 1]
- } else {
- host_port
- .split(':')
- .next()
- .expect("split always has at least 1 item")
- }
-}
-
-// Precondition: f converts all of the bytes in the passed in B into the
-// returned Bytes.
-fn create_authority<B, F>(b: B, f: F) -> Result<Authority, InvalidUri>
-where
- B: AsRef<[u8]>,
- F: FnOnce(B) -> Bytes,
-{
- let s = b.as_ref();
- let authority_end = Authority::parse_non_empty(s)?;
-
- if authority_end != s.len() {
- return Err(ErrorKind::InvalidUriChar.into());
- }
-
- let bytes = f(b);
-
- Ok(Authority {
- // Safety: the postcondition on parse_non_empty() and the check against
- // s.len() ensure that b is valid UTF-8. The precondition on f ensures
- // that this is carried through to bytes.
- data: unsafe { ByteStr::from_utf8_unchecked(bytes) },
- })
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn parse_empty_string_is_error() {
- let err = Authority::parse_non_empty(b"").unwrap_err();
- assert_eq!(err.0, ErrorKind::Empty);
- }
-
- #[test]
- fn equal_to_self_of_same_authority() {
- let authority1: Authority = "example.com".parse().unwrap();
- let authority2: Authority = "EXAMPLE.COM".parse().unwrap();
- assert_eq!(authority1, authority2);
- assert_eq!(authority2, authority1);
- }
-
- #[test]
- fn not_equal_to_self_of_different_authority() {
- let authority1: Authority = "example.com".parse().unwrap();
- let authority2: Authority = "test.com".parse().unwrap();
- assert_ne!(authority1, authority2);
- assert_ne!(authority2, authority1);
- }
-
- #[test]
- fn equates_with_a_str() {
- let authority: Authority = "example.com".parse().unwrap();
- assert_eq!(&authority, "EXAMPLE.com");
- assert_eq!("EXAMPLE.com", &authority);
- assert_eq!(authority, "EXAMPLE.com");
- assert_eq!("EXAMPLE.com", authority);
- }
-
- #[test]
- fn from_static_equates_with_a_str() {
- let authority = Authority::from_static("example.com");
- assert_eq!(authority, "example.com");
- }
-
- #[test]
- fn not_equal_with_a_str_of_a_different_authority() {
- let authority: Authority = "example.com".parse().unwrap();
- assert_ne!(&authority, "test.com");
- assert_ne!("test.com", &authority);
- assert_ne!(authority, "test.com");
- assert_ne!("test.com", authority);
- }
-
- #[test]
- fn equates_with_a_string() {
- let authority: Authority = "example.com".parse().unwrap();
- assert_eq!(authority, "EXAMPLE.com".to_string());
- assert_eq!("EXAMPLE.com".to_string(), authority);
- }
-
- #[test]
- fn equates_with_a_string_of_a_different_authority() {
- let authority: Authority = "example.com".parse().unwrap();
- assert_ne!(authority, "test.com".to_string());
- assert_ne!("test.com".to_string(), authority);
- }
-
- #[test]
- fn compares_to_self() {
- let authority1: Authority = "abc.com".parse().unwrap();
- let authority2: Authority = "def.com".parse().unwrap();
- assert!(authority1 < authority2);
- assert!(authority2 > authority1);
- }
-
- #[test]
- fn compares_with_a_str() {
- let authority: Authority = "def.com".parse().unwrap();
- // with ref
- assert!(&authority < "ghi.com");
- assert!("ghi.com" > &authority);
- assert!(&authority > "abc.com");
- assert!("abc.com" < &authority);
-
- // no ref
- assert!(authority < "ghi.com");
- assert!("ghi.com" > authority);
- assert!(authority > "abc.com");
- assert!("abc.com" < authority);
- }
-
- #[test]
- fn compares_with_a_string() {
- let authority: Authority = "def.com".parse().unwrap();
- assert!(authority < "ghi.com".to_string());
- assert!("ghi.com".to_string() > authority);
- assert!(authority > "abc.com".to_string());
- assert!("abc.com".to_string() < authority);
- }
-
- #[test]
- fn allows_percent_in_userinfo() {
- let authority_str = "a%2f:b%2f@example.com";
- let authority: Authority = authority_str.parse().unwrap();
- assert_eq!(authority, authority_str);
- }
-
- #[test]
- fn rejects_percent_in_hostname() {
- let err = Authority::parse_non_empty(b"example%2f.com").unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidAuthority);
-
- let err = Authority::parse_non_empty(b"a%2f:b%2f@example%2f.com").unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidAuthority);
- }
-
- #[test]
- fn allows_percent_in_ipv6_address() {
- let authority_str = "[fe80::1:2:3:4%25eth0]";
- let result: Authority = authority_str.parse().unwrap();
- assert_eq!(result, authority_str);
- }
-
- #[test]
- fn reject_obviously_invalid_ipv6_address() {
- let err = Authority::parse_non_empty(b"[0:1:2:3:4:5:6:7:8:9:10:11:12:13:14]").unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidAuthority);
- }
-
- #[test]
- fn rejects_percent_outside_ipv6_address() {
- let err = Authority::parse_non_empty(b"1234%20[fe80::1:2:3:4]").unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidAuthority);
-
- let err = Authority::parse_non_empty(b"[fe80::1:2:3:4]%20").unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidAuthority);
- }
-
- #[test]
- fn rejects_invalid_utf8() {
- let err = Authority::try_from([0xc0u8].as_ref()).unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidUriChar);
-
- let err = Authority::from_shared(Bytes::from_static([0xc0u8].as_ref())).unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidUriChar);
- }
-
- #[test]
- fn rejects_invalid_use_of_brackets() {
- let err = Authority::parse_non_empty(b"[]@[").unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidAuthority);
-
- // reject tie-fighter
- let err = Authority::parse_non_empty(b"]o[").unwrap_err();
- assert_eq!(err.0, ErrorKind::InvalidAuthority);
- }
-}
diff --git a/vendor/http/src/uri/builder.rs b/vendor/http/src/uri/builder.rs
deleted file mode 100644
index d5f7f49b..00000000
--- a/vendor/http/src/uri/builder.rs
+++ /dev/null
@@ -1,211 +0,0 @@
-use std::convert::TryInto;
-
-use super::{Authority, Parts, PathAndQuery, Scheme};
-use crate::Uri;
-
-/// A builder for `Uri`s.
-///
-/// This type can be used to construct an instance of `Uri`
-/// through a builder pattern.
-#[derive(Debug)]
-pub struct Builder {
- parts: Result<Parts, crate::Error>,
-}
-
-impl Builder {
- /// Creates a new default instance of `Builder` to construct a `Uri`.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::*;
- ///
- /// let uri = uri::Builder::new()
- /// .scheme("https")
- /// .authority("hyper.rs")
- /// .path_and_query("/")
- /// .build()
- /// .unwrap();
- /// ```
- #[inline]
- pub fn new() -> Builder {
- Builder::default()
- }
-
- /// Set the `Scheme` for this URI.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::*;
- ///
- /// let mut builder = uri::Builder::new();
- /// builder.scheme("https");
- /// ```
- pub fn scheme<T>(self, scheme: T) -> Self
- where
- T: TryInto<Scheme>,
- <T as TryInto<Scheme>>::Error: Into<crate::Error>,
- {
- self.map(move |mut parts| {
- let scheme = scheme.try_into().map_err(Into::into)?;
- parts.scheme = Some(scheme);
- Ok(parts)
- })
- }
-
- /// Set the `Authority` for this URI.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::*;
- ///
- /// let uri = uri::Builder::new()
- /// .authority("tokio.rs")
- /// .build()
- /// .unwrap();
- /// ```
- pub fn authority<T>(self, auth: T) -> Self
- where
- T: TryInto<Authority>,
- <T as TryInto<Authority>>::Error: Into<crate::Error>,
- {
- self.map(move |mut parts| {
- let auth = auth.try_into().map_err(Into::into)?;
- parts.authority = Some(auth);
- Ok(parts)
- })
- }
-
- /// Set the `PathAndQuery` for this URI.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::*;
- ///
- /// let uri = uri::Builder::new()
- /// .path_and_query("/hello?foo=bar")
- /// .build()
- /// .unwrap();
- /// ```
- pub fn path_and_query<T>(self, p_and_q: T) -> Self
- where
- T: TryInto<PathAndQuery>,
- <T as TryInto<PathAndQuery>>::Error: Into<crate::Error>,
- {
- self.map(move |mut parts| {
- let p_and_q = p_and_q.try_into().map_err(Into::into)?;
- parts.path_and_query = Some(p_and_q);
- Ok(parts)
- })
- }
-
- /// Consumes this builder, and tries to construct a valid `Uri` from
- /// the configured pieces.
- ///
- /// # Errors
- ///
- /// This function may return an error if any previously configured argument
- /// failed to parse or get converted to the internal representation. For
- /// example if an invalid `scheme` was specified via `scheme("!@#%/^")`
- /// the error will be returned when this function is called rather than
- /// when `scheme` was called.
- ///
- /// Additionally, the various forms of URI require certain combinations of
- /// parts to be set to be valid. If the parts don't fit into any of the
- /// valid forms of URI, a new error is returned.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::*;
- ///
- /// let uri = Uri::builder()
- /// .build()
- /// .unwrap();
- /// ```
- pub fn build(self) -> Result<Uri, crate::Error> {
- let parts = self.parts?;
- Uri::from_parts(parts).map_err(Into::into)
- }
-
- // private
-
- fn map<F>(self, func: F) -> Self
- where
- F: FnOnce(Parts) -> Result<Parts, crate::Error>,
- {
- Builder {
- parts: self.parts.and_then(func),
- }
- }
-}
-
-impl Default for Builder {
- #[inline]
- fn default() -> Builder {
- Builder {
- parts: Ok(Parts::default()),
- }
- }
-}
-
-impl From<Uri> for Builder {
- fn from(uri: Uri) -> Self {
- Self {
- parts: Ok(uri.into_parts()),
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn build_from_str() {
- let uri = Builder::new()
- .scheme(Scheme::HTTP)
- .authority("hyper.rs")
- .path_and_query("/foo?a=1")
- .build()
- .unwrap();
- assert_eq!(uri.scheme_str(), Some("http"));
- assert_eq!(uri.authority().unwrap().host(), "hyper.rs");
- assert_eq!(uri.path(), "/foo");
- assert_eq!(uri.query(), Some("a=1"));
- }
-
- #[test]
- fn build_from_string() {
- for i in 1..10 {
- let uri = Builder::new()
- .path_and_query(format!("/foo?a={}", i))
- .build()
- .unwrap();
- let expected_query = format!("a={}", i);
- assert_eq!(uri.path(), "/foo");
- assert_eq!(uri.query(), Some(expected_query.as_str()));
- }
- }
-
- #[test]
- fn build_from_string_ref() {
- for i in 1..10 {
- let p_a_q = format!("/foo?a={}", i);
- let uri = Builder::new().path_and_query(&p_a_q).build().unwrap();
- let expected_query = format!("a={}", i);
- assert_eq!(uri.path(), "/foo");
- assert_eq!(uri.query(), Some(expected_query.as_str()));
- }
- }
-
- #[test]
- fn build_from_uri() {
- let original_uri = Uri::default();
- let uri = Builder::from(original_uri.clone()).build().unwrap();
- assert_eq!(original_uri, uri);
- }
-}
diff --git a/vendor/http/src/uri/mod.rs b/vendor/http/src/uri/mod.rs
deleted file mode 100644
index 767f0743..00000000
--- a/vendor/http/src/uri/mod.rs
+++ /dev/null
@@ -1,1117 +0,0 @@
-//! URI component of request and response lines
-//!
-//! This module primarily contains the `Uri` type which is a component of all
-//! HTTP requests and also reexports this type at the root of the crate. A URI
-//! is not always a "full URL" in the sense of something you'd type into a web
-//! browser, but HTTP requests may only have paths on servers but may have full
-//! schemes and hostnames on clients.
-//!
-//! # Examples
-//!
-//! ```
-//! use http::Uri;
-//!
-//! let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
-//! assert_eq!(uri.path(), "/foo/bar");
-//! assert_eq!(uri.query(), Some("baz"));
-//! assert_eq!(uri.host(), None);
-//!
-//! let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
-//! assert_eq!(uri.scheme_str(), Some("https"));
-//! assert_eq!(uri.host(), Some("www.rust-lang.org"));
-//! assert_eq!(uri.path(), "/install.html");
-//! ```
-
-use crate::byte_str::ByteStr;
-use std::convert::TryFrom;
-
-use bytes::Bytes;
-
-use std::error::Error;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::str::{self, FromStr};
-
-use self::scheme::Scheme2;
-
-pub use self::authority::Authority;
-pub use self::builder::Builder;
-pub use self::path::PathAndQuery;
-pub use self::port::Port;
-pub use self::scheme::Scheme;
-
-mod authority;
-mod builder;
-mod path;
-mod port;
-mod scheme;
-#[cfg(test)]
-mod tests;
-
-/// The URI component of a request.
-///
-/// For HTTP 1, this is included as part of the request line. From Section 5.3,
-/// Request Target:
-///
-/// > Once an inbound connection is obtained, the client sends an HTTP
-/// > request message (Section 3) with a request-target derived from the
-/// > target URI. There are four distinct formats for the request-target,
-/// > depending on both the method being requested and whether the request
-/// > is to a proxy.
-/// >
-/// > ```notrust
-/// > request-target = origin-form
-/// > / absolute-form
-/// > / authority-form
-/// > / asterisk-form
-/// > ```
-///
-/// The URI is structured as follows:
-///
-/// ```notrust
-/// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
-/// |-| |-------------------------------||--------| |-------------------| |-----|
-/// | | | | |
-/// scheme authority path query fragment
-/// ```
-///
-/// For HTTP 2.0, the URI is encoded using pseudoheaders.
-///
-/// # Examples
-///
-/// ```
-/// use http::Uri;
-///
-/// let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
-/// assert_eq!(uri.path(), "/foo/bar");
-/// assert_eq!(uri.query(), Some("baz"));
-/// assert_eq!(uri.host(), None);
-///
-/// let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
-/// assert_eq!(uri.scheme_str(), Some("https"));
-/// assert_eq!(uri.host(), Some("www.rust-lang.org"));
-/// assert_eq!(uri.path(), "/install.html");
-/// ```
-#[derive(Clone)]
-pub struct Uri {
- scheme: Scheme,
- authority: Authority,
- path_and_query: PathAndQuery,
-}
-
-/// The various parts of a URI.
-///
-/// This struct is used to provide to and retrieve from a URI.
-#[derive(Debug, Default)]
-pub struct Parts {
- /// The scheme component of a URI
- pub scheme: Option<Scheme>,
-
- /// The authority component of a URI
- pub authority: Option<Authority>,
-
- /// The origin-form component of a URI
- pub path_and_query: Option<PathAndQuery>,
-
- /// Allow extending in the future
- _priv: (),
-}
-
-/// An error resulting from a failed attempt to construct a URI.
-#[derive(Debug)]
-pub struct InvalidUri(ErrorKind);
-
-/// An error resulting from a failed attempt to construct a URI.
-#[derive(Debug)]
-pub struct InvalidUriParts(InvalidUri);
-
-#[derive(Debug, Eq, PartialEq)]
-enum ErrorKind {
- InvalidUriChar,
- InvalidScheme,
- InvalidAuthority,
- InvalidPort,
- InvalidFormat,
- SchemeMissing,
- AuthorityMissing,
- PathAndQueryMissing,
- TooLong,
- Empty,
- SchemeTooLong,
-}
-
-// u16::MAX is reserved for None
-const MAX_LEN: usize = (u16::MAX - 1) as usize;
-
-// URI_CHARS is a table of valid characters in a URI. An entry in the table is
-// 0 for invalid characters. For valid characters the entry is itself (i.e.
-// the entry for 33 is b'!' because b'!' == 33u8). An important characteristic
-// of this table is that all entries above 127 are invalid. This makes all of the
-// valid entries a valid single-byte UTF-8 code point. This means that a slice
-// of such valid entries is valid UTF-8.
-#[rustfmt::skip]
-const URI_CHARS: [u8; 256] = [
- // 0 1 2 3 4 5 6 7 8 9
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 0, 0, 0, b'!', 0, b'#', b'$', 0, b'&', b'\'', // 3x
- b'(', b')', b'*', b'+', b',', b'-', b'.', b'/', b'0', b'1', // 4x
- b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b':', b';', // 5x
- 0, b'=', 0, b'?', b'@', b'A', b'B', b'C', b'D', b'E', // 6x
- b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', // 7x
- b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', // 8x
- b'Z', b'[', 0, b']', 0, b'_', 0, b'a', b'b', b'c', // 9x
- b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x
- b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x
- b'x', b'y', b'z', 0, 0, 0, b'~', 0, 0, 0, // 12x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 18x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 19x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 22x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24x
- 0, 0, 0, 0, 0, 0 // 25x
-];
-
-impl Uri {
- /// Creates a new builder-style object to manufacture a `Uri`.
- ///
- /// This method returns an instance of `Builder` which can be usd to
- /// create a `Uri`.
- ///
- /// # Examples
- ///
- /// ```
- /// use http::Uri;
- ///
- /// let uri = Uri::builder()
- /// .scheme("https")
- /// .authority("hyper.rs")
- /// .path_and_query("/")
- /// .build()
- /// .unwrap();
- /// ```
- pub fn builder() -> Builder {
- Builder::new()
- }
-
- /// Attempt to convert a `Parts` into a `Uri`.
- ///
- /// # Examples
- ///
- /// Relative URI
- ///
- /// ```
- /// # use http::uri::*;
- /// let mut parts = Parts::default();
- /// parts.path_and_query = Some("/foo".parse().unwrap());
- ///
- /// let uri = Uri::from_parts(parts).unwrap();
- ///
- /// assert_eq!(uri.path(), "/foo");
- ///
- /// assert!(uri.scheme().is_none());
- /// assert!(uri.authority().is_none());
- /// ```
- ///
- /// Absolute URI
- ///
- /// ```
- /// # use http::uri::*;
- /// let mut parts = Parts::default();
- /// parts.scheme = Some("http".parse().unwrap());
- /// parts.authority = Some("foo.com".parse().unwrap());
- /// parts.path_and_query = Some("/foo".parse().unwrap());
- ///
- /// let uri = Uri::from_parts(parts).unwrap();
- ///
- /// assert_eq!(uri.scheme().unwrap().as_str(), "http");
- /// assert_eq!(uri.authority().unwrap(), "foo.com");
- /// assert_eq!(uri.path(), "/foo");
- /// ```
- pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts> {
- if src.scheme.is_some() {
- if src.authority.is_none() {
- return Err(ErrorKind::AuthorityMissing.into());
- }
-
- if src.path_and_query.is_none() {
- return Err(ErrorKind::PathAndQueryMissing.into());
- }
- } else if src.authority.is_some() && src.path_and_query.is_some() {
- return Err(ErrorKind::SchemeMissing.into());
- }
-
- let scheme = match src.scheme {
- Some(scheme) => scheme,
- None => Scheme {
- inner: Scheme2::None,
- },
- };
-
- let authority = match src.authority {
- Some(authority) => authority,
- None => Authority::empty(),
- };
-
- let path_and_query = match src.path_and_query {
- Some(path_and_query) => path_and_query,
- None => PathAndQuery::empty(),
- };
-
- Ok(Uri {
- scheme,
- authority,
- path_and_query,
- })
- }
-
- /// Attempt to convert a `Bytes` buffer to a `Uri`.
- ///
- /// This will try to prevent a copy if the type passed is the type used
- /// internally, and will copy the data if it is not.
- pub fn from_maybe_shared<T>(src: T) -> Result<Self, InvalidUri>
- where
- T: AsRef<[u8]> + 'static,
- {
- if_downcast_into!(T, Bytes, src, {
- return Uri::from_shared(src);
- });
-
- Uri::try_from(src.as_ref())
- }
-
- // Not public while `bytes` is unstable.
- fn from_shared(s: Bytes) -> Result<Uri, InvalidUri> {
- use self::ErrorKind::*;
-
- if s.len() > MAX_LEN {
- return Err(TooLong.into());
- }
-
- match s.len() {
- 0 => {
- return Err(Empty.into());
- }
- 1 => match s[0] {
- b'/' => {
- return Ok(Uri {
- scheme: Scheme::empty(),
- authority: Authority::empty(),
- path_and_query: PathAndQuery::slash(),
- });
- }
- b'*' => {
- return Ok(Uri {
- scheme: Scheme::empty(),
- authority: Authority::empty(),
- path_and_query: PathAndQuery::star(),
- });
- }
- _ => {
- let authority = Authority::from_shared(s)?;
-
- return Ok(Uri {
- scheme: Scheme::empty(),
- authority,
- path_and_query: PathAndQuery::empty(),
- });
- }
- },
- _ => {}
- }
-
- if s[0] == b'/' {
- return Ok(Uri {
- scheme: Scheme::empty(),
- authority: Authority::empty(),
- path_and_query: PathAndQuery::from_shared(s)?,
- });
- }
-
- parse_full(s)
- }
-
- /// Convert a `Uri` from a static string.
- ///
- /// This function will not perform any copying, however the string is
- /// checked to ensure that it is valid.
- ///
- /// # Panics
- ///
- /// This function panics if the argument is an invalid URI.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::uri::Uri;
- /// let uri = Uri::from_static("http://example.com/foo");
- ///
- /// assert_eq!(uri.host().unwrap(), "example.com");
- /// assert_eq!(uri.path(), "/foo");
- /// ```
- pub fn from_static(src: &'static str) -> Self {
- let s = Bytes::from_static(src.as_bytes());
- match Uri::from_shared(s) {
- Ok(uri) => uri,
- Err(e) => panic!("static str is not valid URI: {}", e),
- }
- }
-
- /// Convert a `Uri` into `Parts`.
- ///
- /// # Note
- ///
- /// This is just an inherent method providing the same functionality as
- /// `let parts: Parts = uri.into()`
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::uri::*;
- /// let uri: Uri = "/foo".parse().unwrap();
- ///
- /// let parts = uri.into_parts();
- ///
- /// assert_eq!(parts.path_and_query.unwrap(), "/foo");
- ///
- /// assert!(parts.scheme.is_none());
- /// assert!(parts.authority.is_none());
- /// ```
- #[inline]
- pub fn into_parts(self) -> Parts {
- self.into()
- }
-
- /// Returns the path & query components of the Uri
- #[inline]
- pub fn path_and_query(&self) -> Option<&PathAndQuery> {
- if !self.scheme.inner.is_none() || self.authority.data.is_empty() {
- Some(&self.path_and_query)
- } else {
- None
- }
- }
-
- /// Get the path of this `Uri`.
- ///
- /// Both relative and absolute URIs contain a path component, though it
- /// might be the empty string. The path component is **case sensitive**.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |--------|
- /// |
- /// path
- /// ```
- ///
- /// If the URI is `*` then the path component is equal to `*`.
- ///
- /// # Examples
- ///
- /// A relative URI
- ///
- /// ```
- /// # use http::Uri;
- ///
- /// let uri: Uri = "/hello/world".parse().unwrap();
- ///
- /// assert_eq!(uri.path(), "/hello/world");
- /// ```
- ///
- /// An absolute URI
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
- ///
- /// assert_eq!(uri.path(), "/hello/world");
- /// ```
- #[inline]
- pub fn path(&self) -> &str {
- if self.has_path() {
- self.path_and_query.path()
- } else {
- ""
- }
- }
-
- /// Get the scheme of this `Uri`.
- ///
- /// The URI scheme refers to a specification for assigning identifiers
- /// within that scheme. Only absolute URIs contain a scheme component, but
- /// not all absolute URIs will contain a scheme component. Although scheme
- /// names are case-insensitive, the canonical form is lowercase.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |-|
- /// |
- /// scheme
- /// ```
- ///
- /// # Examples
- ///
- /// Absolute URI
- ///
- /// ```
- /// use http::uri::{Scheme, Uri};
- ///
- /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
- ///
- /// assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
- /// ```
- ///
- ///
- /// Relative URI
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "/hello/world".parse().unwrap();
- ///
- /// assert!(uri.scheme().is_none());
- /// ```
- #[inline]
- pub fn scheme(&self) -> Option<&Scheme> {
- if self.scheme.inner.is_none() {
- None
- } else {
- Some(&self.scheme)
- }
- }
-
- /// Get the scheme of this `Uri` as a `&str`.
- ///
- /// # Example
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
- ///
- /// assert_eq!(uri.scheme_str(), Some("http"));
- /// ```
- #[inline]
- pub fn scheme_str(&self) -> Option<&str> {
- if self.scheme.inner.is_none() {
- None
- } else {
- Some(self.scheme.as_str())
- }
- }
-
- /// Get the authority of this `Uri`.
- ///
- /// The authority is a hierarchical element for naming authority such that
- /// the remainder of the URI is delegated to that authority. For HTTP, the
- /// authority consists of the host and port. The host portion of the
- /// authority is **case-insensitive**.
- ///
- /// The authority also includes a `username:password` component, however
- /// the use of this is deprecated and should be avoided.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |-------------------------------|
- /// |
- /// authority
- /// ```
- ///
- /// # Examples
- ///
- /// Absolute URI
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
- ///
- /// assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
- /// ```
- ///
- ///
- /// Relative URI
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "/hello/world".parse().unwrap();
- ///
- /// assert!(uri.authority().is_none());
- /// ```
- #[inline]
- pub fn authority(&self) -> Option<&Authority> {
- if self.authority.data.is_empty() {
- None
- } else {
- Some(&self.authority)
- }
- }
-
- /// Get the host of this `Uri`.
- ///
- /// The host subcomponent of authority is identified by an IP literal
- /// encapsulated within square brackets, an IPv4 address in dotted- decimal
- /// form, or a registered name. The host subcomponent is **case-insensitive**.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |---------|
- /// |
- /// host
- /// ```
- ///
- /// # Examples
- ///
- /// Absolute URI
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
- ///
- /// assert_eq!(uri.host(), Some("example.org"));
- /// ```
- ///
- ///
- /// Relative URI
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "/hello/world".parse().unwrap();
- ///
- /// assert!(uri.host().is_none());
- /// ```
- #[inline]
- pub fn host(&self) -> Option<&str> {
- self.authority().map(|a| a.host())
- }
-
- /// Get the port part of this `Uri`.
- ///
- /// The port subcomponent of authority is designated by an optional port
- /// number following the host and delimited from it by a single colon (":")
- /// character. It can be turned into a decimal port number with the `as_u16`
- /// method or as a `str` with the `as_str` method.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |-|
- /// |
- /// port
- /// ```
- ///
- /// # Examples
- ///
- /// Absolute URI with port
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
- ///
- /// let port = uri.port().unwrap();
- /// assert_eq!(port.as_u16(), 80);
- /// ```
- ///
- /// Absolute URI without port
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
- ///
- /// assert!(uri.port().is_none());
- /// ```
- ///
- /// Relative URI
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "/hello/world".parse().unwrap();
- ///
- /// assert!(uri.port().is_none());
- /// ```
- pub fn port(&self) -> Option<Port<&str>> {
- self.authority().and_then(|a| a.port())
- }
-
- /// Get the port of this `Uri` as a `u16`.
- ///
- ///
- /// # Example
- ///
- /// ```
- /// # use http::{Uri, uri::Port};
- /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
- ///
- /// assert_eq!(uri.port_u16(), Some(80));
- /// ```
- pub fn port_u16(&self) -> Option<u16> {
- self.port().map(|p| p.as_u16())
- }
-
- /// Get the query string of this `Uri`, starting after the `?`.
- ///
- /// The query component contains non-hierarchical data that, along with data
- /// in the path component, serves to identify a resource within the scope of
- /// the URI's scheme and naming authority (if any). The query component is
- /// indicated by the first question mark ("?") character and terminated by a
- /// number sign ("#") character or by the end of the URI.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |-------------------|
- /// |
- /// query
- /// ```
- ///
- /// # Examples
- ///
- /// Absolute URI
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
- ///
- /// assert_eq!(uri.query(), Some("key=value"));
- /// ```
- ///
- /// Relative URI with a query string component
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
- ///
- /// assert_eq!(uri.query(), Some("key=value&foo=bar"));
- /// ```
- ///
- /// Relative URI without a query string component
- ///
- /// ```
- /// # use http::Uri;
- /// let uri: Uri = "/hello/world".parse().unwrap();
- ///
- /// assert!(uri.query().is_none());
- /// ```
- #[inline]
- pub fn query(&self) -> Option<&str> {
- self.path_and_query.query()
- }
-
- fn has_path(&self) -> bool {
- !self.path_and_query.data.is_empty() || !self.scheme.inner.is_none()
- }
-}
-
-impl<'a> TryFrom<&'a [u8]> for Uri {
- type Error = InvalidUri;
-
- #[inline]
- fn try_from(t: &'a [u8]) -> Result<Self, Self::Error> {
- Uri::from_shared(Bytes::copy_from_slice(t))
- }
-}
-
-impl<'a> TryFrom<&'a str> for Uri {
- type Error = InvalidUri;
-
- #[inline]
- fn try_from(t: &'a str) -> Result<Self, Self::Error> {
- t.parse()
- }
-}
-
-impl<'a> TryFrom<&'a String> for Uri {
- type Error = InvalidUri;
-
- #[inline]
- fn try_from(t: &'a String) -> Result<Self, Self::Error> {
- t.parse()
- }
-}
-
-impl TryFrom<String> for Uri {
- type Error = InvalidUri;
-
- #[inline]
- fn try_from(t: String) -> Result<Self, Self::Error> {
- Uri::from_shared(Bytes::from(t))
- }
-}
-
-impl TryFrom<Vec<u8>> for Uri {
- type Error = InvalidUri;
-
- #[inline]
- fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
- Uri::from_shared(Bytes::from(vec))
- }
-}
-
-impl TryFrom<Parts> for Uri {
- type Error = InvalidUriParts;
-
- #[inline]
- fn try_from(src: Parts) -> Result<Self, Self::Error> {
- Uri::from_parts(src)
- }
-}
-
-impl<'a> TryFrom<&'a Uri> for Uri {
- type Error = crate::Error;
-
- #[inline]
- fn try_from(src: &'a Uri) -> Result<Self, Self::Error> {
- Ok(src.clone())
- }
-}
-
-/// Convert an `Authority` into a `Uri`.
-impl From<Authority> for Uri {
- fn from(authority: Authority) -> Self {
- Self {
- scheme: Scheme::empty(),
- authority,
- path_and_query: PathAndQuery::empty(),
- }
- }
-}
-
-/// Convert a `PathAndQuery` into a `Uri`.
-impl From<PathAndQuery> for Uri {
- fn from(path_and_query: PathAndQuery) -> Self {
- Self {
- scheme: Scheme::empty(),
- authority: Authority::empty(),
- path_and_query,
- }
- }
-}
-
-/// Convert a `Uri` into `Parts`
-impl From<Uri> for Parts {
- fn from(src: Uri) -> Self {
- let path_and_query = if src.has_path() {
- Some(src.path_and_query)
- } else {
- None
- };
-
- let scheme = match src.scheme.inner {
- Scheme2::None => None,
- _ => Some(src.scheme),
- };
-
- let authority = if src.authority.data.is_empty() {
- None
- } else {
- Some(src.authority)
- };
-
- Parts {
- scheme,
- authority,
- path_and_query,
- _priv: (),
- }
- }
-}
-
-fn parse_full(mut s: Bytes) -> Result<Uri, InvalidUri> {
- // Parse the scheme
- let scheme = match Scheme2::parse(&s[..])? {
- Scheme2::None => Scheme2::None,
- Scheme2::Standard(p) => {
- // TODO: use truncate
- let _ = s.split_to(p.len() + 3);
- Scheme2::Standard(p)
- }
- Scheme2::Other(n) => {
- // Grab the protocol
- let mut scheme = s.split_to(n + 3);
-
- // Strip ://, TODO: truncate
- let _ = scheme.split_off(n);
-
- // Allocate the ByteStr
- let val = unsafe { ByteStr::from_utf8_unchecked(scheme) };
-
- Scheme2::Other(Box::new(val))
- }
- };
-
- // Find the end of the authority. The scheme will already have been
- // extracted.
- let authority_end = Authority::parse(&s[..])?;
-
- if scheme.is_none() {
- if authority_end != s.len() {
- return Err(ErrorKind::InvalidFormat.into());
- }
-
- let authority = Authority {
- data: unsafe { ByteStr::from_utf8_unchecked(s) },
- };
-
- return Ok(Uri {
- scheme: scheme.into(),
- authority,
- path_and_query: PathAndQuery::empty(),
- });
- }
-
- // Authority is required when absolute
- if authority_end == 0 {
- return Err(ErrorKind::InvalidFormat.into());
- }
-
- let authority = s.split_to(authority_end);
- let authority = Authority {
- data: unsafe { ByteStr::from_utf8_unchecked(authority) },
- };
-
- Ok(Uri {
- scheme: scheme.into(),
- authority,
- path_and_query: PathAndQuery::from_shared(s)?,
- })
-}
-
-impl FromStr for Uri {
- type Err = InvalidUri;
-
- #[inline]
- fn from_str(s: &str) -> Result<Uri, InvalidUri> {
- Uri::try_from(s.as_bytes())
- }
-}
-
-impl PartialEq for Uri {
- fn eq(&self, other: &Uri) -> bool {
- if self.scheme() != other.scheme() {
- return false;
- }
-
- if self.authority() != other.authority() {
- return false;
- }
-
- if self.path() != other.path() {
- return false;
- }
-
- if self.query() != other.query() {
- return false;
- }
-
- true
- }
-}
-
-impl PartialEq<str> for Uri {
- fn eq(&self, other: &str) -> bool {
- let mut other = other.as_bytes();
- let mut absolute = false;
-
- if let Some(scheme) = self.scheme() {
- let scheme = scheme.as_str().as_bytes();
- absolute = true;
-
- if other.len() < scheme.len() + 3 {
- return false;
- }
-
- if !scheme.eq_ignore_ascii_case(&other[..scheme.len()]) {
- return false;
- }
-
- other = &other[scheme.len()..];
-
- if &other[..3] != b"://" {
- return false;
- }
-
- other = &other[3..];
- }
-
- if let Some(auth) = self.authority() {
- let len = auth.data.len();
- absolute = true;
-
- if other.len() < len {
- return false;
- }
-
- if !auth.data.as_bytes().eq_ignore_ascii_case(&other[..len]) {
- return false;
- }
-
- other = &other[len..];
- }
-
- let path = self.path();
-
- if other.len() < path.len() || path.as_bytes() != &other[..path.len()] {
- if absolute && path == "/" {
- // PathAndQuery can be omitted, fall through
- } else {
- return false;
- }
- } else {
- other = &other[path.len()..];
- }
-
- if let Some(query) = self.query() {
- if other.is_empty() {
- return query.is_empty();
- }
-
- if other[0] != b'?' {
- return false;
- }
-
- other = &other[1..];
-
- if other.len() < query.len() {
- return false;
- }
-
- if query.as_bytes() != &other[..query.len()] {
- return false;
- }
-
- other = &other[query.len()..];
- }
-
- other.is_empty() || other[0] == b'#'
- }
-}
-
-impl PartialEq<Uri> for str {
- fn eq(&self, uri: &Uri) -> bool {
- uri == self
- }
-}
-
-impl<'a> PartialEq<&'a str> for Uri {
- fn eq(&self, other: &&'a str) -> bool {
- self == *other
- }
-}
-
-impl<'a> PartialEq<Uri> for &'a str {
- fn eq(&self, uri: &Uri) -> bool {
- uri == *self
- }
-}
-
-impl Eq for Uri {}
-
-/// Returns a `Uri` representing `/`
-impl Default for Uri {
- #[inline]
- fn default() -> Uri {
- Uri {
- scheme: Scheme::empty(),
- authority: Authority::empty(),
- path_and_query: PathAndQuery::slash(),
- }
- }
-}
-
-impl fmt::Display for Uri {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- if let Some(scheme) = self.scheme() {
- write!(f, "{}://", scheme)?;
- }
-
- if let Some(authority) = self.authority() {
- write!(f, "{}", authority)?;
- }
-
- write!(f, "{}", self.path())?;
-
- if let Some(query) = self.query() {
- write!(f, "?{}", query)?;
- }
-
- Ok(())
- }
-}
-
-impl fmt::Debug for Uri {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(self, f)
- }
-}
-
-impl From<ErrorKind> for InvalidUri {
- fn from(src: ErrorKind) -> InvalidUri {
- InvalidUri(src)
- }
-}
-
-impl From<ErrorKind> for InvalidUriParts {
- fn from(src: ErrorKind) -> InvalidUriParts {
- InvalidUriParts(src.into())
- }
-}
-
-impl InvalidUri {
- fn s(&self) -> &str {
- match self.0 {
- ErrorKind::InvalidUriChar => "invalid uri character",
- ErrorKind::InvalidScheme => "invalid scheme",
- ErrorKind::InvalidAuthority => "invalid authority",
- ErrorKind::InvalidPort => "invalid port",
- ErrorKind::InvalidFormat => "invalid format",
- ErrorKind::SchemeMissing => "scheme missing",
- ErrorKind::AuthorityMissing => "authority missing",
- ErrorKind::PathAndQueryMissing => "path missing",
- ErrorKind::TooLong => "uri too long",
- ErrorKind::Empty => "empty string",
- ErrorKind::SchemeTooLong => "scheme too long",
- }
- }
-}
-
-impl fmt::Display for InvalidUri {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.s().fmt(f)
- }
-}
-
-impl Error for InvalidUri {}
-
-impl fmt::Display for InvalidUriParts {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl Error for InvalidUriParts {}
-
-impl Hash for Uri {
- fn hash<H>(&self, state: &mut H)
- where
- H: Hasher,
- {
- if !self.scheme.inner.is_none() {
- self.scheme.hash(state);
- state.write_u8(0xff);
- }
-
- if let Some(auth) = self.authority() {
- auth.hash(state);
- }
-
- Hash::hash_slice(self.path().as_bytes(), state);
-
- if let Some(query) = self.query() {
- b'?'.hash(state);
- Hash::hash_slice(query.as_bytes(), state);
- }
- }
-}
diff --git a/vendor/http/src/uri/path.rs b/vendor/http/src/uri/path.rs
deleted file mode 100644
index 42db1f92..00000000
--- a/vendor/http/src/uri/path.rs
+++ /dev/null
@@ -1,604 +0,0 @@
-use std::convert::TryFrom;
-use std::str::FromStr;
-use std::{cmp, fmt, hash, str};
-
-use bytes::Bytes;
-
-use super::{ErrorKind, InvalidUri};
-use crate::byte_str::ByteStr;
-
-/// Represents the path component of a URI
-#[derive(Clone)]
-pub struct PathAndQuery {
- pub(super) data: ByteStr,
- pub(super) query: u16,
-}
-
-const NONE: u16 = u16::MAX;
-
-impl PathAndQuery {
- // Not public while `bytes` is unstable.
- pub(super) fn from_shared(mut src: Bytes) -> Result<Self, InvalidUri> {
- let mut query = NONE;
- let mut fragment = None;
-
- let mut is_maybe_not_utf8 = false;
-
- // block for iterator borrow
- {
- let mut iter = src.as_ref().iter().enumerate();
-
- // path ...
- for (i, &b) in &mut iter {
- // See https://url.spec.whatwg.org/#path-state
- match b {
- b'?' => {
- debug_assert_eq!(query, NONE);
- query = i as u16;
- break;
- }
- b'#' => {
- fragment = Some(i);
- break;
- }
-
- // This is the range of bytes that don't need to be
- // percent-encoded in the path. If it should have been
- // percent-encoded, then error.
- #[rustfmt::skip]
- 0x21 |
- 0x24..=0x3B |
- 0x3D |
- 0x40..=0x5F |
- 0x61..=0x7A |
- 0x7C |
- 0x7E => {}
-
- // potentially utf8, might not, should check
- 0x7F..=0xFF => {
- is_maybe_not_utf8 = true;
- }
-
- // These are code points that are supposed to be
- // percent-encoded in the path but there are clients
- // out there sending them as is and httparse accepts
- // to parse those requests, so they are allowed here
- // for parity.
- //
- // For reference, those are code points that are used
- // to send requests with JSON directly embedded in
- // the URI path. Yes, those things happen for real.
- #[rustfmt::skip]
- b'"' |
- b'{' | b'}' => {}
-
- _ => return Err(ErrorKind::InvalidUriChar.into()),
- }
- }
-
- // query ...
- if query != NONE {
- for (i, &b) in iter {
- match b {
- // While queries *should* be percent-encoded, most
- // bytes are actually allowed...
- // See https://url.spec.whatwg.org/#query-state
- //
- // Allowed: 0x21 / 0x24 - 0x3B / 0x3D / 0x3F - 0x7E
- #[rustfmt::skip]
- 0x21 |
- 0x24..=0x3B |
- 0x3D |
- 0x3F..=0x7E => {}
-
- 0x7F..=0xFF => {
- is_maybe_not_utf8 = true;
- }
-
- b'#' => {
- fragment = Some(i);
- break;
- }
-
- _ => return Err(ErrorKind::InvalidUriChar.into()),
- }
- }
- }
- }
-
- if let Some(i) = fragment {
- src.truncate(i);
- }
-
- let data = if is_maybe_not_utf8 {
- ByteStr::from_utf8(src).map_err(|_| ErrorKind::InvalidUriChar)?
- } else {
- unsafe { ByteStr::from_utf8_unchecked(src) }
- };
-
- Ok(PathAndQuery { data, query })
- }
-
- /// Convert a `PathAndQuery` from a static string.
- ///
- /// This function will not perform any copying, however the string is
- /// checked to ensure that it is valid.
- ///
- /// # Panics
- ///
- /// This function panics if the argument is an invalid path and query.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::uri::*;
- /// let v = PathAndQuery::from_static("/hello?world");
- ///
- /// assert_eq!(v.path(), "/hello");
- /// assert_eq!(v.query(), Some("world"));
- /// ```
- #[inline]
- pub fn from_static(src: &'static str) -> Self {
- let src = Bytes::from_static(src.as_bytes());
-
- PathAndQuery::from_shared(src).unwrap()
- }
-
- /// Attempt to convert a `Bytes` buffer to a `PathAndQuery`.
- ///
- /// This will try to prevent a copy if the type passed is the type used
- /// internally, and will copy the data if it is not.
- pub fn from_maybe_shared<T>(src: T) -> Result<Self, InvalidUri>
- where
- T: AsRef<[u8]> + 'static,
- {
- if_downcast_into!(T, Bytes, src, {
- return PathAndQuery::from_shared(src);
- });
-
- PathAndQuery::try_from(src.as_ref())
- }
-
- pub(super) fn empty() -> Self {
- PathAndQuery {
- data: ByteStr::new(),
- query: NONE,
- }
- }
-
- pub(super) fn slash() -> Self {
- PathAndQuery {
- data: ByteStr::from_static("/"),
- query: NONE,
- }
- }
-
- pub(super) fn star() -> Self {
- PathAndQuery {
- data: ByteStr::from_static("*"),
- query: NONE,
- }
- }
-
- /// Returns the path component
- ///
- /// The path component is **case sensitive**.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |--------|
- /// |
- /// path
- /// ```
- ///
- /// If the URI is `*` then the path component is equal to `*`.
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::uri::*;
- ///
- /// let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
- ///
- /// assert_eq!(path_and_query.path(), "/hello/world");
- /// ```
- #[inline]
- pub fn path(&self) -> &str {
- let ret = if self.query == NONE {
- &self.data[..]
- } else {
- &self.data[..self.query as usize]
- };
-
- if ret.is_empty() {
- return "/";
- }
-
- ret
- }
-
- /// Returns the query string component
- ///
- /// The query component contains non-hierarchical data that, along with data
- /// in the path component, serves to identify a resource within the scope of
- /// the URI's scheme and naming authority (if any). The query component is
- /// indicated by the first question mark ("?") character and terminated by a
- /// number sign ("#") character or by the end of the URI.
- ///
- /// ```notrust
- /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
- /// |-------------------|
- /// |
- /// query
- /// ```
- ///
- /// # Examples
- ///
- /// With a query string component
- ///
- /// ```
- /// # use http::uri::*;
- /// let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap();
- ///
- /// assert_eq!(path_and_query.query(), Some("key=value&foo=bar"));
- /// ```
- ///
- /// Without a query string component
- ///
- /// ```
- /// # use http::uri::*;
- /// let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
- ///
- /// assert!(path_and_query.query().is_none());
- /// ```
- #[inline]
- pub fn query(&self) -> Option<&str> {
- if self.query == NONE {
- None
- } else {
- let i = self.query + 1;
- Some(&self.data[i as usize..])
- }
- }
-
- /// Returns the path and query as a string component.
- ///
- /// # Examples
- ///
- /// With a query string component
- ///
- /// ```
- /// # use http::uri::*;
- /// let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap();
- ///
- /// assert_eq!(path_and_query.as_str(), "/hello/world?key=value&foo=bar");
- /// ```
- ///
- /// Without a query string component
- ///
- /// ```
- /// # use http::uri::*;
- /// let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
- ///
- /// assert_eq!(path_and_query.as_str(), "/hello/world");
- /// ```
- #[inline]
- pub fn as_str(&self) -> &str {
- let ret = &self.data[..];
- if ret.is_empty() {
- return "/";
- }
- ret
- }
-}
-
-impl<'a> TryFrom<&'a [u8]> for PathAndQuery {
- type Error = InvalidUri;
- #[inline]
- fn try_from(s: &'a [u8]) -> Result<Self, Self::Error> {
- PathAndQuery::from_shared(Bytes::copy_from_slice(s))
- }
-}
-
-impl<'a> TryFrom<&'a str> for PathAndQuery {
- type Error = InvalidUri;
- #[inline]
- fn try_from(s: &'a str) -> Result<Self, Self::Error> {
- TryFrom::try_from(s.as_bytes())
- }
-}
-
-impl TryFrom<Vec<u8>> for PathAndQuery {
- type Error = InvalidUri;
- #[inline]
- fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
- PathAndQuery::from_shared(vec.into())
- }
-}
-
-impl TryFrom<String> for PathAndQuery {
- type Error = InvalidUri;
- #[inline]
- fn try_from(s: String) -> Result<Self, Self::Error> {
- PathAndQuery::from_shared(s.into())
- }
-}
-
-impl TryFrom<&String> for PathAndQuery {
- type Error = InvalidUri;
- #[inline]
- fn try_from(s: &String) -> Result<Self, Self::Error> {
- TryFrom::try_from(s.as_bytes())
- }
-}
-
-impl FromStr for PathAndQuery {
- type Err = InvalidUri;
- #[inline]
- fn from_str(s: &str) -> Result<Self, InvalidUri> {
- TryFrom::try_from(s)
- }
-}
-
-impl fmt::Debug for PathAndQuery {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(self, f)
- }
-}
-
-impl fmt::Display for PathAndQuery {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- if !self.data.is_empty() {
- match self.data.as_bytes()[0] {
- b'/' | b'*' => write!(fmt, "{}", &self.data[..]),
- _ => write!(fmt, "/{}", &self.data[..]),
- }
- } else {
- write!(fmt, "/")
- }
- }
-}
-
-impl hash::Hash for PathAndQuery {
- fn hash<H: hash::Hasher>(&self, state: &mut H) {
- self.data.hash(state);
- }
-}
-
-// ===== PartialEq / PartialOrd =====
-
-impl PartialEq for PathAndQuery {
- #[inline]
- fn eq(&self, other: &PathAndQuery) -> bool {
- self.data == other.data
- }
-}
-
-impl Eq for PathAndQuery {}
-
-impl PartialEq<str> for PathAndQuery {
- #[inline]
- fn eq(&self, other: &str) -> bool {
- self.as_str() == other
- }
-}
-
-impl<'a> PartialEq<PathAndQuery> for &'a str {
- #[inline]
- fn eq(&self, other: &PathAndQuery) -> bool {
- self == &other.as_str()
- }
-}
-
-impl<'a> PartialEq<&'a str> for PathAndQuery {
- #[inline]
- fn eq(&self, other: &&'a str) -> bool {
- self.as_str() == *other
- }
-}
-
-impl PartialEq<PathAndQuery> for str {
- #[inline]
- fn eq(&self, other: &PathAndQuery) -> bool {
- self == other.as_str()
- }
-}
-
-impl PartialEq<String> for PathAndQuery {
- #[inline]
- fn eq(&self, other: &String) -> bool {
- self.as_str() == other.as_str()
- }
-}
-
-impl PartialEq<PathAndQuery> for String {
- #[inline]
- fn eq(&self, other: &PathAndQuery) -> bool {
- self.as_str() == other.as_str()
- }
-}
-
-impl PartialOrd for PathAndQuery {
- #[inline]
- fn partial_cmp(&self, other: &PathAndQuery) -> Option<cmp::Ordering> {
- self.as_str().partial_cmp(other.as_str())
- }
-}
-
-impl PartialOrd<str> for PathAndQuery {
- #[inline]
- fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
- self.as_str().partial_cmp(other)
- }
-}
-
-impl PartialOrd<PathAndQuery> for str {
- #[inline]
- fn partial_cmp(&self, other: &PathAndQuery) -> Option<cmp::Ordering> {
- self.partial_cmp(other.as_str())
- }
-}
-
-impl<'a> PartialOrd<&'a str> for PathAndQuery {
- #[inline]
- fn partial_cmp(&self, other: &&'a str) -> Option<cmp::Ordering> {
- self.as_str().partial_cmp(*other)
- }
-}
-
-impl<'a> PartialOrd<PathAndQuery> for &'a str {
- #[inline]
- fn partial_cmp(&self, other: &PathAndQuery) -> Option<cmp::Ordering> {
- self.partial_cmp(&other.as_str())
- }
-}
-
-impl PartialOrd<String> for PathAndQuery {
- #[inline]
- fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
- self.as_str().partial_cmp(other.as_str())
- }
-}
-
-impl PartialOrd<PathAndQuery> for String {
- #[inline]
- fn partial_cmp(&self, other: &PathAndQuery) -> Option<cmp::Ordering> {
- self.as_str().partial_cmp(other.as_str())
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn equal_to_self_of_same_path() {
- let p1: PathAndQuery = "/hello/world&foo=bar".parse().unwrap();
- let p2: PathAndQuery = "/hello/world&foo=bar".parse().unwrap();
- assert_eq!(p1, p2);
- assert_eq!(p2, p1);
- }
-
- #[test]
- fn not_equal_to_self_of_different_path() {
- let p1: PathAndQuery = "/hello/world&foo=bar".parse().unwrap();
- let p2: PathAndQuery = "/world&foo=bar".parse().unwrap();
- assert_ne!(p1, p2);
- assert_ne!(p2, p1);
- }
-
- #[test]
- fn equates_with_a_str() {
- let path_and_query: PathAndQuery = "/hello/world&foo=bar".parse().unwrap();
- assert_eq!(&path_and_query, "/hello/world&foo=bar");
- assert_eq!("/hello/world&foo=bar", &path_and_query);
- assert_eq!(path_and_query, "/hello/world&foo=bar");
- assert_eq!("/hello/world&foo=bar", path_and_query);
- }
-
- #[test]
- fn not_equal_with_a_str_of_a_different_path() {
- let path_and_query: PathAndQuery = "/hello/world&foo=bar".parse().unwrap();
- // as a reference
- assert_ne!(&path_and_query, "/hello&foo=bar");
- assert_ne!("/hello&foo=bar", &path_and_query);
- // without reference
- assert_ne!(path_and_query, "/hello&foo=bar");
- assert_ne!("/hello&foo=bar", path_and_query);
- }
-
- #[test]
- fn equates_with_a_string() {
- let path_and_query: PathAndQuery = "/hello/world&foo=bar".parse().unwrap();
- assert_eq!(path_and_query, "/hello/world&foo=bar".to_string());
- assert_eq!("/hello/world&foo=bar".to_string(), path_and_query);
- }
-
- #[test]
- fn not_equal_with_a_string_of_a_different_path() {
- let path_and_query: PathAndQuery = "/hello/world&foo=bar".parse().unwrap();
- assert_ne!(path_and_query, "/hello&foo=bar".to_string());
- assert_ne!("/hello&foo=bar".to_string(), path_and_query);
- }
-
- #[test]
- fn compares_to_self() {
- let p1: PathAndQuery = "/a/world&foo=bar".parse().unwrap();
- let p2: PathAndQuery = "/b/world&foo=bar".parse().unwrap();
- assert!(p1 < p2);
- assert!(p2 > p1);
- }
-
- #[test]
- fn compares_with_a_str() {
- let path_and_query: PathAndQuery = "/b/world&foo=bar".parse().unwrap();
- // by ref
- assert!(&path_and_query < "/c/world&foo=bar");
- assert!("/c/world&foo=bar" > &path_and_query);
- assert!(&path_and_query > "/a/world&foo=bar");
- assert!("/a/world&foo=bar" < &path_and_query);
-
- // by val
- assert!(path_and_query < "/c/world&foo=bar");
- assert!("/c/world&foo=bar" > path_and_query);
- assert!(path_and_query > "/a/world&foo=bar");
- assert!("/a/world&foo=bar" < path_and_query);
- }
-
- #[test]
- fn compares_with_a_string() {
- let path_and_query: PathAndQuery = "/b/world&foo=bar".parse().unwrap();
- assert!(path_and_query < "/c/world&foo=bar".to_string());
- assert!("/c/world&foo=bar".to_string() > path_and_query);
- assert!(path_and_query > "/a/world&foo=bar".to_string());
- assert!("/a/world&foo=bar".to_string() < path_and_query);
- }
-
- #[test]
- fn ignores_valid_percent_encodings() {
- assert_eq!("/a%20b", pq("/a%20b?r=1").path());
- assert_eq!("qr=%31", pq("/a/b?qr=%31").query().unwrap());
- }
-
- #[test]
- fn ignores_invalid_percent_encodings() {
- assert_eq!("/a%%b", pq("/a%%b?r=1").path());
- assert_eq!("/aaa%", pq("/aaa%").path());
- assert_eq!("/aaa%", pq("/aaa%?r=1").path());
- assert_eq!("/aa%2", pq("/aa%2").path());
- assert_eq!("/aa%2", pq("/aa%2?r=1").path());
- assert_eq!("qr=%3", pq("/a/b?qr=%3").query().unwrap());
- }
-
- #[test]
- fn allow_utf8_in_path() {
- assert_eq!("/🍕", pq("/🍕").path());
- }
-
- #[test]
- fn allow_utf8_in_query() {
- assert_eq!(Some("pizza=🍕"), pq("/test?pizza=🍕").query());
- }
-
- #[test]
- fn rejects_invalid_utf8_in_path() {
- PathAndQuery::try_from(&[b'/', 0xFF][..]).expect_err("reject invalid utf8");
- }
-
- #[test]
- fn rejects_invalid_utf8_in_query() {
- PathAndQuery::try_from(&[b'/', b'a', b'?', 0xFF][..]).expect_err("reject invalid utf8");
- }
-
- #[test]
- fn json_is_fine() {
- assert_eq!(
- r#"/{"bread":"baguette"}"#,
- pq(r#"/{"bread":"baguette"}"#).path()
- );
- }
-
- fn pq(s: &str) -> PathAndQuery {
- s.parse().expect(&format!("parsing {}", s))
- }
-}
diff --git a/vendor/http/src/uri/port.rs b/vendor/http/src/uri/port.rs
deleted file mode 100644
index 2a7028e2..00000000
--- a/vendor/http/src/uri/port.rs
+++ /dev/null
@@ -1,151 +0,0 @@
-use std::fmt;
-
-use super::{ErrorKind, InvalidUri};
-
-/// The port component of a URI.
-pub struct Port<T> {
- port: u16,
- repr: T,
-}
-
-impl<T> Port<T> {
- /// Returns the port number as a `u16`.
- ///
- /// # Examples
- ///
- /// Port as `u16`.
- ///
- /// ```
- /// # use http::uri::Authority;
- /// let authority: Authority = "example.org:80".parse().unwrap();
- ///
- /// let port = authority.port().unwrap();
- /// assert_eq!(port.as_u16(), 80);
- /// ```
- pub const fn as_u16(&self) -> u16 {
- self.port
- }
-}
-
-impl<T> Port<T>
-where
- T: AsRef<str>,
-{
- /// Converts a `str` to a port number.
- ///
- /// The supplied `str` must be a valid u16.
- pub(crate) fn from_str(bytes: T) -> Result<Self, InvalidUri> {
- bytes
- .as_ref()
- .parse::<u16>()
- .map(|port| Port { port, repr: bytes })
- .map_err(|_| ErrorKind::InvalidPort.into())
- }
-
- /// Returns the port number as a `str`.
- ///
- /// # Examples
- ///
- /// Port as `str`.
- ///
- /// ```
- /// # use http::uri::Authority;
- /// let authority: Authority = "example.org:80".parse().unwrap();
- ///
- /// let port = authority.port().unwrap();
- /// assert_eq!(port.as_str(), "80");
- /// ```
- pub fn as_str(&self) -> &str {
- self.repr.as_ref()
- }
-}
-
-impl<T> fmt::Debug for Port<T>
-where
- T: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_tuple("Port").field(&self.port).finish()
- }
-}
-
-impl<T> fmt::Display for Port<T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // Use `u16::fmt` so that it respects any formatting flags that
- // may have been set (like padding, align, etc).
- fmt::Display::fmt(&self.port, f)
- }
-}
-
-impl<T> From<Port<T>> for u16 {
- fn from(port: Port<T>) -> Self {
- port.as_u16()
- }
-}
-
-impl<T> AsRef<str> for Port<T>
-where
- T: AsRef<str>,
-{
- fn as_ref(&self) -> &str {
- self.as_str()
- }
-}
-
-impl<T, U> PartialEq<Port<U>> for Port<T> {
- fn eq(&self, other: &Port<U>) -> bool {
- self.port == other.port
- }
-}
-
-impl<T> PartialEq<u16> for Port<T> {
- fn eq(&self, other: &u16) -> bool {
- self.port == *other
- }
-}
-
-impl<T> PartialEq<Port<T>> for u16 {
- fn eq(&self, other: &Port<T>) -> bool {
- other.port == *self
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn partialeq_port() {
- let port_a = Port::from_str("8080").unwrap();
- let port_b = Port::from_str("8080").unwrap();
- assert_eq!(port_a, port_b);
- }
-
- #[test]
- fn partialeq_port_different_reprs() {
- let port_a = Port {
- repr: "8081",
- port: 8081,
- };
- let port_b = Port {
- repr: String::from("8081"),
- port: 8081,
- };
- assert_eq!(port_a, port_b);
- assert_eq!(port_b, port_a);
- }
-
- #[test]
- fn partialeq_u16() {
- let port = Port::from_str("8080").unwrap();
- // test equals in both directions
- assert_eq!(port, 8080);
- assert_eq!(8080, port);
- }
-
- #[test]
- fn u16_from_port() {
- let port = Port::from_str("8080").unwrap();
- assert_eq!(8080, u16::from(port));
- }
-}
diff --git a/vendor/http/src/uri/scheme.rs b/vendor/http/src/uri/scheme.rs
deleted file mode 100644
index dbcc8c3f..00000000
--- a/vendor/http/src/uri/scheme.rs
+++ /dev/null
@@ -1,361 +0,0 @@
-use std::convert::TryFrom;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::str::FromStr;
-
-use bytes::Bytes;
-
-use super::{ErrorKind, InvalidUri};
-use crate::byte_str::ByteStr;
-
-/// Represents the scheme component of a URI
-#[derive(Clone)]
-pub struct Scheme {
- pub(super) inner: Scheme2,
-}
-
-#[derive(Clone, Debug)]
-pub(super) enum Scheme2<T = Box<ByteStr>> {
- None,
- Standard(Protocol),
- Other(T),
-}
-
-#[derive(Copy, Clone, Debug)]
-pub(super) enum Protocol {
- Http,
- Https,
-}
-
-impl Scheme {
- /// HTTP protocol scheme
- pub const HTTP: Scheme = Scheme {
- inner: Scheme2::Standard(Protocol::Http),
- };
-
- /// HTTP protocol over TLS.
- pub const HTTPS: Scheme = Scheme {
- inner: Scheme2::Standard(Protocol::Https),
- };
-
- pub(super) fn empty() -> Self {
- Scheme {
- inner: Scheme2::None,
- }
- }
-
- /// Return a str representation of the scheme
- ///
- /// # Examples
- ///
- /// ```
- /// # use http::uri::*;
- /// let scheme: Scheme = "http".parse().unwrap();
- /// assert_eq!(scheme.as_str(), "http");
- /// ```
- #[inline]
- pub fn as_str(&self) -> &str {
- use self::Protocol::*;
- use self::Scheme2::*;
-
- match self.inner {
- Standard(Http) => "http",
- Standard(Https) => "https",
- Other(ref v) => &v[..],
- None => unreachable!(),
- }
- }
-}
-
-impl<'a> TryFrom<&'a [u8]> for Scheme {
- type Error = InvalidUri;
- #[inline]
- fn try_from(s: &'a [u8]) -> Result<Self, Self::Error> {
- use self::Scheme2::*;
-
- match Scheme2::parse_exact(s)? {
- None => Err(ErrorKind::InvalidScheme.into()),
- Standard(p) => Ok(Standard(p).into()),
- Other(_) => {
- let bytes = Bytes::copy_from_slice(s);
-
- // Safety: postcondition on parse_exact() means that s and
- // hence bytes are valid UTF-8.
- let string = unsafe { ByteStr::from_utf8_unchecked(bytes) };
-
- Ok(Other(Box::new(string)).into())
- }
- }
- }
-}
-
-impl<'a> TryFrom<&'a str> for Scheme {
- type Error = InvalidUri;
- #[inline]
- fn try_from(s: &'a str) -> Result<Self, Self::Error> {
- TryFrom::try_from(s.as_bytes())
- }
-}
-
-impl FromStr for Scheme {
- type Err = InvalidUri;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- TryFrom::try_from(s)
- }
-}
-
-impl fmt::Debug for Scheme {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Debug::fmt(self.as_str(), f)
- }
-}
-
-impl fmt::Display for Scheme {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(self.as_str())
- }
-}
-
-impl AsRef<str> for Scheme {
- #[inline]
- fn as_ref(&self) -> &str {
- self.as_str()
- }
-}
-
-impl PartialEq for Scheme {
- fn eq(&self, other: &Scheme) -> bool {
- use self::Protocol::*;
- use self::Scheme2::*;
-
- match (&self.inner, &other.inner) {
- (&Standard(Http), &Standard(Http)) => true,
- (&Standard(Https), &Standard(Https)) => true,
- (Other(a), Other(b)) => a.eq_ignore_ascii_case(b),
- (&None, _) | (_, &None) => unreachable!(),
- _ => false,
- }
- }
-}
-
-impl Eq for Scheme {}
-
-/// Case-insensitive equality
-///
-/// # Examples
-///
-/// ```
-/// # use http::uri::Scheme;
-/// let scheme: Scheme = "HTTP".parse().unwrap();
-/// assert_eq!(scheme, *"http");
-/// ```
-impl PartialEq<str> for Scheme {
- fn eq(&self, other: &str) -> bool {
- self.as_str().eq_ignore_ascii_case(other)
- }
-}
-
-/// Case-insensitive equality
-impl PartialEq<Scheme> for str {
- fn eq(&self, other: &Scheme) -> bool {
- other == self
- }
-}
-
-/// Case-insensitive hashing
-impl Hash for Scheme {
- fn hash<H>(&self, state: &mut H)
- where
- H: Hasher,
- {
- match self.inner {
- Scheme2::None => (),
- Scheme2::Standard(Protocol::Http) => state.write_u8(1),
- Scheme2::Standard(Protocol::Https) => state.write_u8(2),
- Scheme2::Other(ref other) => {
- other.len().hash(state);
- for &b in other.as_bytes() {
- state.write_u8(b.to_ascii_lowercase());
- }
- }
- }
- }
-}
-
-impl<T> Scheme2<T> {
- pub(super) fn is_none(&self) -> bool {
- matches!(*self, Scheme2::None)
- }
-}
-
-// Require the scheme to not be too long in order to enable further
-// optimizations later.
-const MAX_SCHEME_LEN: usize = 64;
-
-// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-//
-// SCHEME_CHARS is a table of valid characters in the scheme part of a URI. An
-// entry in the table is 0 for invalid characters. For valid characters the
-// entry is itself (i.e. the entry for 43 is b'+' because b'+' == 43u8). An
-// important characteristic of this table is that all entries above 127 are
-// invalid. This makes all of the valid entries a valid single-byte UTF-8 code
-// point. This means that a slice of such valid entries is valid UTF-8.
-#[rustfmt::skip]
-const SCHEME_CHARS: [u8; 256] = [
- // 0 1 2 3 4 5 6 7 8 9
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3x
- 0, 0, 0, b'+', 0, b'-', b'.', 0, b'0', b'1', // 4x
- b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b':', 0, // 5x
- 0, 0, 0, 0, 0, b'A', b'B', b'C', b'D', b'E', // 6x
- b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', // 7x
- b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', // 8x
- b'Z', 0, 0, 0, 0, 0, 0, b'a', b'b', b'c', // 9x
- b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x
- b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x
- b'x', b'y', b'z', 0, 0, 0, b'~', 0, 0, 0, // 12x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 18x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 19x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 22x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24x
- 0, 0, 0, 0, 0, 0 // 25x
-];
-
-impl Scheme2<usize> {
- // Postcondition: On all Ok() returns, s is valid UTF-8
- fn parse_exact(s: &[u8]) -> Result<Scheme2<()>, InvalidUri> {
- match s {
- b"http" => Ok(Protocol::Http.into()),
- b"https" => Ok(Protocol::Https.into()),
- _ => {
- if s.len() > MAX_SCHEME_LEN {
- return Err(ErrorKind::SchemeTooLong.into());
- }
-
- // check that each byte in s is a SCHEME_CHARS which implies
- // that it is a valid single byte UTF-8 code point.
- for &b in s {
- match SCHEME_CHARS[b as usize] {
- b':' => {
- // Don't want :// here
- return Err(ErrorKind::InvalidScheme.into());
- }
- 0 => {
- return Err(ErrorKind::InvalidScheme.into());
- }
- _ => {}
- }
- }
-
- Ok(Scheme2::Other(()))
- }
- }
- }
-
- pub(super) fn parse(s: &[u8]) -> Result<Scheme2<usize>, InvalidUri> {
- if s.len() >= 7 {
- // Check for HTTP
- if s[..7].eq_ignore_ascii_case(b"http://") {
- // Prefix will be striped
- return Ok(Protocol::Http.into());
- }
- }
-
- if s.len() >= 8 {
- // Check for HTTPs
- if s[..8].eq_ignore_ascii_case(b"https://") {
- return Ok(Protocol::Https.into());
- }
- }
-
- if s.len() > 3 {
- for i in 0..s.len() {
- let b = s[i];
-
- match SCHEME_CHARS[b as usize] {
- b':' => {
- // Not enough data remaining
- if s.len() < i + 3 {
- break;
- }
-
- // Not a scheme
- if &s[i + 1..i + 3] != b"//" {
- break;
- }
-
- if i > MAX_SCHEME_LEN {
- return Err(ErrorKind::SchemeTooLong.into());
- }
-
- // Return scheme
- return Ok(Scheme2::Other(i));
- }
- // Invalid scheme character, abort
- 0 => break,
- _ => {}
- }
- }
- }
-
- Ok(Scheme2::None)
- }
-}
-
-impl Protocol {
- pub(super) fn len(&self) -> usize {
- match *self {
- Protocol::Http => 4,
- Protocol::Https => 5,
- }
- }
-}
-
-impl<T> From<Protocol> for Scheme2<T> {
- fn from(src: Protocol) -> Self {
- Scheme2::Standard(src)
- }
-}
-
-#[doc(hidden)]
-impl From<Scheme2> for Scheme {
- fn from(src: Scheme2) -> Self {
- Scheme { inner: src }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn scheme_eq_to_str() {
- assert_eq!(&scheme("http"), "http");
- assert_eq!(&scheme("https"), "https");
- assert_eq!(&scheme("ftp"), "ftp");
- assert_eq!(&scheme("my+funky+scheme"), "my+funky+scheme");
- }
-
- #[test]
- fn invalid_scheme_is_error() {
- Scheme::try_from("my_funky_scheme").expect_err("Unexpectedly valid Scheme");
-
- // Invalid UTF-8
- Scheme::try_from([0xC0].as_ref()).expect_err("Unexpectedly valid Scheme");
- }
-
- fn scheme(s: &str) -> Scheme {
- s.parse().expect(&format!("Invalid scheme: {}", s))
- }
-}
diff --git a/vendor/http/src/uri/tests.rs b/vendor/http/src/uri/tests.rs
deleted file mode 100644
index 719cb94e..00000000
--- a/vendor/http/src/uri/tests.rs
+++ /dev/null
@@ -1,519 +0,0 @@
-use std::str::FromStr;
-
-use super::{ErrorKind, InvalidUri, Port, Uri, URI_CHARS};
-
-#[test]
-fn test_char_table() {
- for (i, &v) in URI_CHARS.iter().enumerate() {
- if v != 0 {
- assert_eq!(i, v as usize);
- }
- }
-}
-
-macro_rules! part {
- ($s:expr) => {
- Some(&$s.parse().unwrap())
- };
-}
-
-macro_rules! test_parse {
- (
- $test_name:ident,
- $str:expr,
- $alt:expr,
- $($method:ident = $value:expr,)*
- ) => (
- #[test]
- fn $test_name() {
- let orig_str = $str;
- let uri = match Uri::from_str(orig_str) {
- Ok(uri) => uri,
- Err(err) => {
- panic!("parse error {:?} from {:?}", err, orig_str);
- },
- };
- $(
- assert_eq!(uri.$method(), $value, "{}: uri = {:?}", stringify!($method), uri);
- )+
- assert_eq!(uri, orig_str, "partial eq to original str");
- assert_eq!(uri, uri.clone(), "clones are equal");
-
- let new_str = uri.to_string();
- let new_uri = Uri::from_str(&new_str).expect("to_string output parses again as a Uri");
- assert_eq!(new_uri, orig_str, "round trip still equals original str");
-
- const ALT: &'static [&'static str] = &$alt;
-
- for &alt in ALT.iter() {
- let other: Uri = alt.parse().unwrap();
- assert_eq!(uri, *alt);
- assert_eq!(uri, other);
- }
- }
- );
-}
-
-test_parse! {
- test_uri_parse_path_and_query,
- "/some/path/here?and=then&hello#and-bye",
- [],
-
- scheme = None,
- authority = None,
- path = "/some/path/here",
- query = Some("and=then&hello"),
- host = None,
-}
-
-test_parse! {
- test_uri_parse_absolute_form,
- "http://127.0.0.1:61761/chunks",
- [],
-
- scheme = part!("http"),
- authority = part!("127.0.0.1:61761"),
- path = "/chunks",
- query = None,
- host = Some("127.0.0.1"),
- port = Port::from_str("61761").ok(),
-}
-
-test_parse! {
- test_uri_parse_absolute_form_without_path,
- "https://127.0.0.1:61761",
- ["https://127.0.0.1:61761/"],
-
- scheme = part!("https"),
- authority = part!("127.0.0.1:61761"),
- path = "/",
- query = None,
- host = Some("127.0.0.1"),
- port = Port::from_str("61761").ok(),
-}
-
-test_parse! {
- test_uri_parse_asterisk_form,
- "*",
- [],
-
- scheme = None,
- authority = None,
- path = "*",
- query = None,
- host = None,
-}
-
-test_parse! {
- test_uri_parse_authority_no_port,
- "localhost",
- ["LOCALHOST", "LocaLHOSt"],
-
- scheme = None,
- authority = part!("localhost"),
- path = "",
- query = None,
- port = None,
- host = Some("localhost"),
-}
-
-test_parse! {
- test_uri_authority_only_one_character_issue_197,
- "S",
- [],
-
- scheme = None,
- authority = part!("S"),
- path = "",
- query = None,
- port = None,
- host = Some("S"),
-}
-
-test_parse! {
- test_uri_parse_authority_form,
- "localhost:3000",
- ["localhosT:3000"],
-
- scheme = None,
- authority = part!("localhost:3000"),
- path = "",
- query = None,
- host = Some("localhost"),
- port = Port::from_str("3000").ok(),
-}
-
-test_parse! {
- test_uri_parse_absolute_with_default_port_http,
- "http://127.0.0.1:80",
- ["http://127.0.0.1:80/"],
-
- scheme = part!("http"),
- authority = part!("127.0.0.1:80"),
- host = Some("127.0.0.1"),
- path = "/",
- query = None,
- port = Port::from_str("80").ok(),
-}
-
-test_parse! {
- test_uri_parse_absolute_with_default_port_https,
- "https://127.0.0.1:443",
- ["https://127.0.0.1:443/"],
-
- scheme = part!("https"),
- authority = part!("127.0.0.1:443"),
- host = Some("127.0.0.1"),
- path = "/",
- query = None,
- port = Port::from_str("443").ok(),
-}
-
-test_parse! {
- test_uri_parse_fragment_questionmark,
- "http://127.0.0.1/#?",
- [],
-
- scheme = part!("http"),
- authority = part!("127.0.0.1"),
- host = Some("127.0.0.1"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_uri_parse_path_with_terminating_questionmark,
- "http://127.0.0.1/path?",
- [],
-
- scheme = part!("http"),
- authority = part!("127.0.0.1"),
- path = "/path",
- query = Some(""),
- port = None,
-}
-
-test_parse! {
- test_uri_parse_absolute_form_with_empty_path_and_nonempty_query,
- "http://127.0.0.1?foo=bar",
- [],
-
- scheme = part!("http"),
- authority = part!("127.0.0.1"),
- path = "/",
- query = Some("foo=bar"),
- port = None,
-}
-
-test_parse! {
- test_uri_parse_absolute_form_with_empty_path_and_fragment_with_slash,
- "http://127.0.0.1#foo/bar",
- [],
-
- scheme = part!("http"),
- authority = part!("127.0.0.1"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_uri_parse_absolute_form_with_empty_path_and_fragment_with_questionmark,
- "http://127.0.0.1#foo?bar",
- [],
-
- scheme = part!("http"),
- authority = part!("127.0.0.1"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_uri_parse_long_host_with_no_scheme,
- "thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost",
- [],
-
- scheme = None,
- authority = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost"),
- path = "",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_uri_parse_long_host_with_port_and_no_scheme,
- "thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234",
- [],
-
- scheme = None,
- authority = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234"),
- path = "",
- query = None,
- port = Port::from_str("1234").ok(),
-}
-
-test_parse! {
- test_userinfo1,
- "http://a:b@127.0.0.1:1234/",
- [],
-
- scheme = part!("http"),
- authority = part!("a:b@127.0.0.1:1234"),
- host = Some("127.0.0.1"),
- path = "/",
- query = None,
- port = Port::from_str("1234").ok(),
-}
-
-test_parse! {
- test_userinfo2,
- "http://a:b@127.0.0.1/",
- [],
-
- scheme = part!("http"),
- authority = part!("a:b@127.0.0.1"),
- host = Some("127.0.0.1"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_userinfo3,
- "http://a@127.0.0.1/",
- [],
-
- scheme = part!("http"),
- authority = part!("a@127.0.0.1"),
- host = Some("127.0.0.1"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_userinfo_with_port,
- "user@localhost:3000",
- [],
-
- scheme = None,
- authority = part!("user@localhost:3000"),
- path = "",
- query = None,
- host = Some("localhost"),
- port = Port::from_str("3000").ok(),
-}
-
-test_parse! {
- test_userinfo_pass_with_port,
- "user:pass@localhost:3000",
- [],
-
- scheme = None,
- authority = part!("user:pass@localhost:3000"),
- path = "",
- query = None,
- host = Some("localhost"),
- port = Port::from_str("3000").ok(),
-}
-
-test_parse! {
- test_ipv6,
- "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/",
- [],
-
- scheme = part!("http"),
- authority = part!("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"),
- host = Some("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_ipv6_shorthand,
- "http://[::1]/",
- [],
-
- scheme = part!("http"),
- authority = part!("[::1]"),
- host = Some("[::1]"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_ipv6_shorthand2,
- "http://[::]/",
- [],
-
- scheme = part!("http"),
- authority = part!("[::]"),
- host = Some("[::]"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_ipv6_shorthand3,
- "http://[2001:db8::2:1]/",
- [],
-
- scheme = part!("http"),
- authority = part!("[2001:db8::2:1]"),
- host = Some("[2001:db8::2:1]"),
- path = "/",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_ipv6_with_port,
- "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8008/",
- [],
-
- scheme = part!("http"),
- authority = part!("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8008"),
- host = Some("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"),
- path = "/",
- query = None,
- port = Port::from_str("8008").ok(),
-}
-
-test_parse! {
- test_percentage_encoded_path,
- "/echo/abcdefgh_i-j%20/abcdefg_i-j%20478",
- [],
-
- scheme = None,
- authority = None,
- host = None,
- path = "/echo/abcdefgh_i-j%20/abcdefg_i-j%20478",
- query = None,
- port = None,
-}
-
-test_parse! {
- test_path_permissive,
- "/foo=bar|baz\\^~%",
- [],
-
- path = "/foo=bar|baz\\^~%",
-}
-
-test_parse! {
- test_query_permissive,
- "/?foo={bar|baz}\\^`",
- [],
-
- query = Some("foo={bar|baz}\\^`"),
-}
-
-#[test]
-fn test_uri_parse_error() {
- fn err(s: &str) {
- Uri::from_str(s).unwrap_err();
- }
-
- err("http://");
- err("htt:p//host");
- err("hyper.rs/");
- err("hyper.rs?key=val");
- err("?key=val");
- err("localhost/");
- err("localhost?key=val");
- err("\0");
- err("http://[::1");
- err("http://::1]");
- err("localhost:8080:3030");
- err("@");
- err("http://username:password@/wut");
-
- // illegal queries
- err("/?foo\rbar");
- err("/?foo\nbar");
- err("/?<");
- err("/?>");
-}
-
-#[test]
-fn test_max_uri_len() {
- let mut uri = vec![];
- uri.extend(b"http://localhost/");
- uri.extend(vec![b'a'; 70 * 1024]);
-
- let uri = String::from_utf8(uri).unwrap();
- let res: Result<Uri, InvalidUri> = uri.parse();
-
- assert_eq!(res.unwrap_err().0, ErrorKind::TooLong);
-}
-
-#[test]
-fn test_overflowing_scheme() {
- let mut uri = vec![];
- uri.extend(vec![b'a'; 256]);
- uri.extend(b"://localhost/");
-
- let uri = String::from_utf8(uri).unwrap();
- let res: Result<Uri, InvalidUri> = uri.parse();
-
- assert_eq!(res.unwrap_err().0, ErrorKind::SchemeTooLong);
-}
-
-#[test]
-fn test_max_length_scheme() {
- let mut uri = vec![];
- uri.extend(vec![b'a'; 64]);
- uri.extend(b"://localhost/");
-
- let uri = String::from_utf8(uri).unwrap();
- let uri: Uri = uri.parse().unwrap();
-
- assert_eq!(uri.scheme_str().unwrap().len(), 64);
-}
-
-#[test]
-fn test_uri_to_path_and_query() {
- let cases = vec![
- ("/", "/"),
- ("/foo?bar", "/foo?bar"),
- ("/foo?bar#nope", "/foo?bar"),
- ("http://hyper.rs", "/"),
- ("http://hyper.rs/", "/"),
- ("http://hyper.rs/path", "/path"),
- ("http://hyper.rs?query", "/?query"),
- ("*", "*"),
- ];
-
- for case in cases {
- let uri = Uri::from_str(case.0).unwrap();
- let s = uri.path_and_query().unwrap().to_string();
-
- assert_eq!(s, case.1);
- }
-}
-
-#[test]
-fn test_authority_uri_parts_round_trip() {
- let s = "hyper.rs";
- let uri = Uri::from_str(s).expect("first parse");
- assert_eq!(uri, s);
- assert_eq!(uri.to_string(), s);
-
- let parts = uri.into_parts();
- let uri2 = Uri::from_parts(parts).expect("from_parts");
- assert_eq!(uri2, s);
- assert_eq!(uri2.to_string(), s);
-}
-
-#[test]
-fn test_partial_eq_path_with_terminating_questionmark() {
- let a = "/path";
- let uri = Uri::from_str("/path?").expect("first parse");
-
- assert_eq!(uri, a);
-}