Ensure we provide a Transport::message() when we can

This commit is contained in:
Martin Algesten
2021-12-19 12:46:27 +01:00
parent 6a094db668
commit f3857eed00
7 changed files with 39 additions and 22 deletions

View File

@@ -356,8 +356,8 @@ impl ErrorKind {
Error::new(self, None) Error::new(self, None)
} }
pub(crate) fn msg(self, s: &str) -> Error { pub(crate) fn msg(self, s: impl Into<String>) -> Error {
Error::new(self, Some(s.to_string())) Error::new(self, Some(s.into()))
} }
} }
@@ -382,7 +382,7 @@ impl From<Transport> for Error {
impl From<ParseError> for Error { impl From<ParseError> for Error {
fn from(err: ParseError) -> Self { fn from(err: ParseError) -> Self {
ErrorKind::InvalidUrl ErrorKind::InvalidUrl
.msg(&format!("failed to parse URL: {:?}", err)) .msg(format!("failed to parse URL: {:?}", err))
.src(err) .src(err)
} }
} }

View File

@@ -143,7 +143,7 @@ impl Header {
let value_raw = &bytes[self.index + 1..]; let value_raw = &bytes[self.index + 1..];
if !valid_name(name_raw) || !valid_value(value_raw) { if !valid_name(name_raw) || !valid_value(value_raw) {
Err(ErrorKind::BadHeader.msg(&format!("invalid header '{}'", self.line))) Err(ErrorKind::BadHeader.msg(format!("invalid header '{}'", self.line)))
} else { } else {
Ok(()) Ok(())
} }

View File

@@ -16,8 +16,13 @@ impl TlsConnector for native_tls::TlsConnector {
dns_name: &str, dns_name: &str,
tcp_stream: TcpStream, tcp_stream: TcpStream,
) -> Result<Box<dyn HttpsStream>, Error> { ) -> Result<Box<dyn HttpsStream>, Error> {
let stream = native_tls::TlsConnector::connect(self, dns_name, tcp_stream) let stream =
.map_err(|e| ErrorKind::Dns.new().src(e))?; native_tls::TlsConnector::connect(self, dns_name, tcp_stream).map_err(|e| {
ErrorKind::ConnectionFailed
.msg("native_tls connect failed")
.src(e)
})?;
Ok(Box::new(stream)) Ok(Box::new(stream))
} }
} }

View File

