diff --git a/lib/Cargo.toml b/lib/Cargo.toml index eef84bb9ef..0ac922c634 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -16,7 +16,9 @@ license = "MIT" [features] openssl = ["hyper-tls"] -rustls = ["hyper-rustls"] +rustls = ["rustls-webpki-roots"] +rustls-native-roots = ["dep:hyper-rustls", "hyper-rustls/ring", "hyper-rustls/native-tokio"] +rustls-webpki-roots = ["dep:hyper-rustls", "hyper-rustls/ring", "hyper-rustls/webpki-roots"] default = ["openssl"] [dependencies] bytes = "1.0.1" @@ -24,14 +26,16 @@ tokio = { version = "1.2", features = ["fs", "rt"]} tracing = "0.1.23" tracing-futures = "0.2" -multipart = { version = "0.17", default-features = false, features = ["client"] } +multipart = { version = "0.18", default-features = false, features = ["client"] } telegram-bot-raw = { version = "0.9.0", path = "../raw" } -hyper = { version = "0.14", features = ["client", "http1"] } -hyper-tls = { version = "0.5", optional = true } +hyper = { version = "1", features = ["client", "http1"] } +hyper-tls = { version = "0.6", optional = true } +hyper-util = { version = "0.1.9", features = ["client", "client-legacy", "http1"] } +http-body-util = "0.1.2" futures = "0.3" -hyper-rustls = { version = "0.22", optional = true } +hyper-rustls = { version = "0.27", optional = true, default-features = false, features = ["http1", "tls12"] } [dev-dependencies] -tracing-subscriber = "0.2.15" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tokio = { version = "1.2", features = ["macros", "time", "fs", "rt-multi-thread"] } diff --git a/lib/src/connector/hyper.rs b/lib/src/connector/hyper.rs index f6d82ef8f3..f092188161 100644 --- a/lib/src/connector/hyper.rs +++ b/lib/src/connector/hyper.rs @@ -5,17 +5,12 @@ use std::str::FromStr; use bytes::Bytes; use futures::{Future, FutureExt}; -use hyper::{ - body::to_bytes, - client::{connect::Connect, Client}, - header::CONTENT_TYPE, - http::Error as HttpError, - Method, Request, Uri, +use http_body_util::{BodyExt, Full}; +use hyper::{header::CONTENT_TYPE, http::Error as HttpError, Method, Request, Uri}; +use hyper_util::{ + client::legacy::{connect::Connect, Client}, + rt::TokioExecutor, }; -#[cfg(feature = "rustls")] -use hyper_rustls::HttpsConnector; -#[cfg(feature = "openssl")] -use hyper_tls::HttpsConnector; use multipart::client::lazy::Multipart; use telegram_bot_raw::{ Body as TelegramBody, HttpRequest, HttpResponse, Method as TelegramMethod, MultipartValue, Text, @@ -25,7 +20,7 @@ use super::Connector; use crate::errors::{Error, ErrorKind}; #[derive(Debug)] -pub struct HyperConnector(Client); +pub struct HyperConnector(Client>); enum MultipartTemporaryValue { Text(Text), @@ -33,7 +28,7 @@ enum MultipartTemporaryValue { } impl HyperConnector { - pub fn new(client: Client) -> Self { + pub fn new(client: Client>) -> Self { HyperConnector(client) } } @@ -58,7 +53,7 @@ impl Connector for let mut http_request = Request::builder().method(method).uri(uri); let request = match req.body { - TelegramBody::Empty => http_request.body(Into::::into(vec![])), + TelegramBody::Empty => http_request.body(Full::new(Bytes::new())), TelegramBody::Json(body) => { let content_type = "application/json" .parse() @@ -67,7 +62,7 @@ impl Connector for http_request .headers_mut() .map(move |headers| headers.insert(CONTENT_TYPE, content_type)); - http_request.body(Into::::into(body)) + http_request.body(Full::new(body.into())) } TelegramBody::Multipart(parts) => { let mut fields = Vec::new(); @@ -141,12 +136,12 @@ impl Connector for .map_err(ErrorKind::from)?; let response = client.request(request).await.map_err(ErrorKind::from)?; - let whole_chunk = to_bytes(response.into_body()).await; + let whole_chunk = response.into_body().collect().await; let body = whole_chunk - .iter() + .into_iter() .fold(vec![], |mut acc, chunk| -> Vec { - acc.extend_from_slice(&chunk); + acc.extend_from_slice(&chunk.to_bytes()); acc }); @@ -158,13 +153,29 @@ impl Connector for } pub fn default_connector() -> Result, Error> { - #[cfg(feature = "rustls")] - let connector = HttpsConnector::with_native_roots(); + #[cfg(any(feature = "rustls-native-roots", feature = "rustls-webpki-roots"))] + let connector = { + let builder = hyper_rustls::HttpsConnectorBuilder::new(); + + #[cfg(feature = "rustls-native-roots")] + let builder = builder + .with_native_roots() + .expect("no native root CA certificates found"); + + #[cfg(feature = "rustls-webpki-roots")] + let builder = builder.with_webpki_roots(); + + builder.https_only().enable_http1().build() + }; #[cfg(feature = "openssl")] - let connector = HttpsConnector::new(); + let connector = { + let mut connector = hyper_tls::HttpsConnector::new(); + connector.https_only(true); + connector + }; Ok(Box::new(HyperConnector::new( - Client::builder().build(connector), + Client::builder(TokioExecutor::new()).build(connector), ))) } diff --git a/lib/src/errors.rs b/lib/src/errors.rs index 8ee859264e..6e878996e5 100644 --- a/lib/src/errors.rs +++ b/lib/src/errors.rs @@ -7,7 +7,7 @@ pub struct Error(ErrorKind); #[derive(Debug)] pub(crate) enum ErrorKind { Raw(telegram_bot_raw::Error), - Hyper(hyper::Error), + Hyper(hyper_util::client::legacy::Error), Http(hyper::http::Error), Io(std::io::Error), InvalidMultipartFilename, @@ -19,8 +19,8 @@ impl From for ErrorKind { } } -impl From for ErrorKind { - fn from(error: hyper::Error) -> Self { +impl From for ErrorKind { + fn from(error: hyper_util::client::legacy::Error) -> Self { ErrorKind::Hyper(error) } }