use std::convert::TryFrom; use std::error::Error; use std::fmt::Write; use std::hash::{Hash, Hasher}; use std::str::FromStr; use std::{cmp, fmt, str};
usecrate::header::name::HeaderName;
/// Represents an HTTP header field value. /// /// In practice, HTTP header field values are usually valid ASCII. However, the /// HTTP spec allows for a header value to contain opaque bytes as well. In this /// case, the header field value is not able to be represented as a string. /// /// To handle this, the `HeaderValue` is usable as a type and can be compared /// with strings and implements `Debug`. A `to_str` fn is provided that returns /// an `Err` if the header value contains non visible ascii characters. #[derive(Clone)] pubstruct HeaderValue {
inner: Bytes,
is_sensitive: bool,
}
/// A possible error when converting a `HeaderValue` from a string or byte /// slice. pubstruct InvalidHeaderValue {
_priv: (),
}
/// A possible error when converting a `HeaderValue` to a string representation. /// /// Header field values may contain opaque bytes, in which case it is not /// possible to represent the value as a string. #[derive(Debug)] pubstruct ToStrError {
_priv: (),
}
impl HeaderValue { /// Convert a static string to a `HeaderValue`. /// /// This function will not perform any copying, however the string is /// checked to ensure that no invalid characters are present. Only visible /// ASCII characters (32-127) are permitted. /// /// # Panics /// /// This function panics if the argument contains invalid header value /// characters. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_static("hello"); /// assert_eq!(val, "hello"); /// ``` #[inline] pubconstfn from_static(src: &'static str) -> HeaderValue { let bytes = src.as_bytes(); letmut i = 0; while i < bytes.len() { if !is_visible_ascii(bytes[i]) {
panic!("HeaderValue::from_static with invalid bytes")
}
i += 1;
}
/// Attempt to convert a string to a `HeaderValue`. /// /// If the argument contains invalid header value characters, an error is /// returned. Only visible ASCII characters (32-127) are permitted. Use /// `from_bytes` to create a `HeaderValue` that includes opaque octets /// (128-255). /// /// This function is intended to be replaced in the future by a `TryFrom` /// implementation once the trait is stabilized in std. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_str("hello").unwrap(); /// assert_eq!(val, "hello"); /// ``` /// /// An invalid value /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_str("\n"); /// assert!(val.is_err()); /// ``` #[inline] #[allow(clippy::should_implement_trait)] pubfn from_str(src: &str) -> Result<HeaderValue, InvalidHeaderValue> {
HeaderValue::try_from_generic(src, |s| Bytes::copy_from_slice(s.as_bytes()))
}
/// Converts a HeaderName into a HeaderValue /// /// Since every valid HeaderName is a valid HeaderValue this is done infallibly. /// /// # Examples /// /// ``` /// # use http::header::{HeaderValue, HeaderName}; /// # use http::header::ACCEPT; /// let val = HeaderValue::from_name(ACCEPT); /// assert_eq!(val, HeaderValue::from_bytes(b"accept").unwrap()); /// ``` #[inline] pubfn from_name(name: HeaderName) -> HeaderValue {
name.into()
}
/// Attempt to convert a byte slice to a `HeaderValue`. /// /// If the argument contains invalid header value bytes, an error is /// returned. Only byte values between 32 and 255 (inclusive) are permitted, /// excluding byte 127 (DEL). /// /// This function is intended to be replaced in the future by a `TryFrom` /// implementation once the trait is stabilized in std. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_bytes(b"hello\xfa").unwrap(); /// assert_eq!(val, &b"hello\xfa"[..]); /// ``` /// /// An invalid value /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_bytes(b"\n"); /// assert!(val.is_err()); /// ``` #[inline] pubfn from_bytes(src: &[u8]) -> Result<HeaderValue, InvalidHeaderValue> {
HeaderValue::try_from_generic(src, Bytes::copy_from_slice)
}
/// Attempt to convert a `Bytes` buffer to a `HeaderValue`. /// /// 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. pubfn from_maybe_shared<T>(src: T) -> Result<HeaderValue, InvalidHeaderValue> where
T: AsRef<[u8]> + 'static,
{
if_downcast_into!(T, Bytes, src, { return HeaderValue::from_shared(src);
});
HeaderValue::from_bytes(src.as_ref())
}
/// Convert a `Bytes` directly into a `HeaderValue` without validating. /// /// This function does NOT validate that illegal bytes are not contained /// within the buffer. /// /// ## Panics /// In a debug build this will panic if `src` is not valid UTF-8. /// /// ## Safety /// `src` must contain valid UTF-8. In a release build it is undefined /// behaviour to call this with `src` that is not valid UTF-8. pubunsafefn from_maybe_shared_unchecked<T>(src: T) -> HeaderValue where
T: AsRef<[u8]> + 'static,
{ if cfg!(debug_assertions) { match HeaderValue::from_maybe_shared(src) {
Ok(val) => val,
Err(_err) => {
panic!("HeaderValue::from_maybe_shared_unchecked() with invalid bytes");
}
}
} else {
if_downcast_into!(T, Bytes, src, { return HeaderValue {
inner: src,
is_sensitive: false,
};
});
/// Yields a `&str` slice if the `HeaderValue` only contains visible ASCII /// chars. /// /// This function will perform a scan of the header value, checking all the /// characters. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_static("hello"); /// assert_eq!(val.to_str().unwrap(), "hello"); /// ``` pubfn to_str(&self) -> Result<&str, ToStrError> { let bytes = self.as_ref();
for &b in bytes { if !is_visible_ascii(b) { return Err(ToStrError { _priv: () });
}
}
unsafe { Ok(str::from_utf8_unchecked(bytes)) }
}
/// Returns the length of `self`. /// /// This length is in bytes. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_static("hello"); /// assert_eq!(val.len(), 5); /// ``` #[inline] pubfn len(&self) -> usize { self.as_ref().len()
}
/// Returns true if the `HeaderValue` has a length of zero bytes. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_static(""); /// assert!(val.is_empty()); /// /// let val = HeaderValue::from_static("hello"); /// assert!(!val.is_empty()); /// ``` #[inline] pubfn is_empty(&self) -> bool { self.len() == 0
}
/// Converts a `HeaderValue` to a byte slice. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let val = HeaderValue::from_static("hello"); /// assert_eq!(val.as_bytes(), b"hello"); /// ``` #[inline] pubfn as_bytes(&self) -> &[u8] { self.as_ref()
}
/// Mark that the header value represents sensitive information. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let mut val = HeaderValue::from_static("my secret"); /// /// val.set_sensitive(true); /// assert!(val.is_sensitive()); /// /// val.set_sensitive(false); /// assert!(!val.is_sensitive()); /// ``` #[inline] pubfn set_sensitive(&mutself, val: bool) { self.is_sensitive = val;
}
/// Returns `true` if the value represents sensitive data. /// /// Sensitive data could represent passwords or other data that should not /// be stored on disk or in memory. By marking header values as sensitive, /// components using this crate can be instructed to treat them with special /// care for security reasons. For example, caches can avoid storing /// sensitive values, and HPACK encoders used by HTTP/2.0 implementations /// can choose not to compress them. /// /// Additionally, sensitive values will be masked by the `Debug` /// implementation of `HeaderValue`. /// /// Note that sensitivity is not factored into equality or ordering. /// /// # Examples /// /// ``` /// # use http::header::HeaderValue; /// let mut val = HeaderValue::from_static("my secret"); /// /// val.set_sensitive(true); /// assert!(val.is_sensitive()); /// /// val.set_sensitive(false); /// assert!(!val.is_sensitive()); /// ``` #[inline] pubfn is_sensitive(&self) -> bool { self.is_sensitive
}
}
for &(value, expected) in cases { let val = HeaderValue::from_bytes(value.as_bytes()).unwrap(); let actual = format!("{:?}", val);
assert_eq!(expected, actual);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.