diff --git a/interop/Cargo.toml b/interop/Cargo.toml index 8716118f4..fa7456239 100644 --- a/interop/Cargo.toml +++ b/interop/Cargo.toml @@ -15,11 +15,11 @@ structopt = "0.3.0" tokio = "0.2.0-alpha.5" tokio-net = "0.2.0-alpha.5" # tokio doesn't reexport everything we use rustls = { version = "0.16", features = ["dangerous_configuration"] } -failure = "0.1" futures = { package = "futures-preview", version = "0.3.0-alpha.18" } webpki = "0.21" tracing = "0.1.10" tracing-subscriber = "0.1.5" +anyhow = "1.0.22" [[bin]] name = "main" diff --git a/interop/src/main.rs b/interop/src/main.rs index 8e33f1bbf..f7c782dbf 100644 --- a/interop/src/main.rs +++ b/interop/src/main.rs @@ -3,14 +3,12 @@ use std::{ sync::{Arc, Mutex}, }; -use failure::{format_err, Error}; +use anyhow::{anyhow, Error, Result}; use futures::TryFutureExt; use structopt::StructOpt; use tokio::runtime::current_thread::Runtime; use tracing::{info, warn}; -type Result = std::result::Result; - #[derive(StructOpt, Debug)] #[structopt(name = "interop")] struct Opt { @@ -59,7 +57,7 @@ impl State { .endpoint .connect_with(self.client_config.clone(), &self.remote, &self.host)? .await - .map_err(|e| format_err!("failed to connect: {}", e))?; + .map_err(|e| anyhow!("failed to connect: {}", e))?; self.results.lock().unwrap().handshake = true; let results = self.results.clone(); tokio::runtime::current_thread::spawn( @@ -74,10 +72,10 @@ impl State { .connection .open_bi() .await - .map_err(|e| format_err!("failed to open stream: {}", e))?; + .map_err(|e| anyhow!("failed to open stream: {}", e))?; get(stream) .await - .map_err(|e| format_err!("simple request failed: {}", e))?; + .map_err(|e| anyhow!("simple request failed: {}", e))?; self.results.lock().unwrap().stream_data = true; new_conn.connection.close(0u32.into(), b"done"); @@ -93,10 +91,10 @@ impl State { .connection .open_bi() .await - .map_err(|e| format_err!("failed to open 0-RTT stream: {}", e))?; + .map_err(|e| anyhow!("failed to open 0-RTT stream: {}", e))?; get(stream) .await - .map_err(|e| format_err!("0-RTT request failed: {}", e))?; + .map_err(|e| anyhow!("0-RTT request failed: {}", e))?; self.results.lock().unwrap().zero_rtt = true; new_conn.connection } @@ -104,7 +102,7 @@ impl State { info!("0-RTT unsupported"); let new_conn = conn .await - .map_err(|e| format_err!("failed to connect: {}", e))?; + .map_err(|e| anyhow!("failed to connect: {}", e))?; tokio::runtime::current_thread::spawn(new_conn.driver.unwrap_or_else(|_| ())); new_conn.connection } @@ -123,20 +121,20 @@ impl State { .endpoint .connect_with(self.client_config.clone(), &self.remote, &self.host)? .await - .map_err(|e| format_err!("failed to connect: {}", e))?; + .map_err(|e| anyhow!("failed to connect: {}", e))?; tokio::runtime::current_thread::spawn(new_conn.driver.unwrap_or_else(|_| ())); let conn = new_conn.connection; // Make sure some traffic has gone both ways before the key update let stream = conn .open_bi() .await - .map_err(|e| format_err!("failed to open stream: {}", e))?; + .map_err(|e| anyhow!("failed to open stream: {}", e))?; get(stream).await?; conn.force_key_update(); let stream = conn .open_bi() .await - .map_err(|e| format_err!("failed to open stream: {}", e))?; + .map_err(|e| anyhow!("failed to open stream: {}", e))?; get(stream).await?; self.results.lock().unwrap().key_update = true; conn.close(0u32.into(), b"done"); @@ -151,13 +149,13 @@ impl State { .endpoint .connect_with(self.client_config.clone(), &self.remote, &self.host)? .await - .map_err(|e| format_err!("failed to connect: {}", e))?; + .map_err(|e| anyhow!("failed to connect: {}", e))?; tokio::runtime::current_thread::spawn(new_conn.driver.unwrap_or_else(|_| ())); let stream = new_conn .connection .open_bi() .await - .map_err(|e| format_err!("failed to open stream: {}", e))?; + .map_err(|e| anyhow!("failed to open stream: {}", e))?; get(stream).await?; self.results.lock().unwrap().retry = true; new_conn.connection.close(0u32.into(), b"done"); @@ -174,7 +172,7 @@ impl State { let new_conn = endpoint .connect_with(self.client_config.clone(), &self.remote, &self.host)? .await - .map_err(|e| format_err!("failed to connect: {}", e))?; + .map_err(|e| anyhow!("failed to connect: {}", e))?; tokio::runtime::current_thread::spawn(new_conn.driver.unwrap_or_else(|_| ())); let socket = std::net::UdpSocket::bind("[::]:0").unwrap(); endpoint.rebind(socket, &tokio_net::driver::Handle::default())?; @@ -182,7 +180,7 @@ impl State { .connection .open_bi() .await - .map_err(|e| format_err!("failed to open stream: {}", e))?; + .map_err(|e| anyhow!("failed to open stream: {}", e))?; get(stream).await?; self.results.lock().unwrap().rebinding = true; new_conn.connection.close(0u32.into(), b"done"); @@ -194,14 +192,14 @@ impl State { let (quic_driver, h3_driver, conn) = h3_client .connect(&self.remote, &self.host)? .await - .map_err(|e| format_err!("h3 failed to connect: {}", e))?; + .map_err(|e| anyhow!("h3 failed to connect: {}", e))?; tokio::runtime::current_thread::spawn(h3_driver.unwrap_or_else(|_| ())); tokio::runtime::current_thread::spawn(quic_driver.unwrap_or_else(|_| ())); h3_get(&conn) .await - .map_err(|e| format_err!("h3 request failed: {}", e))?; + .map_err(|e| anyhow!("h3 request failed: {}", e))?; conn.close(); self.results.lock().unwrap().h3 = true; @@ -228,7 +226,7 @@ fn run(options: Opt) -> Result<()> { let remote = format!("{}:{}", options.host, options.port) .to_socket_addrs()? .next() - .ok_or_else(|| format_err!("couldn't resolve to an address"))?; + .ok_or_else(|| anyhow!("couldn't resolve to an address"))?; let host = if webpki::DNSNameRef::try_from_ascii_str(&options.host).is_ok() { &options.host } else { @@ -368,14 +366,14 @@ async fn get(stream: (quinn::SendStream, quinn::RecvStream)) -> Result> let (mut send, recv) = stream; send.write_all(b"GET /index.html\r\n") .await - .map_err(|e| format_err!("failed to send request: {}", e))?; + .map_err(|e| anyhow!("failed to send request: {}", e))?; send.finish() .await - .map_err(|e| format_err!("failed to shutdown stream: {}", e))?; + .map_err(|e| anyhow!("failed to shutdown stream: {}", e))?; let response = recv .read_to_end(usize::max_value()) .await - .map_err(|e| format_err!("failed to read response: {}", e))?; + .map_err(|e| anyhow!("failed to read response: {}", e))?; Ok(response) } diff --git a/quinn-h3/Cargo.toml b/quinn-h3/Cargo.toml index 1cf7fa8e6..78ce6ebb4 100644 --- a/quinn-h3/Cargo.toml +++ b/quinn-h3/Cargo.toml @@ -39,7 +39,7 @@ tokio-codec = "0.2.0-alpha.5" [dev-dependencies] assert_matches = "1.1" directories = "2.0.1" -failure = "0.1" +anyhow = "1.0.22" proptest = "0.9.1" rand = "0.7.0" rcgen = "0.7" diff --git a/quinn-h3/examples/h3.rs b/quinn-h3/examples/h3.rs index 0c62a8f36..979d1533d 100644 --- a/quinn-h3/examples/h3.rs +++ b/quinn-h3/examples/h3.rs @@ -5,7 +5,7 @@ use std::{ time::Instant, }; -use failure::{format_err, Error}; +use anyhow::{anyhow, Result}; use futures::{StreamExt, TryFutureExt}; use http::{header::HeaderValue, method::Method, HeaderMap, Request, Response, StatusCode}; use structopt::{self, StructOpt}; @@ -42,7 +42,7 @@ struct Opt { } #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<()> { tracing::subscriber::set_global_default( tracing_subscriber::FmtSubscriber::builder() .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) @@ -85,10 +85,7 @@ async fn main() -> Result<(), Box> { ::std::process::exit(0); } -fn server( - options: Opt, - certs: (CertificateChain, PrivateKey), -) -> Result { +fn server(options: Opt, certs: (CertificateChain, PrivateKey)) -> Result { let server_config = quinn::ServerConfig { transport: Arc::new(quinn::TransportConfig { stream_window_uni: 513, @@ -116,7 +113,7 @@ fn server( println!("server received connection"); let connection = connecting .await - .map_err(|e| format_err!("accept failed: {:?}", e)) + .map_err(|e| anyhow!("accept failed: {:?}", e)) .expect("server failed"); println!("received connection"); handle_connection(connection).await @@ -148,13 +145,13 @@ async fn handle_connection(conn: (QuicDriver, ConnectionDriver, IncomingRequest) } } -async fn handle_request(request: Request, sender: Sender) -> Result<(), Error> { +async fn handle_request(request: Request, sender: Sender) -> Result<()> { println!("received request: {:?}", request); let (_, body) = request.into_parts(); let (content, trailers) = body .read_to_end(1024, 10 * 1024) .await - .map_err(|e| format_err!("receive body failed: {:?}", e))?; + .map_err(|e| anyhow!("receive body failed: {:?}", e))?; if let Some(content) = content { println!("server received body len: {:?}", content.len()); @@ -179,7 +176,7 @@ async fn handle_request(request: Request, sender: Sender) -> Result<() .trailers(trailer) .stream() .await - .map_err(|e| format_err!("receive response failed: {:?}", e))?; + .map_err(|e| anyhow!("receive response failed: {:?}", e))?; let response_body = "r".repeat(1024); println!("sending body"); @@ -187,12 +184,12 @@ async fn handle_request(request: Request, sender: Sender) -> Result<() println!("sent body"); writer .close() - .map_err(|e| format_err!("close failed: {:?}", e)) + .map_err(|e| anyhow!("close failed: {:?}", e)) .await?; Ok(()) } -fn build_client(cert: Certificate) -> Result<(Client, quinn::EndpointDriver), Error> { +fn build_client(cert: Certificate) -> Result<(Client, quinn::EndpointDriver)> { let mut endpoint = quinn::Endpoint::builder(); let mut client_config = quinn::ClientConfigBuilder::default(); client_config.protocols(&[quinn_h3::ALPN]); @@ -207,12 +204,12 @@ fn build_client(cert: Certificate) -> Result<(Client, quinn::EndpointDriver), Er )) } -async fn client_request(client: Client, remote: &SocketAddr) -> Result<(), Error> { +async fn client_request(client: Client, remote: &SocketAddr) -> Result<()> { let start = Instant::now(); let (quic_driver, h3_driver, conn) = client .connect(&remote, "localhost")? .await - .map_err(|e| format_err!("failed ot connect: {:?}", e))?; + .map_err(|e| anyhow!("failed ot connect: {:?}", e))?; eprintln!("client connected at {:?}", start.elapsed()); tokio::spawn(async move { diff --git a/quinn-h3/examples/shared/mod.rs b/quinn-h3/examples/shared/mod.rs index 8e38d528b..c97e1770c 100644 --- a/quinn-h3/examples/shared/mod.rs +++ b/quinn-h3/examples/shared/mod.rs @@ -1,35 +1,9 @@ -use std::{fmt, fs, io, path::PathBuf}; +use std::{fs, io, path::PathBuf}; -use failure::{bail, Error, Fail, ResultExt}; +use anyhow::{bail, Context, Result}; use quinn_proto::crypto::rustls::{Certificate, CertificateChain, PrivateKey}; use tracing::info; -pub type Result = std::result::Result; - -pub struct PrettyErr<'a>(&'a dyn Fail); -impl<'a> fmt::Display for PrettyErr<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.0, f)?; - let mut x: &dyn Fail = self.0; - while let Some(cause) = x.cause() { - f.write_str(": ")?; - fmt::Display::fmt(&cause, f)?; - x = cause; - } - Ok(()) - } -} - -pub trait ErrorExt { - fn pretty(&self) -> PrettyErr<'_>; -} - -impl ErrorExt for Error { - fn pretty(&self) -> PrettyErr<'_> { - PrettyErr(self.as_fail()) - } -} - pub fn build_certs( key: &Option, cert: &Option, diff --git a/quinn-h3/examples/simple_client.rs b/quinn-h3/examples/simple_client.rs index 36a767eab..824bf4364 100644 --- a/quinn-h3/examples/simple_client.rs +++ b/quinn-h3/examples/simple_client.rs @@ -4,7 +4,7 @@ use std::{ }; use structopt::{self, StructOpt}; -use failure::{format_err, Error}; +use anyhow::{anyhow, Result}; use http::{header::HeaderValue, method::Method, HeaderMap, Request}; use url::Url; @@ -33,7 +33,7 @@ const INITIAL_CAPACITY: usize = 256; const MAX_LEN: usize = 256 * 1024; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<()> { tracing::subscriber::set_global_default( tracing_subscriber::FmtSubscriber::builder() .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) @@ -73,11 +73,11 @@ async fn main() -> Result<(), Box> { Ok(()) } -async fn request(client: Client, remote: &SocketAddr) -> Result<(), Error> { +async fn request(client: Client, remote: &SocketAddr) -> Result<()> { let (quic_driver, h3_driver, conn) = client .connect(&remote, "localhost")? .await - .map_err(|e| format_err!("failed ot connect: {:?}", e))?; + .map_err(|e| anyhow!("failed ot connect: {:?}", e))?; tokio::spawn(async move { if let Err(e) = h3_driver.await { diff --git a/quinn-h3/examples/simple_server.rs b/quinn-h3/examples/simple_server.rs index f1898cd1b..c8dca7d59 100644 --- a/quinn-h3/examples/simple_server.rs +++ b/quinn-h3/examples/simple_server.rs @@ -1,6 +1,6 @@ use std::{net::SocketAddr, path::PathBuf, sync::Arc}; -use failure::{format_err, Error}; +use anyhow::{anyhow, Result}; use futures::StreamExt; use http::{Request, Response, StatusCode}; use structopt::{self, StructOpt}; @@ -32,7 +32,7 @@ struct Opt { } #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<()> { tracing::subscriber::set_global_default( tracing_subscriber::FmtSubscriber::builder() .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) @@ -76,7 +76,7 @@ async fn main() -> Result<(), Box> { println!("server received connection"); let connection = connecting .await - .map_err(|e| format_err!("accept failed: {:?}", e)) + .map_err(|e| anyhow!("accept failed: {:?}", e)) .expect("server failed"); handle_connection(connection) @@ -87,9 +87,7 @@ async fn main() -> Result<(), Box> { Ok(()) } -async fn handle_connection( - conn: (QuicDriver, ConnectionDriver, IncomingRequest), -) -> Result<(), Error> { +async fn handle_connection(conn: (QuicDriver, ConnectionDriver, IncomingRequest)) -> Result<()> { let (quic_driver, h3_driver, mut incoming) = conn; tokio::spawn(async move { @@ -119,7 +117,7 @@ async fn handle_connection( const INITIAL_CAPACITY: usize = 256; const MAX_LEN: usize = 256; -async fn handle_request(request: Request, sender: Sender) -> Result<(), Error> { +async fn handle_request(request: Request, sender: Sender) -> Result<()> { println!("received request: {:?}", request); let (_, body) = request.into_parts(); @@ -127,7 +125,7 @@ async fn handle_request(request: Request, sender: Sender) -> Result<() let (content, trailers) = body .read_to_end(INITIAL_CAPACITY, MAX_LEN) .await - .map_err(|e| format_err!("failed to send response headers: {:?}", e))?; + .map_err(|e| anyhow!("failed to send response headers: {:?}", e))?; if let Some(content) = content { println!("received body: {}", String::from_utf8_lossy(&content)); @@ -146,7 +144,7 @@ async fn handle_request(request: Request, sender: Sender) -> Result<() .response(response) .send() .await - .map_err(|e| format_err!("failed to send response: {:?}", e))?; + .map_err(|e| anyhow!("failed to send response: {:?}", e))?; Ok(()) } diff --git a/quinn/Cargo.toml b/quinn/Cargo.toml index 12bef5384..bfb52c786 100644 --- a/quinn/Cargo.toml +++ b/quinn/Cargo.toml @@ -44,7 +44,6 @@ rustls-native-certs = { version = "0.1.0", optional = true } crc = "1.8.1" criterion = "0.3" directories = "2.0.0" -failure = "0.1" rand = "0.7" rcgen = "0.7" tracing-subscriber = "0.1.5" @@ -53,6 +52,7 @@ structopt = "0.3.0" tokio = "0.2.0-alpha.5" unwrap = "1.2.1" url = "2" +anyhow = "1.0.22" [[example]] name = "server" diff --git a/quinn/examples/client.rs b/quinn/examples/client.rs index 753d3d99b..263c20190 100644 --- a/quinn/examples/client.rs +++ b/quinn/examples/client.rs @@ -1,6 +1,3 @@ -#[macro_use] -extern crate failure; - use std::{ fs, io::{self, Write}, @@ -9,7 +6,7 @@ use std::{ time::{Duration, Instant}, }; -use failure::Error; +use anyhow::{anyhow, Result}; use futures::TryFutureExt; use structopt::StructOpt; use tokio::runtime::current_thread::Runtime; @@ -18,8 +15,6 @@ use url::Url; mod common; -type Result = std::result::Result; - /// HTTP/0.9 over QUIC client #[derive(StructOpt, Debug)] #[structopt(name = "client")] @@ -67,7 +62,7 @@ fn run(options: Opt) -> Result<()> { let remote = (url.host_str().unwrap(), url.port().unwrap_or(4433)) .to_socket_addrs()? .next() - .ok_or(format_err!("couldn't resolve to an address"))?; + .ok_or(anyhow!("couldn't resolve to an address"))?; let mut endpoint = quinn::Endpoint::builder(); let mut client_config = quinn::ClientConfigBuilder::default(); @@ -106,12 +101,12 @@ fn run(options: Opt) -> Result<()> { .host .as_ref() .map_or_else(|| url.host_str(), |x| Some(&x)) - .ok_or(format_err!("no hostname specified"))?; + .ok_or(anyhow!("no hostname specified"))?; let r: Result<()> = runtime.block_on(async { let new_conn = endpoint .connect(&remote, &host)? .await - .map_err(|e| format_err!("failed to connect: {}", e))?; + .map_err(|e| anyhow!("failed to connect: {}", e))?; eprintln!("connected at {:?}", start.elapsed()); tokio::runtime::current_thread::spawn( new_conn @@ -122,7 +117,7 @@ fn run(options: Opt) -> Result<()> { let (mut send, recv) = conn .open_bi() .await - .map_err(|e| format_err!("failed to open stream: {}", e))?; + .map_err(|e| anyhow!("failed to open stream: {}", e))?; if rebind { let socket = std::net::UdpSocket::bind("[::]:0").unwrap(); let addr = socket.local_addr().unwrap(); @@ -134,16 +129,16 @@ fn run(options: Opt) -> Result<()> { send.write_all(request.as_bytes()) .await - .map_err(|e| format_err!("failed to send request: {}", e))?; + .map_err(|e| anyhow!("failed to send request: {}", e))?; send.finish() .await - .map_err(|e| format_err!("failed to shutdown stream: {}", e))?; + .map_err(|e| anyhow!("failed to shutdown stream: {}", e))?; let response_start = Instant::now(); eprintln!("request sent at {:?}", response_start - start); let resp = recv .read_to_end(usize::max_value()) .await - .map_err(|e| format_err!("failed to read response: {}", e))?; + .map_err(|e| anyhow!("failed to read response: {}", e))?; let duration = response_start.elapsed(); eprintln!( "response received in {:?} - {} KiB/s", diff --git a/quinn/examples/server.rs b/quinn/examples/server.rs index 1d0a8bd17..3104c048a 100644 --- a/quinn/examples/server.rs +++ b/quinn/examples/server.rs @@ -1,6 +1,3 @@ -#[macro_use] -extern crate failure; - use std::{ ascii, fs, io, net::SocketAddr, @@ -9,7 +6,7 @@ use std::{ sync::Arc, }; -use failure::{Error, ResultExt}; +use anyhow::{anyhow, bail, Context, Result}; use futures::{StreamExt, TryFutureExt}; use structopt::{self, StructOpt}; use tokio::runtime::Runtime; @@ -18,8 +15,6 @@ use tracing_futures::Instrument as _; mod common; -type Result = std::result::Result; - #[derive(StructOpt, Debug)] #[structopt(name = "server")] struct Opt { @@ -201,7 +196,7 @@ async fn handle_request( let req = recv .read_to_end(64 * 1024) .await - .map_err(|e| format_err!("failed reading request: {}", e))?; + .map_err(|e| anyhow!("failed reading request: {}", e))?; let mut escaped = String::new(); for &x in &req[..] { let part = ascii::escape_default(x).collect::>(); @@ -218,11 +213,11 @@ async fn handle_request( // Write the response send.write_all(&resp) .await - .map_err(|e| format_err!("failed to send response: {}", e))?; + .map_err(|e| anyhow!("failed to send response: {}", e))?; // Gracefully terminate the stream send.finish() .await - .map_err(|e| format_err!("failed to shutdown stream: {}", e))?; + .map_err(|e| anyhow!("failed to shutdown stream: {}", e))?; info!("complete"); Ok(()) }