Add optional native-tls support, clear up warnings for flag configurations
This commit is contained in:
@@ -250,7 +250,7 @@ impl Agent {
|
||||
self.request("PATCH", path)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, any(feature = "tls", feature = "native-tls")))]
|
||||
pub(crate) fn state(&self) -> &Arc<Mutex<Option<AgentState>>> {
|
||||
&self.state
|
||||
}
|
||||
|
||||
@@ -31,6 +31,9 @@ pub enum Error {
|
||||
ProxyConnect,
|
||||
/// Incorrect credentials for proxy
|
||||
InvalidProxyCreds,
|
||||
/// TLS Error
|
||||
#[cfg(feature = "native-tls")]
|
||||
TlsError(native_tls::Error),
|
||||
}
|
||||
|
||||
impl Error {
|
||||
@@ -59,6 +62,8 @@ impl Error {
|
||||
Error::BadProxyCreds => 500,
|
||||
Error::ProxyConnect => 500,
|
||||
Error::InvalidProxyCreds => 500,
|
||||
#[cfg(feature = "native-tls")]
|
||||
Error::TlsError(_) => 599,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +83,8 @@ impl Error {
|
||||
Error::BadProxyCreds => "Failed to parse proxy credentials",
|
||||
Error::ProxyConnect => "Proxy failed to connect",
|
||||
Error::InvalidProxyCreds => "Provided proxy credentials are incorrect",
|
||||
#[cfg(feature = "native-tls")]
|
||||
Error::TlsError(_) => "TLS Error",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +104,8 @@ impl Error {
|
||||
Error::BadProxyCreds => "Failed to parse proxy credentials".to_string(),
|
||||
Error::ProxyConnect => "Proxy failed to connect".to_string(),
|
||||
Error::InvalidProxyCreds => "Provided proxy credentials are incorrect".to_string(),
|
||||
#[cfg(feature = "native-tls")]
|
||||
Error::TlsError(err) => format!("TLS Error: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//! * Obvious API
|
||||
//!
|
||||
//! ```
|
||||
//! # #[cfg(feature = "json")] {
|
||||
//! // requires feature: `ureq = { version = "*", features = ["json"] }`
|
||||
//! # #[cfg(feature = "json")] {
|
||||
//! use ureq::json;
|
||||
@@ -195,7 +196,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
fn connect_https_google() {
|
||||
let resp = get("https://www.google.com/").call();
|
||||
assert_eq!(
|
||||
@@ -206,7 +207,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
fn connect_https_invalid_name() {
|
||||
let resp = get("https://example.com{REQUEST_URI}/").call();
|
||||
assert_eq!(400, resp.status());
|
||||
|
||||
@@ -29,12 +29,12 @@ impl ConnectionPool {
|
||||
self.recycle.remove(&PoolKey::new(url))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, any(feature = "tls", feature = "native-tls")))]
|
||||
pub fn len(&self) -> usize {
|
||||
self.recycle.len()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, any(feature = "tls", feature = "native-tls")))]
|
||||
pub fn get(&self, hostname: &str, port: u16) -> Option<&Stream> {
|
||||
let key = PoolKey {
|
||||
hostname: hostname.into(),
|
||||
|
||||
@@ -12,6 +12,9 @@ use rustls::StreamOwned;
|
||||
#[cfg(feature = "socks-proxy")]
|
||||
use socks::{TargetAddr, ToTargetAddr};
|
||||
|
||||
#[cfg(feature = "native-tls")]
|
||||
use native_tls::{TlsConnector, TlsStream, HandshakeError};
|
||||
|
||||
use crate::proxy::Proto;
|
||||
use crate::proxy::Proxy;
|
||||
|
||||
@@ -23,6 +26,8 @@ pub enum Stream {
|
||||
Http(TcpStream),
|
||||
#[cfg(feature = "tls")]
|
||||
Https(rustls::StreamOwned<rustls::ClientSession, TcpStream>),
|
||||
#[cfg(feature = "native-tls")]
|
||||
Https(TlsStream<TcpStream>),
|
||||
Cursor(Cursor<Vec<u8>>),
|
||||
#[cfg(test)]
|
||||
Test(Box<dyn Read + Send>, Vec<u8>),
|
||||
@@ -35,7 +40,7 @@ impl ::std::fmt::Debug for Stream {
|
||||
"Stream[{}]",
|
||||
match self {
|
||||
Stream::Http(_) => "http",
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
Stream::Https(_) => "https",
|
||||
Stream::Cursor(_) => "cursor",
|
||||
#[cfg(test)]
|
||||
@@ -76,7 +81,7 @@ impl Stream {
|
||||
pub fn is_poolable(&self) -> bool {
|
||||
match self {
|
||||
Stream::Http(_) => true,
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
Stream::Https(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
@@ -95,7 +100,7 @@ impl Read for Stream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
match self {
|
||||
Stream::Http(sock) => sock.read(buf),
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
Stream::Https(stream) => read_https(stream, buf),
|
||||
Stream::Cursor(read) => read.read(buf),
|
||||
#[cfg(test)]
|
||||
@@ -116,7 +121,20 @@ fn read_https(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "native-tls")]
|
||||
fn read_https(
|
||||
stream: &mut TlsStream<TcpStream>,
|
||||
buf: &mut [u8],
|
||||
) -> IoResult<usize> {
|
||||
match stream.read(buf) {
|
||||
Ok(size) => Ok(size),
|
||||
Err(ref e) if is_close_notify(e) => Ok(0),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
fn is_close_notify(e: &std::io::Error) -> bool {
|
||||
if e.kind() != ErrorKind::ConnectionAborted {
|
||||
return false;
|
||||
@@ -135,7 +153,7 @@ impl Write for Stream {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
|
||||
match self {
|
||||
Stream::Http(sock) => sock.write(buf),
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
Stream::Https(stream) => stream.write(buf),
|
||||
Stream::Cursor(_) => panic!("Write to read only stream"),
|
||||
#[cfg(test)]
|
||||
@@ -145,7 +163,7 @@ impl Write for Stream {
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
match self {
|
||||
Stream::Http(sock) => sock.flush(),
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
Stream::Https(stream) => stream.flush(),
|
||||
Stream::Cursor(_) => panic!("Flush read only stream"),
|
||||
#[cfg(test)]
|
||||
@@ -162,6 +180,7 @@ pub(crate) fn connect_http(unit: &Unit) -> Result<Stream, Error> {
|
||||
connect_host(unit, hostname, port).map(Stream::Http)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(all(feature = "tls", feature = "native-certs"))]
|
||||
fn configure_certs(config: &mut rustls::ClientConfig) {
|
||||
config.root_store =
|
||||
@@ -204,6 +223,23 @@ pub(crate) fn connect_https(unit: &Unit) -> Result<Stream, Error> {
|
||||
Ok(Stream::Https(stream))
|
||||
}
|
||||
|
||||
#[cfg(feature = "native-tls")]
|
||||
pub(crate) fn connect_https(unit: &Unit) -> Result<Stream, Error> {
|
||||
let hostname = unit.url.host_str().unwrap();
|
||||
let port = unit.url.port().unwrap_or(443);
|
||||
let sock = connect_host(unit, hostname, port)?;
|
||||
|
||||
let tls_connector = TlsConnector::new().map_err(|e| Error::TlsError(e))?;
|
||||
let stream = tls_connector.connect(hostname, sock).map_err(|e| {
|
||||
match e {
|
||||
HandshakeError::Failure(err) => Error::TlsError(err),
|
||||
_ => Error::BadStatusRead,
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok(Stream::Https(stream))
|
||||
}
|
||||
|
||||
pub(crate) fn connect_host(unit: &Unit, hostname: &str, port: u16) -> Result<TcpStream, Error> {
|
||||
//
|
||||
let sock_addrs: Vec<SocketAddr> = match unit.proxy {
|
||||
@@ -470,7 +506,8 @@ pub(crate) fn connect_test(unit: &Unit) -> Result<Stream, Error> {
|
||||
Err(Error::UnknownScheme(unit.url.scheme().to_string()))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tls"))]
|
||||
#[cfg(not(any(feature = "tls", feature = "native-tls")))]
|
||||
pub(crate) fn connect_https(unit: &Unit) -> Result<Stream, Error> {
|
||||
Err(Error::UnknownScheme(unit.url.scheme().to_string()))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
use std::io::Read;
|
||||
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
use super::super::*;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
fn read_range() {
|
||||
let resp = get("https://ureq.s3.eu-central-1.amazonaws.com/sherlock.txt")
|
||||
.set("Range", "bytes=1000-1999")
|
||||
@@ -20,7 +22,7 @@ fn read_range() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "tls")]
|
||||
#[cfg(any(feature = "tls", feature = "native-tls"))]
|
||||
fn agent_pool() {
|
||||
let agent = agent();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user