diff --git a/Cargo.toml b/Cargo.toml index f3a6271ee..3757ac9f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,6 +97,8 @@ either = "1.5.3" encoding_rs = "0.8" futures-core = { version = "0.3.7", default-features = false } futures-util = { version = "0.3.7", default-features = false } +language-tags = "0.2" +once_cell = "1.5" log = "0.4" mime = "0.3" pin-project = "1.0.0" diff --git a/actix-http/src/header/mod.rs b/actix-http/src/header/mod.rs index 1100a959d..9017f15aa 100644 --- a/actix-http/src/header/mod.rs +++ b/actix-http/src/header/mod.rs @@ -14,13 +14,10 @@ use crate::HttpMessage; mod as_name; mod into_pair; mod into_value; -mod utils; -mod common; pub(crate) mod map; mod shared; -pub use self::common::*; #[doc(hidden)] pub use self::shared::*; @@ -30,7 +27,6 @@ pub use self::into_value::IntoHeaderValue; #[doc(hidden)] pub use self::map::GetAll; pub use self::map::HeaderMap; -pub use self::utils::*; /// A trait for any object that already represents a valid header field and value. pub trait Header: IntoHeaderValue { @@ -41,17 +37,18 @@ pub trait Header: IntoHeaderValue { fn parse(msg: &T) -> Result; } +#[doc(hidden)] #[derive(Debug, Default)] -pub(crate) struct Writer { +pub struct Writer { buf: BytesMut, } impl Writer { - fn new() -> Writer { + pub fn new() -> Writer { Writer::default() } - fn take(&mut self) -> Bytes { + pub fn take(&mut self) -> Bytes { self.buf.split().freeze() } } diff --git a/actix-http/src/header/common/content_encoding.rs b/actix-http/src/header/shared/content_encoding.rs similarity index 86% rename from actix-http/src/header/common/content_encoding.rs rename to actix-http/src/header/shared/content_encoding.rs index b93d66101..51e65b5cf 100644 --- a/actix-http/src/header/common/content_encoding.rs +++ b/actix-http/src/header/shared/content_encoding.rs @@ -4,7 +4,7 @@ use http::header::InvalidHeaderValue; use crate::{ error::ParseError, - header::{self, from_one_raw_str, Header, HeaderName, HeaderValue, IntoHeaderValue}, + header::{self, Header, HeaderName, HeaderValue, IntoHeaderValue}, HttpMessage, }; @@ -101,6 +101,14 @@ impl Header for ContentEncoding { } fn parse(msg: &T) -> Result { - from_one_raw_str(msg.headers().get(Self::name())) + let val = msg.headers().get(Self::name()); + + if let Some(line) = val { + let line = line.to_str().map_err(|_| ParseError::Header)?; + if !line.is_empty() { + return Self::from_str(line).or(Err(ParseError::Header)); + } + } + Err(ParseError::Header) } } diff --git a/actix-http/src/header/shared/mod.rs b/actix-http/src/header/shared/mod.rs index 72161e46b..665ac6687 100644 --- a/actix-http/src/header/shared/mod.rs +++ b/actix-http/src/header/shared/mod.rs @@ -6,6 +6,7 @@ mod entity; mod extended; mod httpdate; mod quality_item; +mod content_encoding; pub use self::charset::Charset; pub use self::encoding::Encoding; @@ -13,4 +14,5 @@ pub use self::entity::EntityTag; pub use self::extended::{parse_extended_value, ExtendedValue}; pub use self::httpdate::HttpDate; pub use self::quality_item::{q, qitem, Quality, QualityItem}; +pub use self::content_encoding::ContentEncoding; pub use language_tags::LanguageTag; diff --git a/actix-http/src/response.rs b/actix-http/src/response.rs index d581fd293..15eb271aa 100644 --- a/actix-http/src/response.rs +++ b/actix-http/src/response.rs @@ -682,7 +682,7 @@ impl ResponseBuilder { }; if !contains { - self.insert_header(header::ContentType(mime::APPLICATION_JSON)); + self.insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON)); } self.body(Body::from(body)) diff --git a/src/lib.rs b/src/lib.rs index 136c462b8..f37ed7461 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,7 +102,7 @@ pub mod web; #[cfg(feature = "cookies")] pub use actix_http::cookie; pub use actix_http::Response as HttpResponse; -pub use actix_http::{body, http, Error, HttpMessage, ResponseError, Result}; +pub use actix_http::{body, Error, HttpMessage, ResponseError, Result}; pub use actix_rt as rt; pub use actix_web_codegen::*; @@ -117,6 +117,11 @@ pub use crate::server::HttpServer; // TODO: is exposing the error directly really needed pub use crate::types::{Either, EitherExtractError}; +pub mod http { + pub use actix_http::http::*; + pub use crate::types::header; +} + pub mod dev { //! The `actix-web` prelude for library developers //! diff --git a/src/test.rs b/src/test.rs index bc19296e2..5e0706c64 100644 --- a/src/test.rs +++ b/src/test.rs @@ -8,7 +8,6 @@ use std::{fmt, net, thread, time}; use actix_codec::{AsyncRead, AsyncWrite, Framed}; #[cfg(feature = "cookies")] use actix_http::cookie::Cookie; -use actix_http::http::header::{ContentType, IntoHeaderPair}; use actix_http::http::{Method, StatusCode, Uri, Version}; use actix_http::test::TestRequest as HttpTestRequest; use actix_http::{ws, Extensions, HttpService, Request}; @@ -34,6 +33,7 @@ use crate::dev::{Body, MessageBody, Payload, Server}; use crate::rmap::ResourceMap; use crate::service::{ServiceRequest, ServiceResponse}; use crate::{Error, HttpRequest, HttpResponse}; +use crate::http::header::{ContentType, IntoHeaderPair}; /// Create service that always responds with `HttpResponse::Ok()` pub fn ok_service( diff --git a/actix-http/src/header/common/accept.rs b/src/types/header/accept.rs similarity index 97% rename from actix-http/src/header/common/accept.rs rename to src/types/header/accept.rs index 775da3394..cb883eff5 100644 --- a/actix-http/src/header/common/accept.rs +++ b/src/types/header/accept.rs @@ -2,10 +2,10 @@ use std::cmp::Ordering; use mime::Mime; -use crate::header::{qitem, QualityItem}; +use super::{qitem, QualityItem}; use crate::http::header; -header! { +crate::header! { /// `Accept` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.2) /// /// The `Accept` header field can be used by user agents to specify @@ -116,8 +116,8 @@ header! { #[test] fn test_fuzzing1() { - use crate::test::TestRequest; - let req = TestRequest::default().insert_header((crate::header::ACCEPT, "chunk#;e")).finish(); + use actix_http::test::TestRequest; + let req = TestRequest::default().insert_header((crate::http::header::ACCEPT, "chunk#;e")).finish(); let header = Accept::parse(&req); assert!(header.is_ok()); } @@ -213,7 +213,7 @@ impl Accept { #[cfg(test)] mod tests { use super::*; - use crate::header::q; + use crate::http::header::q; #[test] fn test_mime_precedence() { diff --git a/actix-http/src/header/common/accept_charset.rs b/src/types/header/accept_charset.rs similarity index 96% rename from actix-http/src/header/common/accept_charset.rs rename to src/types/header/accept_charset.rs index db530a8bc..57c73966f 100644 --- a/actix-http/src/header/common/accept_charset.rs +++ b/src/types/header/accept_charset.rs @@ -1,6 +1,6 @@ -use crate::header::{Charset, QualityItem, ACCEPT_CHARSET}; +use super::{Charset, QualityItem, ACCEPT_CHARSET}; -header! { +crate::header! { /// `Accept-Charset` header, defined in /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.3) /// diff --git a/actix-http/src/header/common/accept_encoding.rs b/src/types/header/accept_encoding.rs similarity index 100% rename from actix-http/src/header/common/accept_encoding.rs rename to src/types/header/accept_encoding.rs diff --git a/actix-http/src/header/common/accept_language.rs b/src/types/header/accept_language.rs similarity index 97% rename from actix-http/src/header/common/accept_language.rs rename to src/types/header/accept_language.rs index a7ad00863..48847cff3 100644 --- a/actix-http/src/header/common/accept_language.rs +++ b/src/types/header/accept_language.rs @@ -1,7 +1,7 @@ -use crate::header::{QualityItem, ACCEPT_LANGUAGE}; +use super::{QualityItem, ACCEPT_LANGUAGE}; use language_tags::LanguageTag; -header! { +crate::header! { /// `Accept-Language` header, defined in /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-5.3.5) /// diff --git a/actix-http/src/header/common/allow.rs b/src/types/header/allow.rs similarity index 96% rename from actix-http/src/header/common/allow.rs rename to src/types/header/allow.rs index 06b1efedc..85710e677 100644 --- a/actix-http/src/header/common/allow.rs +++ b/src/types/header/allow.rs @@ -1,7 +1,7 @@ -use http::header; -use http::Method; +use actix_http::http::Method; +use crate::http::header; -header! { +crate::header! { /// `Allow` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.4.1) /// /// The `Allow` header field lists the set of methods advertised as diff --git a/actix-http/src/header/common/cache_control.rs b/src/types/header/cache_control.rs similarity index 98% rename from actix-http/src/header/common/cache_control.rs rename to src/types/header/cache_control.rs index 94ce9a750..ec894554f 100644 --- a/actix-http/src/header/common/cache_control.rs +++ b/src/types/header/cache_control.rs @@ -1,12 +1,12 @@ use std::fmt::{self, Write}; use std::str::FromStr; -use http::header; - -use crate::header::{ +use super::{ fmt_comma_delimited, from_comma_delimited, Header, IntoHeaderValue, Writer, }; +use crate::http::header; + /// `Cache-Control` header, defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2) /// /// The `Cache-Control` header field is used to specify directives for @@ -191,8 +191,8 @@ impl FromStr for CacheDirective { #[cfg(test)] mod tests { use super::*; - use crate::header::Header; - use crate::test::TestRequest; + use crate::http::header::Header; + use actix_http::test::TestRequest; #[test] fn test_parse_multiple_headers() { diff --git a/actix-http/src/header/common/content_disposition.rs b/src/types/header/content_disposition.rs similarity index 99% rename from actix-http/src/header/common/content_disposition.rs rename to src/types/header/content_disposition.rs index 6076d033c..4dc1aeacf 100644 --- a/actix-http/src/header/common/content_disposition.rs +++ b/src/types/header/content_disposition.rs @@ -10,7 +10,8 @@ use once_cell::sync::Lazy; use regex::Regex; use std::fmt::{self, Write}; -use crate::header::{self, ExtendedValue, Header, IntoHeaderValue, Writer}; +use crate::http::header; +use super::{ExtendedValue, Header, IntoHeaderValue, Writer}; /// Split at the index of the first `needle` if it exists or at the end. fn split_once(haystack: &str, needle: char) -> (&str, &str) { @@ -554,8 +555,8 @@ impl fmt::Display for ContentDisposition { #[cfg(test)] mod tests { use super::{ContentDisposition, DispositionParam, DispositionType}; - use crate::header::shared::Charset; - use crate::header::{ExtendedValue, HeaderValue}; + use crate::http::header::Charset; + use crate::http::header::{ExtendedValue, HeaderValue}; #[test] fn test_from_raw_basic() { diff --git a/actix-http/src/header/common/content_language.rs b/src/types/header/content_language.rs similarity index 96% rename from actix-http/src/header/common/content_language.rs rename to src/types/header/content_language.rs index e9be67a1b..5987e15c2 100644 --- a/actix-http/src/header/common/content_language.rs +++ b/src/types/header/content_language.rs @@ -1,7 +1,7 @@ -use crate::header::{QualityItem, CONTENT_LANGUAGE}; +use super::{QualityItem, CONTENT_LANGUAGE}; use language_tags::LanguageTag; -header! { +crate::header! { /// `Content-Language` header, defined in /// [RFC7231](https://tools.ietf.org/html/rfc7231#section-3.1.3.2) /// diff --git a/actix-http/src/header/common/content_range.rs b/src/types/header/content_range.rs similarity index 99% rename from actix-http/src/header/common/content_range.rs rename to src/types/header/content_range.rs index 8b7552377..dfcf24251 100644 --- a/actix-http/src/header/common/content_range.rs +++ b/src/types/header/content_range.rs @@ -2,11 +2,11 @@ use std::fmt::{self, Display, Write}; use std::str::FromStr; use crate::error::ParseError; -use crate::header::{ +use super::{ HeaderValue, IntoHeaderValue, InvalidHeaderValue, Writer, CONTENT_RANGE, }; -header! { +crate::header! { /// `Content-Range` header, defined in /// [RFC7233](http://tools.ietf.org/html/rfc7233#section-4.2) (ContentRange, CONTENT_RANGE) => [ContentRangeSpec] diff --git a/actix-http/src/header/common/content_type.rs b/src/types/header/content_type.rs similarity index 98% rename from actix-http/src/header/common/content_type.rs rename to src/types/header/content_type.rs index ac5c7e5b8..e4a4e621d 100644 --- a/actix-http/src/header/common/content_type.rs +++ b/src/types/header/content_type.rs @@ -1,7 +1,7 @@ -use crate::header::CONTENT_TYPE; +use super::CONTENT_TYPE; use mime::Mime; -header! { +crate::header! { /// `Content-Type` header, defined in /// [RFC7231](http://tools.ietf.org/html/rfc7231#section-3.1.1.5) /// diff --git a/actix-http/src/header/common/date.rs b/src/types/header/date.rs similarity index 95% rename from actix-http/src/header/common/date.rs rename to src/types/header/date.rs index e5ace95e6..35037d1bf 100644 --- a/actix-http/src/header/common/date.rs +++ b/src/types/header/date.rs @@ -1,7 +1,7 @@ -use crate::header::{HttpDate, DATE}; +use super::{HttpDate, DATE}; use std::time::SystemTime; -header! { +crate::header! { /// `Date` header, defined in [RFC7231](http://tools.ietf.org/html/rfc7231#section-7.1.1.2) /// /// The `Date` header field represents the date and time at which the diff --git a/actix-http/src/header/common/etag.rs b/src/types/header/etag.rs similarity index 98% rename from actix-http/src/header/common/etag.rs rename to src/types/header/etag.rs index 4c1e8d262..3a913c19b 100644 --- a/actix-http/src/header/common/etag.rs +++ b/src/types/header/etag.rs @@ -1,6 +1,6 @@ -use crate::header::{EntityTag, ETAG}; +use super::{EntityTag, ETAG}; -header! { +crate::header! { /// `ETag` header, defined in [RFC7232](http://tools.ietf.org/html/rfc7232#section-2.3) /// /// The `ETag` header field in a response provides the current entity-tag diff --git a/actix-http/src/header/common/expires.rs b/src/types/header/expires.rs similarity index 95% rename from actix-http/src/header/common/expires.rs rename to src/types/header/expires.rs index 79563955d..2816b50da 100644 --- a/actix-http/src/header/common/expires.rs +++ b/src/types/header/expires.rs @@ -1,6 +1,6 @@ -use crate::header::{HttpDate, EXPIRES}; +use super::{HttpDate, EXPIRES}; -header! { +crate::header! { /// `Expires` header, defined in [RFC7234](http://tools.ietf.org/html/rfc7234#section-5.3) /// /// The `Expires` header field gives the date/time after which the diff --git a/actix-http/src/header/common/if_match.rs b/src/types/header/if_match.rs similarity index 97% rename from actix-http/src/header/common/if_match.rs rename to src/types/header/if_match.rs index db255e91a..a5f2cc5bf 100644 --- a/actix-http/src/header/common/if_match.rs +++ b/src/types/header/if_match.rs @@ -1,6 +1,6 @@ -use crate::header::{EntityTag, IF_MATCH}; +use super::{EntityTag, IF_MATCH}; -header! { +crate::header! { /// `If-Match` header, defined in /// [RFC7232](https://tools.ietf.org/html/rfc7232#section-3.1) /// diff --git a/actix-http/src/header/common/if_modified_since.rs b/src/types/header/if_modified_since.rs similarity index 95% rename from actix-http/src/header/common/if_modified_since.rs rename to src/types/header/if_modified_since.rs index 99c7e441d..98cbacdba 100644 --- a/actix-http/src/header/common/if_modified_since.rs +++ b/src/types/header/if_modified_since.rs @@ -1,6 +1,6 @@ -use crate::header::{HttpDate, IF_MODIFIED_SINCE}; +use super::{HttpDate, IF_MODIFIED_SINCE}; -header! { +crate::header! { /// `If-Modified-Since` header, defined in /// [RFC7232](http://tools.ietf.org/html/rfc7232#section-3.3) /// diff --git a/actix-http/src/header/common/if_none_match.rs b/src/types/header/if_none_match.rs similarity index 95% rename from actix-http/src/header/common/if_none_match.rs rename to src/types/header/if_none_match.rs index 464caf1ae..79bf0a4c0 100644 --- a/actix-http/src/header/common/if_none_match.rs +++ b/src/types/header/if_none_match.rs @@ -1,6 +1,6 @@ -use crate::header::{EntityTag, IF_NONE_MATCH}; +use super::{EntityTag, IF_NONE_MATCH}; -header! { +crate::header! { /// `If-None-Match` header, defined in /// [RFC7232](https://tools.ietf.org/html/rfc7232#section-3.2) /// @@ -66,8 +66,8 @@ header! { #[cfg(test)] mod tests { use super::IfNoneMatch; - use crate::header::{EntityTag, Header, IF_NONE_MATCH}; - use crate::test::TestRequest; + use crate::http::header::{EntityTag, Header, IF_NONE_MATCH}; + use actix_http::test::TestRequest; #[test] fn test_if_none_match() { diff --git a/actix-http/src/header/common/if_range.rs b/src/types/header/if_range.rs similarity index 95% rename from actix-http/src/header/common/if_range.rs rename to src/types/header/if_range.rs index 0a5749505..6398981e9 100644 --- a/actix-http/src/header/common/if_range.rs +++ b/src/types/header/if_range.rs @@ -1,8 +1,9 @@ use std::fmt::{self, Display, Write}; +use crate::http::header; use crate::error::ParseError; -use crate::header::{ - self, from_one_raw_str, EntityTag, Header, HeaderName, HeaderValue, HttpDate, +use super::{ + from_one_raw_str, EntityTag, Header, HeaderName, HeaderValue, HttpDate, IntoHeaderValue, InvalidHeaderValue, Writer, }; use crate::HttpMessage; @@ -111,7 +112,7 @@ impl IntoHeaderValue for IfRange { #[cfg(test)] mod test_if_range { use super::IfRange as HeaderField; - use crate::header::*; + use crate::http::header::*; use std::str; test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); diff --git a/actix-http/src/header/common/if_unmodified_since.rs b/src/types/header/if_unmodified_since.rs similarity index 95% rename from actix-http/src/header/common/if_unmodified_since.rs rename to src/types/header/if_unmodified_since.rs index 1c2b4af78..c63026554 100644 --- a/actix-http/src/header/common/if_unmodified_since.rs +++ b/src/types/header/if_unmodified_since.rs @@ -1,6 +1,6 @@ -use crate::header::{HttpDate, IF_UNMODIFIED_SINCE}; +use super::{HttpDate, IF_UNMODIFIED_SINCE}; -header! { +crate::header! { /// `If-Unmodified-Since` header, defined in /// [RFC7232](http://tools.ietf.org/html/rfc7232#section-3.4) /// diff --git a/actix-http/src/header/common/last_modified.rs b/src/types/header/last_modified.rs similarity index 95% rename from actix-http/src/header/common/last_modified.rs rename to src/types/header/last_modified.rs index 65608d846..2d06a1778 100644 --- a/actix-http/src/header/common/last_modified.rs +++ b/src/types/header/last_modified.rs @@ -1,6 +1,6 @@ -use crate::header::{HttpDate, LAST_MODIFIED}; +use super::{HttpDate, LAST_MODIFIED}; -header! { +crate::header! { /// `Last-Modified` header, defined in /// [RFC7232](http://tools.ietf.org/html/rfc7232#section-2.2) /// diff --git a/actix-http/src/header/common/mod.rs b/src/types/header/mod.rs similarity index 97% rename from actix-http/src/header/common/mod.rs rename to src/types/header/mod.rs index 90e0a855e..868346452 100644 --- a/actix-http/src/header/common/mod.rs +++ b/src/types/header/mod.rs @@ -7,6 +7,7 @@ //! is used, such as `ContentType(pub Mime)`. #![cfg_attr(rustfmt, rustfmt_skip)] +pub use actix_http::http::header::*; pub use self::accept_charset::AcceptCharset; //pub use self::accept_encoding::AcceptEncoding; pub use self::accept::Accept; @@ -18,7 +19,6 @@ pub use self::content_disposition::{ }; pub use self::content_language::ContentLanguage; pub use self::content_range::{ContentRange, ContentRangeSpec}; -pub use self::content_encoding::{ContentEncoding}; pub use self::content_type::ContentType; pub use self::date::Date; pub use self::etag::ETag; @@ -30,6 +30,7 @@ pub use self::if_range::IfRange; pub use self::if_unmodified_since::IfUnmodifiedSince; pub use self::last_modified::LastModified; //pub use self::range::{Range, ByteRangeSpec}; +pub(crate) use self::utils::{fmt_comma_delimited, from_comma_delimited, from_one_raw_str}; #[doc(hidden)] #[macro_export] @@ -61,9 +62,9 @@ macro_rules! __hyper__tm { #[cfg(test)] mod $tm{ use std::str; - use http::Method; + use actix_http::http::Method; use mime::*; - use $crate::header::*; + use $crate::http::header::*; use super::$id as HeaderField; $($tf)* } @@ -77,8 +78,8 @@ macro_rules! test_header { ($id:ident, $raw:expr) => { #[test] fn $id() { - use super::*; - use $crate::test; + use actix_http::http::header::Header; + use actix_http::test; let raw = $raw; let a: Vec> = raw.iter().map(|x| x.to_vec()).collect(); @@ -106,7 +107,7 @@ macro_rules! test_header { ($id:ident, $raw:expr, $typed:expr) => { #[test] fn $id() { - use $crate::test; + use actix_http::test; let a: Vec> = $raw.iter().map(|x| x.to_vec()).collect(); let mut req = test::TestRequest::default(); @@ -134,6 +135,7 @@ macro_rules! test_header { }; } +#[doc(hidden)] #[macro_export] macro_rules! header { // $a:meta: Attributes associated with the header item (usually docs) @@ -341,7 +343,6 @@ mod allow; mod cache_control; mod content_disposition; mod content_language; -mod content_encoding; mod content_range; mod content_type; mod date; @@ -353,3 +354,4 @@ mod if_none_match; mod if_range; mod if_unmodified_since; mod last_modified; +mod utils; diff --git a/actix-http/src/header/common/range.rs b/src/types/header/range.rs similarity index 99% rename from actix-http/src/header/common/range.rs rename to src/types/header/range.rs index f9e203bb2..a9b40b403 100644 --- a/actix-http/src/header/common/range.rs +++ b/src/types/header/range.rs @@ -1,8 +1,8 @@ use std::fmt::{self, Display}; use std::str::FromStr; -use header::parsing::from_one_raw_str; -use header::{Header, Raw}; +use super::parsing::from_one_raw_str; +use super::{Header, Raw}; /// `Range` header, defined in [RFC7233](https://tools.ietf.org/html/rfc7233#section-3.1) /// diff --git a/actix-http/src/header/utils.rs b/src/types/header/utils.rs similarity index 78% rename from actix-http/src/header/utils.rs rename to src/types/header/utils.rs index e232d462f..a1258368c 100644 --- a/actix-http/src/header/utils.rs +++ b/src/types/header/utils.rs @@ -1,8 +1,7 @@ use std::{fmt, str::FromStr}; -use http::HeaderValue; - -use crate::{error::ParseError, header::HTTP_VALUE}; +use super::HeaderValue; +use crate::error::ParseError; /// Reads a comma-delimited raw header into a Vec. #[inline] @@ -54,10 +53,3 @@ where } Ok(()) } - -/// Percent encode a sequence of bytes with a character set defined in -/// -pub fn http_percent_encode(f: &mut fmt::Formatter<'_>, bytes: &[u8]) -> fmt::Result { - let encoded = percent_encoding::percent_encode(bytes, HTTP_VALUE); - fmt::Display::fmt(&encoded, f) -} diff --git a/src/types/mod.rs b/src/types/mod.rs index a062c351e..f472fed74 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -3,6 +3,7 @@ // TODO: review visibility mod either; pub(crate) mod form; +pub mod header; pub(crate) mod json; mod path; pub(crate) mod payload;