diff --git a/Cargo.toml b/Cargo.toml index a8026b8..876d953 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,12 +44,14 @@ tokio-stream = {version = "0.1.9", features = ["net"]} warp = "0.3.2" [features] +# This is not a real user-facing feature, don't enable it directly. +_compress-any = [] basic-auth = ["base64"] charsets = ["encoding_rs", "encoding_rs_io"] # The following three compress features are mutually exclusive. -compress = ["flate2/default"] -compress-zlib = ["flate2/zlib"] -compress-zlib-ng = ["flate2/zlib-ng"] +compress = ["flate2/default", "_compress-any"] +compress-zlib = ["flate2/zlib", "_compress-any"] +compress-zlib-ng = ["flate2/zlib-ng", "_compress-any"] default = ["compress", "tls"] form = ["serde", "serde_urlencoded"] json = ["serde", "serde_json"] diff --git a/src/parsing/compressed_reader.rs b/src/parsing/compressed_reader.rs index 3c8cd7d..9a626b4 100644 --- a/src/parsing/compressed_reader.rs +++ b/src/parsing/compressed_reader.rs @@ -1,11 +1,11 @@ use std::io::{self, Read}; -#[cfg(feature = "compress")] +#[cfg(feature = "_compress-any")] use flate2::bufread::{DeflateDecoder, GzDecoder}; use http::header::HeaderMap; -#[cfg(feature = "compress")] +#[cfg(feature = "_compress-any")] use http::header::{CONTENT_ENCODING, TRANSFER_ENCODING}; -#[cfg(feature = "compress")] +#[cfg(feature = "_compress-any")] use http::Method; use crate::error::Result; @@ -16,18 +16,18 @@ use crate::request::PreparedRequest; #[derive(Debug)] pub enum CompressedReader { Plain(BodyReader), - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] Deflate(DeflateDecoder), - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] Gzip(GzDecoder), } -#[cfg(feature = "compress")] +#[cfg(feature = "_compress-any")] fn have_encoding_item(value: &str, enc: &str) -> bool { value.split(',').map(|s| s.trim()).any(|s| s.eq_ignore_ascii_case(enc)) } -#[cfg(feature = "compress")] +#[cfg(feature = "_compress-any")] fn have_encoding_content_encoding(headers: &HeaderMap, enc: &str) -> bool { headers .get_all(CONTENT_ENCODING) @@ -36,7 +36,7 @@ fn have_encoding_content_encoding(headers: &HeaderMap, enc: &str) -> bool { .any(|val| have_encoding_item(val, enc)) } -#[cfg(feature = "compress")] +#[cfg(feature = "_compress-any")] fn have_encoding_transfer_encoding(headers: &HeaderMap, enc: &str) -> bool { headers .get_all(TRANSFER_ENCODING) @@ -45,13 +45,13 @@ fn have_encoding_transfer_encoding(headers: &HeaderMap, enc: &str) -> bool { .any(|val| have_encoding_item(val, enc)) } -#[cfg(feature = "compress")] +#[cfg(feature = "_compress-any")] fn have_encoding(headers: &HeaderMap, enc: &str) -> bool { have_encoding_content_encoding(headers, enc) || have_encoding_transfer_encoding(headers, enc) } impl CompressedReader { - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] pub fn new(headers: &HeaderMap, request: &PreparedRequest, reader: BodyReader) -> Result { if request.method() != Method::HEAD { if have_encoding(headers, "gzip") { @@ -68,7 +68,7 @@ impl CompressedReader { Ok(CompressedReader::Plain(reader)) } - #[cfg(not(feature = "compress"))] + #[cfg(not(feature = "_compress-any"))] pub fn new(_: &HeaderMap, _: &PreparedRequest, reader: BodyReader) -> Result { Ok(CompressedReader::Plain(reader)) } @@ -80,9 +80,9 @@ impl Read for CompressedReader { // TODO: gzip does not read until EOF, leaving some data in the buffer. match self { CompressedReader::Plain(s) => s.read(buf), - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] CompressedReader::Deflate(s) => s.read(buf), - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] CompressedReader::Gzip(s) => s.read(buf), } } @@ -92,23 +92,23 @@ impl Read for CompressedReader { mod tests { use std::io::prelude::*; - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] use flate2::{ write::{DeflateEncoder, GzEncoder}, Compression, }; - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] use http::header::{HeaderMap, HeaderValue}; use http::Method; - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] use super::have_encoding; use crate::parsing::response::parse_response; use crate::streams::BaseStream; use crate::PreparedRequest; #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_have_encoding_none() { let mut headers = HeaderMap::new(); headers.insert("content-encoding", HeaderValue::from_static("gzip")); @@ -116,7 +116,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_have_encoding_content_encoding_simple() { let mut headers = HeaderMap::new(); headers.insert("content-encoding", HeaderValue::from_static("gzip")); @@ -124,7 +124,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_have_encoding_content_encoding_multi() { let mut headers = HeaderMap::new(); headers.insert("content-encoding", HeaderValue::from_static("identity, deflate")); @@ -132,7 +132,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_have_encoding_transfer_encoding_simple() { let mut headers = HeaderMap::new(); headers.insert("transfer-encoding", HeaderValue::from_static("deflate")); @@ -140,7 +140,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_have_encoding_transfer_encoding_multi() { let mut headers = HeaderMap::new(); headers.insert("transfer-encoding", HeaderValue::from_static("gzip, chunked")); @@ -163,7 +163,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_stream_deflate() { let mut payload = Vec::new(); let mut enc = DeflateEncoder::new(&mut payload, Compression::default()); @@ -186,7 +186,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_stream_gzip() { let mut payload = Vec::new(); let mut enc = GzEncoder::new(&mut payload, Compression::default()); @@ -210,7 +210,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_no_body_with_gzip() { let buf = b"HTTP/1.1 200 OK\r\ncontent-encoding: gzip\r\n\r\n"; @@ -221,7 +221,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_no_body_with_gzip_head() { let buf = b"HTTP/1.1 200 OK\r\ncontent-encoding: gzip\r\n\r\n"; diff --git a/src/request/builder.rs b/src/request/builder.rs index 2b62b1e..fdef145 100644 --- a/src/request/builder.rs +++ b/src/request/builder.rs @@ -358,7 +358,7 @@ impl RequestBuilder { /// /// This value defaults to true. Note that this only lets the browser know that this request supports /// compression, the server might choose not to compress the content. - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] pub fn allow_compression(mut self, allow_compression: bool) -> Self { self.base_settings.allow_compression = allow_compression; self @@ -579,7 +579,7 @@ mod tests { } } - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn assert_request_content( builder: RequestBuilder, status_line: &str, @@ -615,7 +615,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_request_builder_write_request_no_query() { assert_request_content( RequestBuilder::new(Method::GET, "http://localhost:1337/foo"), @@ -631,7 +631,7 @@ mod tests { } #[test] - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn test_request_builder_write_request_with_query() { assert_request_content( RequestBuilder::new(Method::GET, "http://localhost:1337/foo").param("hello", "world"), diff --git a/src/request/mod.rs b/src/request/mod.rs index 76e54cc..60873a8 100644 --- a/src/request/mod.rs +++ b/src/request/mod.rs @@ -3,7 +3,7 @@ use std::io::{prelude::*, BufWriter}; use std::str; use std::time::Instant; -#[cfg(feature = "compress")] +#[cfg(feature = "_compress-any")] use http::header::ACCEPT_ENCODING; use http::{ header::{HeaderValue, IntoHeaderName, HOST}, @@ -85,12 +85,12 @@ impl PreparedRequest { } impl PreparedRequest { - #[cfg(not(feature = "compress"))] + #[cfg(not(feature = "_compress-any"))] fn set_compression(&mut self) -> Result { Ok(()) } - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] fn set_compression(&mut self) -> Result { if self.base_settings.allow_compression { header_insert(&mut self.base_settings.headers, ACCEPT_ENCODING, "gzip, deflate")?; diff --git a/src/request/session.rs b/src/request/session.rs index cf7e3fd..93fcea1 100644 --- a/src/request/session.rs +++ b/src/request/session.rs @@ -214,7 +214,7 @@ impl Session { /// /// This value defaults to true. Note that this only lets the browser know that this `Request` supports /// compression, the server might choose not to compress the content. - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] pub fn allow_compression(&mut self, allow_compression: bool) { self.base_settings.allow_compression = allow_compression; } diff --git a/src/request/settings.rs b/src/request/settings.rs index 3c98d3d..d897bb1 100644 --- a/src/request/settings.rs +++ b/src/request/settings.rs @@ -24,7 +24,7 @@ pub struct BaseSettings { #[cfg(feature = "charsets")] pub default_charset: Option, - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] pub allow_compression: bool, } @@ -45,7 +45,7 @@ impl Default for BaseSettings { #[cfg(feature = "charsets")] default_charset: None, - #[cfg(feature = "compress")] + #[cfg(feature = "_compress-any")] allow_compression: true, } }