@@ -613,7 +613,9 @@ fn parse_status_line(line: &str) -> Result<(ResponseStatusIndex, u16), Error> {
return Err(BadStatus.msg("Status code was wrong length")); return Err(BadStatus.msg("Status code was wrong length"));
} }
let status: u16 = status_str.parse().map_err(|_| BadStatus.new())?; let status: u16 = status_str
.parse()
.map_err(|_| BadStatus.msg(format!("unable to parse status as u16 ({})", status_str)))?;
Ok(( Ok((
ResponseStatusIndex { ResponseStatusIndex {

View File

@@ -95,14 +95,20 @@ impl TlsConnector for Arc<rustls::ClientConfig> {
dns_name: &str, dns_name: &str,
mut tcp_stream: TcpStream, mut tcp_stream: TcpStream,
) -> Result<Box<dyn HttpsStream>, Error> { ) -> Result<Box<dyn HttpsStream>, Error> {
let sni = let sni = rustls::ServerName::try_from(dns_name).map_err(|e| {
rustls::ServerName::try_from(dns_name).map_err(|e| ErrorKind::Dns.new().src(e))?; ErrorKind::Dns
.msg(format!("dns server name failed ({})", dns_name))
.src(e)
})?;
let mut sess = rustls::ClientConnection::new(self.clone(), sni) let mut sess = rustls::ClientConnection::new(self.clone(), sni)
.map_err(|e| ErrorKind::Io.new().src(e))?; .map_err(|e| ErrorKind::Io.msg("tls connection creation failed").src(e))?;
sess.complete_io(&mut tcp_stream) sess.complete_io(&mut tcp_stream).map_err(|e| {
.map_err(|err| ErrorKind::ConnectionFailed.new().src(err))?; ErrorKind::ConnectionFailed
.msg("tls connection init failed")
.src(e)
})?;
let stream = rustls::StreamOwned::new(sess, tcp_stream); let stream = rustls::StreamOwned::new(sess, tcp_stream);
Ok(Box::new(RustlsStream(stream))) Ok(Box::new(RustlsStream(stream)))

View File

@@ -350,13 +350,14 @@ pub(crate) fn connect_host(unit: &Unit, hostname: &str, port: u16) -> Result<Tcp
}; };
// TODO: Find a way to apply deadline to DNS lookup. // TODO: Find a way to apply deadline to DNS lookup.
let sock_addrs = unit let sock_addrs = unit.resolver().resolve(&netloc).map_err(|e| {
.resolver() ErrorKind::Dns
.resolve(&netloc) .msg(format!("failed to resove dns ({})", netloc))
.map_err(|e| ErrorKind::Dns.new().src(e))?; .src(e)
})?;
if sock_addrs.is_empty() { if sock_addrs.is_empty() {
return Err(ErrorKind::Dns.msg(&format!("No ip address for {}", hostname))); return Err(ErrorKind::Dns.msg(format!("No ip address for {}", hostname)));
} }
let proto = proxy.as_ref().map(|proxy| proxy.proto); let proto = proxy.as_ref().map(|proxy| proxy.proto);
@@ -621,5 +622,5 @@ pub(crate) fn connect_test(unit: &Unit) -> Result<Stream, Error> {
#[cfg(not(test))] #[cfg(not(test))]
pub(crate) fn connect_test(unit: &Unit) -> Result<Stream, Error> { pub(crate) fn connect_test(unit: &Unit) -> Result<Stream, Error> {
Err(ErrorKind::UnknownScheme.msg(&format!("unknown scheme '{}'", unit.url.scheme()))) Err(ErrorKind::UnknownScheme.msg(format!("unknown scheme '{}'", unit.url.scheme())))
} }

View File

@@ -168,7 +168,10 @@ pub(crate) fn connect(
break resp; break resp;
} }
if history.len() + 1 >= unit.agent.config.redirects as usize { if history.len() + 1 >= unit.agent.config.redirects as usize {
return Err(ErrorKind::TooManyRedirects.new()); return Err(ErrorKind::TooManyRedirects.msg(format!(
"reached max redirects ({})",
unit.agent.config.redirects
)));
} }
// the location header // the location header
let location = match resp.header("location") { let location = match resp.header("location") {
@@ -181,7 +184,7 @@ pub(crate) fn connect(
// join location header to current url in case it is relative // join location header to current url in case it is relative
let new_url = url.join(location).map_err(|e| { let new_url = url.join(location).map_err(|e| {
ErrorKind::InvalidUrl ErrorKind::InvalidUrl
.msg(&format!("Bad redirection: {}", location)) .msg(format!("Bad redirection: {}", location))
.src(e) .src(e)
})?; })?;
@@ -340,7 +343,7 @@ fn extract_cookies(agent: &Agent, url: &Url) -> Option<Header> {
fn connect_socket(unit: &Unit, hostname: &str, use_pooled: bool) -> Result<(Stream, bool), Error> { fn connect_socket(unit: &Unit, hostname: &str, use_pooled: bool) -> Result<(Stream, bool), Error> {
match unit.url.scheme() { match unit.url.scheme() {
"http" | "https" | "test" => (), "http" | "https" | "test" => (),
scheme => return Err(ErrorKind::UnknownScheme.msg(&format!("unknown scheme '{}'", scheme))), scheme => return Err(ErrorKind::UnknownScheme.msg(format!("unknown scheme '{}'", scheme))),
}; };
if use_pooled { if use_pooled {
let pool = &unit.agent.state.pool; let pool = &unit.agent.state.pool;
@@ -360,7 +363,7 @@ fn connect_socket(unit: &Unit, hostname: &str, use_pooled: bool) -> Result<(Stre
"http" => stream::connect_http(unit, hostname), "http" => stream::connect_http(unit, hostname),
"https" => stream::connect_https(unit, hostname), "https" => stream::connect_https(unit, hostname),
"test" => connect_test(unit), "test" => connect_test(unit),
scheme => Err(ErrorKind::UnknownScheme.msg(&format!("unknown scheme {}", scheme))), scheme => Err(ErrorKind::UnknownScheme.msg(format!("unknown scheme {}", scheme))),
}; };
Ok((stream?, false)) Ok((stream?, false))
} }