Skip to content

Commit

Permalink
build(http): Update to hyper 1.0 and rustls 0.22
Browse files Browse the repository at this point in the history
Signed-off-by: Jens Reidel <[email protected]>
  • Loading branch information
Gelbpunkt committed Dec 29, 2023
1 parent 01fce6c commit a336f93
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 35 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ include = ["src/**/*.rs", "README.md"]
license = "ISC"
repository = "https://github.com/twilight-rs/twilight.git"
rust-version = "1.67"

[patch.crates-io]
# Needed for hyper 1.0 compatibility
hyper-rustls = { git = "https://github.com/Gelbpunkt/hyper-rustls.git", branch = "hyper-v1" }
1 change: 1 addition & 0 deletions twilight-gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ version = "0.15.4"

[dependencies]
bitflags = { default-features = false, version = "2" }
bytes = { default-features = false, features = ["std"], version = "1" }
fastrand = { default-features = false, features = ["std"], version = "2" }
futures-util = { default-features = false, features = ["sink", "std"], version = "0.3" }
serde = { default-features = false, features = ["derive"], version = "1" }
Expand Down
9 changes: 6 additions & 3 deletions twilight-http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ version = "0.15.4"

[dependencies]
fastrand = { default-features = false, features = ["std"], version = "2" }
hyper = { default-features = false, features = ["client", "http1", "http2", "runtime"], version = "0.14" }
hyper-rustls = { default-features = false, optional = true, features = ["http1", "http2"], version = "0.24" }
hyper-tls = { default-features = false, optional = true, version = "0.5" }
http = { default-features = false, version = "1" }
http-body-util = { default-features = false, version = "0.1" }
hyper = { default-features = false, version = "1" }
hyper-util = { default-features = false, features = ["client-legacy", "http1", "http2", "tokio"], version = "0.1.2" }
hyper-rustls = { default-features = false, optional = true, features = ["http1", "http2", "ring"], version = "0.25" }
hyper-tls = { default-features = false, optional = true, version = "0.6" }
hyper-hickory = { default-features = false, optional = true, features = ["tokio"], version = "0.6" }
percent-encoding = { default-features = false, version = "2" }
serde = { default-features = false, features = ["derive"], version = "1" }
Expand Down
6 changes: 4 additions & 2 deletions twilight-http/src/client/builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::Token;
use crate::{client::connector, Client};
use hyper::header::HeaderMap;
use http::header::HeaderMap;
use hyper_util::rt::TokioExecutor;
use std::{
sync::{atomic::AtomicBool, Arc},
time::Duration,
Expand Down Expand Up @@ -32,7 +33,8 @@ impl ClientBuilder {
pub fn build(self) -> Client {
let connector = connector::create();

let http = hyper::Client::builder().build(connector);
let http =
hyper_util::client::legacy::Client::builder(TokioExecutor::new()).build(connector);

let token_invalidated = if self.remember_invalid_token {
Some(Arc::new(AtomicBool::new(false)))
Expand Down
5 changes: 3 additions & 2 deletions twilight-http/src/client/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type HttpsConnector<T> = hyper_tls::HttpsConnector<T>;
type HttpConnector = hyper_hickory::TokioHickoryHttpConnector;
/// HTTP connector.
#[cfg(not(feature = "hickory"))]
type HttpConnector = hyper::client::HttpConnector;
type HttpConnector = hyper_util::client::legacy::connect::HttpConnector;

/// Re-exported generic connector for use in the client.
#[cfg(any(
Expand All @@ -35,7 +35,7 @@ pub type Connector = HttpConnector;
/// Create a connector with the specified features.
pub fn create() -> Connector {
#[cfg(not(feature = "hickory"))]
let mut connector = hyper::client::HttpConnector::new();
let mut connector = HttpConnector::new();
#[cfg(feature = "hickory")]
let mut connector = hyper_hickory::TokioHickoryResolver::default().into_http_connector();

Expand All @@ -44,6 +44,7 @@ pub fn create() -> Connector {
#[cfg(feature = "rustls-native-roots")]
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.expect("no native root certificates found")
.https_or_http()
.enable_http1()
.enable_http2()
Expand Down
17 changes: 9 additions & 8 deletions twilight-http/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,12 @@ use crate::{
response::ResponseFuture,
API_VERSION,
};
use hyper::{
client::Client as HyperClient,
header::{HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE, USER_AGENT},
Body,
use http::header::{
HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE, USER_AGENT,
};
use http_body_util::Full;
use hyper::body::Bytes;
use hyper_util::client::legacy::Client as HyperClient;
use std::{
fmt::{Debug, Formatter, Result as FmtResult},
ops::Deref,
Expand Down Expand Up @@ -231,7 +232,7 @@ impl Deref for Token {
pub struct Client {
pub(crate) default_allowed_mentions: Option<AllowedMentions>,
default_headers: Option<HeaderMap>,
http: HyperClient<Connector>,
http: HyperClient<Connector, Full<Bytes>>,
proxy: Option<Box<str>>,
ratelimiter: Option<Box<dyn Ratelimiter>>,
timeout: Duration,
Expand Down Expand Up @@ -2659,11 +2660,11 @@ impl Client {
}

let try_req = if let Some(form) = form {
builder.body(Body::from(form.build()))
builder.body(Full::from(form.build()))
} else if let Some(bytes) = body {
builder.body(Body::from(bytes))
builder.body(Full::from(bytes))
} else {
builder.body(Body::empty())
builder.body(Full::default())
};

let inner = self.http.request(try_req.map_err(|source| Error {
Expand Down
5 changes: 3 additions & 2 deletions twilight-http/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{api_error::ApiError, json::JsonError, response::StatusCode};
use hyper::{Body, Response};
use http::Response;
use hyper::body::Incoming;
use std::{
error::Error as StdError,
fmt::{Debug, Display, Formatter, Result as FmtResult},
Expand Down Expand Up @@ -125,7 +126,7 @@ pub enum ErrorType {
///
/// This may occur during Discord API stability incidents.
ServiceUnavailable {
response: Response<Body>,
response: Response<Incoming>,
},
/// Token in use has become revoked or is otherwise invalid.
///
Expand Down
2 changes: 1 addition & 1 deletion twilight-http/src/request/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
error::Error,
routing::{Path, Route},
};
use hyper::header::{HeaderMap, HeaderName, HeaderValue};
use http::header::{HeaderMap, HeaderName, HeaderValue};
use serde::Serialize;

/// Builder to create a customized request.
Expand Down
2 changes: 1 addition & 1 deletion twilight-http/src/request/guild/ban/create_ban.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ mod tests {
client::Client,
request::{AuditLogReason, TryIntoRequest, REASON_HEADER_NAME},
};
use hyper::header::HeaderValue;
use http::header::HeaderValue;
use std::error::Error;
use twilight_http_ratelimiting::Method;
use twilight_model::id::{
Expand Down
2 changes: 1 addition & 1 deletion twilight-http/src/request/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub use self::{
pub use twilight_http_ratelimiting::request::Method;

use crate::error::{Error, ErrorType};
use hyper::header::{HeaderName, HeaderValue};
use http::header::{HeaderName, HeaderValue};
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use serde::Serialize;
use std::iter;
Expand Down
5 changes: 3 additions & 2 deletions twilight-http/src/response/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use crate::{
api_error::ApiError,
error::{Error, ErrorType},
};
use hyper::{client::ResponseFuture as HyperResponseFuture, StatusCode as HyperStatusCode};
use http::StatusCode as HyperStatusCode;
use hyper_util::client::legacy::ResponseFuture as HyperResponseFuture;
use std::{
future::Future,
marker::PhantomData,
Expand Down Expand Up @@ -130,7 +131,7 @@ impl InFlight {
let mut resp = resp;
// Inaccurate since end-users can only access the decompressed body.
#[cfg(feature = "decompression")]
resp.headers_mut().remove(hyper::header::CONTENT_LENGTH);
resp.headers_mut().remove(http::header::CONTENT_LENGTH);

return InnerPoll::Ready(Ok(Response::new(resp)));
}
Expand Down
34 changes: 21 additions & 13 deletions twilight-http/src/response/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ mod status_code;
pub use self::{future::ResponseFuture, status_code::StatusCode};

use self::marker::ListBody;
use hyper::{
body::{self, Bytes},
use http::{
header::{HeaderValue, Iter as HeaderMapIter},
Body, Response as HyperResponse,
Response as HyperResponse,
};
use http_body_util::BodyExt;
use hyper::body::{Bytes, Incoming};
use serde::de::DeserializeOwned;
use std::{
error::Error,
Expand Down Expand Up @@ -174,12 +175,12 @@ pub enum DeserializeBodyErrorType {
/// ```
#[derive(Debug)]
pub struct Response<T> {
inner: HyperResponse<Body>,
inner: HyperResponse<Incoming>,
phantom: PhantomData<T>,
}

impl<T> Response<T> {
pub(crate) const fn new(inner: HyperResponse<Body>) -> Self {
pub(crate) const fn new(inner: HyperResponse<Incoming>) -> Self {
Self {
inner,
phantom: PhantomData,
Expand Down Expand Up @@ -237,7 +238,7 @@ impl<T> Response<T> {
let compressed = self
.inner
.headers()
.get(hyper::header::CONTENT_ENCODING)
.get(http::header::CONTENT_ENCODING)
.is_some();

let body = self.inner.into_body();
Expand All @@ -249,12 +250,14 @@ impl<T> Response<T> {
return decompress(body).await;
}

body::to_bytes(body)
Ok(body
.collect()
.await
.map_err(|source| DeserializeBodyError {
kind: DeserializeBodyErrorType::Chunking,
source: Some(Box::new(source)),
})
})?
.to_bytes())
}
};

Expand Down Expand Up @@ -573,17 +576,22 @@ impl Future for TextFuture {
}

#[cfg(feature = "decompression")]
async fn decompress(body: Body) -> Result<Bytes, DeserializeBodyError> {
async fn decompress<B: hyper::body::Body>(body: B) -> Result<Bytes, DeserializeBodyError>
where
<B as hyper::body::Body>::Error: Send + Sync + Error + 'static,
{
use brotli::Decompressor;
use hyper::body::Buf;
use std::io::Read;

let aggregate = body::aggregate(body)
let aggregate = body
.collect()
.await
.map_err(|source| DeserializeBodyError {
kind: DeserializeBodyErrorType::Chunking,
source: Some(Box::new(source)),
})?;
})?
.aggregate();

// Determine the size of the entire buffer, in order to create the
// decompressed and compressed buffers.
Expand Down Expand Up @@ -628,7 +636,7 @@ mod tests {
#[tokio::test]
async fn test_decompression() -> Result<(), Box<dyn Error + Send + Sync>> {
use super::decompress;
use hyper::Body;
use http_body_util::Full;
use twilight_model::guild::invite::Invite;

const COMPRESSED: [u8; 685] = [
Expand Down Expand Up @@ -671,7 +679,7 @@ mod tests {
3,
];

let decompressed = decompress(Body::from(COMPRESSED.as_ref())).await?;
let decompressed = decompress(Full::new(COMPRESSED.as_slice())).await?;

let deserialized = serde_json::from_slice::<Invite>(&decompressed)?;

Expand Down

0 comments on commit a336f93

Please sign in to comment.