Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,26 @@ 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"
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"] }
53 changes: 32 additions & 21 deletions lib/src/connector/hyper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -25,15 +20,15 @@ use super::Connector;
use crate::errors::{Error, ErrorKind};

#[derive(Debug)]
pub struct HyperConnector<C>(Client<C>);
pub struct HyperConnector<C>(Client<C, Full<Bytes>>);

enum MultipartTemporaryValue {
Text(Text),
Data { file_name: Text, data: Bytes },
}

impl<C> HyperConnector<C> {
pub fn new(client: Client<C>) -> Self {
pub fn new(client: Client<C, Full<Bytes>>) -> Self {
HyperConnector(client)
}
}
Expand All @@ -58,7 +53,7 @@ impl<C: Connect + std::fmt::Debug + 'static + Clone + Send + Sync> Connector for
let mut http_request = Request::builder().method(method).uri(uri);

let request = match req.body {
TelegramBody::Empty => http_request.body(Into::<hyper::Body>::into(vec![])),
TelegramBody::Empty => http_request.body(Full::new(Bytes::new())),
TelegramBody::Json(body) => {
let content_type = "application/json"
.parse()
Expand All @@ -67,7 +62,7 @@ impl<C: Connect + std::fmt::Debug + 'static + Clone + Send + Sync> Connector for
http_request
.headers_mut()
.map(move |headers| headers.insert(CONTENT_TYPE, content_type));
http_request.body(Into::<hyper::Body>::into(body))
http_request.body(Full::new(body.into()))
}
TelegramBody::Multipart(parts) => {
let mut fields = Vec::new();
Expand Down Expand Up @@ -141,12 +136,12 @@ impl<C: Connect + std::fmt::Debug + 'static + Clone + Send + Sync> 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<u8> {
acc.extend_from_slice(&chunk);
acc.extend_from_slice(&chunk.to_bytes());
acc
});

Expand All @@ -158,13 +153,29 @@ impl<C: Connect + std::fmt::Debug + 'static + Clone + Send + Sync> Connector for
}

pub fn default_connector() -> Result<Box<dyn Connector>, 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),
)))
}
6 changes: 3 additions & 3 deletions lib/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -19,8 +19,8 @@ impl From<telegram_bot_raw::Error> for ErrorKind {
}
}

impl From<hyper::Error> for ErrorKind {
fn from(error: hyper::Error) -> Self {
impl From<hyper_util::client::legacy::Error> for ErrorKind {
fn from(error: hyper_util::client::legacy::Error) -> Self {
ErrorKind::Hyper(error)
}
}
Expand Down