diff --git a/src/lib.rs b/src/lib.rs index 3f623a7..442c9ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -181,6 +181,12 @@ pub fn patch(path: &str) -> Request { request("PATCH", path) } +// Compilation error when both tls and native-tls features are enabled +#[cfg(all(feature = "tls", feature = "native-tls"))] +std::compile_error!( + "You have both the \"tls\" and \"native-tls\" features enabled on ureq. Please disable one of these features." +); + #[cfg(test)] mod tests { use super::*; diff --git a/src/stream.rs b/src/stream.rs index 334c759..71ed219 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -24,9 +24,9 @@ use crate::unit::Unit; #[allow(clippy::large_enum_variant)] pub enum Stream { Http(TcpStream), - #[cfg(feature = "tls")] + #[cfg(all(feature = "tls", not(feature = "native-tls")))] Https(rustls::StreamOwned), - #[cfg(feature = "native-tls")] + #[cfg(all(feature = "native-tls", not(feature = "tls")))] Https(TlsStream), Cursor(Cursor>), #[cfg(test)] @@ -40,7 +40,10 @@ impl ::std::fmt::Debug for Stream { "Stream[{}]", match self { Stream::Http(_) => "http", - #[cfg(any(feature = "tls", feature = "native-tls"))] + #[cfg(any( + all(feature = "tls", not(feature = "native-tls")), + all(feature = "native-tls", not(feature = "tls")), + ))] Stream::Https(_) => "https", Stream::Cursor(_) => "cursor", #[cfg(test)] @@ -81,7 +84,10 @@ impl Stream { pub fn is_poolable(&self) -> bool { match self { Stream::Http(_) => true, - #[cfg(any(feature = "tls", feature = "native-tls"))] + #[cfg(any( + all(feature = "tls", not(feature = "native-tls")), + all(feature = "native-tls", not(feature = "tls")), + ))] Stream::Https(_) => true, _ => false, } @@ -100,7 +106,10 @@ impl Read for Stream { fn read(&mut self, buf: &mut [u8]) -> IoResult { match self { Stream::Http(sock) => sock.read(buf), - #[cfg(any(feature = "tls", feature = "native-tls"))] + #[cfg(any( + all(feature = "tls", not(feature = "native-tls")), + all(feature = "native-tls", not(feature = "tls")), + ))] Stream::Https(stream) => read_https(stream, buf), Stream::Cursor(read) => read.read(buf), #[cfg(test)] @@ -109,7 +118,7 @@ impl Read for Stream { } } -#[cfg(feature = "tls")] +#[cfg(all(feature = "tls", not(feature = "native-tls")))] fn read_https( stream: &mut StreamOwned, buf: &mut [u8], @@ -121,11 +130,8 @@ fn read_https( } } -#[cfg(feature = "native-tls")] -fn read_https( - stream: &mut TlsStream, - buf: &mut [u8], -) -> IoResult { +#[cfg(all(feature = "native-tls", not(feature = "tls")))] +fn read_https(stream: &mut TlsStream, buf: &mut [u8]) -> IoResult { match stream.read(buf) { Ok(size) => Ok(size), Err(ref e) if is_close_notify(e) => Ok(0), @@ -153,7 +159,10 @@ impl Write for Stream { fn write(&mut self, buf: &[u8]) -> IoResult { match self { Stream::Http(sock) => sock.write(buf), - #[cfg(any(feature = "tls", feature = "native-tls"))] + #[cfg(any( + all(feature = "tls", not(feature = "native-tls")), + all(feature = "native-tls", not(feature = "tls")), + ))] Stream::Https(stream) => stream.write(buf), Stream::Cursor(_) => panic!("Write to read only stream"), #[cfg(test)] @@ -163,7 +172,10 @@ impl Write for Stream { fn flush(&mut self) -> IoResult<()> { match self { Stream::Http(sock) => sock.flush(), - #[cfg(any(feature = "tls", feature = "native-tls"))] + #[cfg(any( + all(feature = "tls", not(feature = "native-tls")), + all(feature = "native-tls", not(feature = "tls")), + ))] Stream::Https(stream) => stream.flush(), Stream::Cursor(_) => panic!("Flush read only stream"), #[cfg(test)] @@ -194,7 +206,7 @@ fn configure_certs(config: &mut rustls::ClientConfig) { .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS); } -#[cfg(feature = "tls")] +#[cfg(all(feature = "tls", not(feature = "native-tls")))] pub(crate) fn connect_https(unit: &Unit) -> Result { use lazy_static::lazy_static; use std::sync::Arc; @@ -223,7 +235,7 @@ pub(crate) fn connect_https(unit: &Unit) -> Result { Ok(Stream::Https(stream)) } -#[cfg(feature = "native-tls")] +#[cfg(all(feature = "native-tls", not(feature = "tls")))] pub(crate) fn connect_https(unit: &Unit) -> Result { let hostname = unit.url.host_str().unwrap(); let port = unit.url.port().unwrap_or(443); diff --git a/src/unit.rs b/src/unit.rs index 5046bf3..4828cdc 100644 --- a/src/unit.rs +++ b/src/unit.rs @@ -10,7 +10,12 @@ use cookie::{Cookie, CookieJar}; use crate::agent::AgentState; use crate::body::{self, Payload, SizedReader}; use crate::header; -use crate::stream::{self, connect_https, connect_test, Stream}; +#[cfg(any( + all(feature = "tls", not(feature = "native-tls")), + all(feature = "native-tls", not(feature = "tls")), +))] +use crate::stream::connect_https; +use crate::stream::{self, connect_test, Stream}; use crate::Proxy; use crate::{Error, Header, Request, Response}; @@ -286,6 +291,10 @@ fn connect_socket(unit: &Unit, use_pooled: bool) -> Result<(Stream, bool), Error } let stream = match unit.url.scheme() { "http" => stream::connect_http(&unit), + #[cfg(any( + all(feature = "tls", not(feature = "native-tls")), + all(feature = "native-tls", not(feature = "tls")), + ))] "https" => connect_https(&unit), "test" => connect_test(&unit), _ => Err(Error::UnknownScheme(unit.url.scheme().to_string())), diff --git a/tests/https-agent.rs b/tests/https-agent.rs index 5703f68..b6fe27e 100644 --- a/tests/https-agent.rs +++ b/tests/https-agent.rs @@ -1,7 +1,8 @@ #[cfg(all(test, any(feature = "tls", feature = "native-tls")))] use std::io::Read; -#[cfg(all(test, any(feature = "tls", feature = "native-tls")))] +#[cfg(any(feature = "tls", feature = "native-tls"))] +#[test] fn tls_connection_close() { let agent = ureq::Agent::default().build(); let resp = agent