From d023e41f3444ed8f03afb7b16ee8fcad69fa0f6f Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Mon, 11 Dec 2023 22:59:18 +0100 Subject: [PATCH 1/3] build(gateway, lavalink): Update to tokio-websockets 0.5 and rustls 0.22 Signed-off-by: Jens Reidel --- twilight-gateway/Cargo.toml | 6 +++--- twilight-gateway/src/connection.rs | 4 ++-- twilight-lavalink/Cargo.toml | 8 ++++---- twilight-lavalink/src/node.rs | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/twilight-gateway/Cargo.toml b/twilight-gateway/Cargo.toml index fd482c6fc51..afbedb9637e 100644 --- a/twilight-gateway/Cargo.toml +++ b/twilight-gateway/Cargo.toml @@ -20,7 +20,7 @@ futures-util = { default-features = false, features = ["sink", "std"], version = serde = { default-features = false, features = ["derive"], version = "1" } serde_json = { default-features = false, features = ["std"], version = "1" } tokio = { default-features = false, features = ["net", "rt", "sync", "time"], version = "1.19" } -tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.4" } +tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.5" } tracing = { default-features = false, features = ["std", "attributes"], version = "0.1" } twilight-gateway-queue = { default-features = false, path = "../twilight-gateway-queue", version = "0.15.4" } twilight-model = { default-features = false, path = "../twilight-model", version = "0.15.4" } @@ -45,8 +45,8 @@ tracing-subscriber = { default-features = false, features = ["fmt", "tracing-log [features] default = ["rustls-native-roots", "twilight-http", "zlib-stock"] native = ["tokio-websockets/native-tls", "tokio-websockets/openssl"] -rustls-native-roots = ["tokio-websockets/rustls-native-roots"] -rustls-webpki-roots = ["tokio-websockets/rustls-webpki-roots"] +rustls-native-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-native-roots"] +rustls-webpki-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-webpki-roots"] zlib-simd = ["dep:flate2", "flate2?/zlib-ng"] zlib-stock = ["dep:flate2", "flate2?/zlib"] diff --git a/twilight-gateway/src/connection.rs b/twilight-gateway/src/connection.rs index aba90a10d6a..ee81f88a47f 100644 --- a/twilight-gateway/src/connection.rs +++ b/twilight-gateway/src/connection.rs @@ -6,7 +6,7 @@ use crate::{ }; use std::fmt::{Display, Formatter, Result as FmtResult}; use tokio::net::TcpStream; -use tokio_websockets::{ClientBuilder, Connector, Limits, MaybeTlsStream, WebsocketStream}; +use tokio_websockets::{ClientBuilder, Connector, Limits, MaybeTlsStream, WebSocketStream}; /// Query argument with zlib-stream enabled. #[cfg(any(feature = "zlib-stock", feature = "zlib-simd"))] @@ -24,7 +24,7 @@ const GATEWAY_URL: &str = "wss://gateway.discord.gg"; /// Connections are used by [`Shard`]s when reconnecting. /// /// [`Shard`]: crate::Shard -pub type Connection = WebsocketStream>; +pub type Connection = WebSocketStream>; /// Formatter for a gateway URL, with the API version and compression features /// specified. diff --git a/twilight-lavalink/Cargo.toml b/twilight-lavalink/Cargo.toml index ef697a1b786..675ef15a8d6 100644 --- a/twilight-lavalink/Cargo.toml +++ b/twilight-lavalink/Cargo.toml @@ -16,11 +16,11 @@ version = "0.15.3" [dependencies] dashmap = { default-features = false, version = "5.3" } futures-util = { default-features = false, features = ["bilock", "sink", "std", "unstable"], version = "0.3" } -http = { default-features = false, version = "0.2" } +http = { default-features = false, version = "1" } serde = { default-features = false, features = ["derive", "std"], version = "1" } serde_json = { default-features = false, features = ["std"], version = "1" } tokio = { default-features = false, features = ["macros", "net", "rt", "sync", "time"], version = "1.0" } -tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.4" } +tokio-websockets = { default-features = false, features = ["client", "fastrand", "sha1_smol", "simd"], version = "0.5" } tracing = { default-features = false, features = ["std", "attributes"], version = "0.1" } twilight-model = { default-features = false, path = "../twilight-model", version = "0.15.4" } @@ -40,8 +40,8 @@ twilight-http = { default-features = false, features = ["rustls-native-roots"], default = ["http-support", "rustls-native-roots"] http-support = ["dep:percent-encoding"] native = ["tokio-websockets/native-tls", "tokio-websockets/openssl"] -rustls-native-roots = ["tokio-websockets/rustls-native-roots"] -rustls-webpki-roots = ["tokio-websockets/rustls-webpki-roots"] +rustls-native-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-native-roots"] +rustls-webpki-roots = ["tokio-websockets/ring", "tokio-websockets/rustls-webpki-roots"] [package.metadata.docs.rs] all-features = true diff --git a/twilight-lavalink/src/node.rs b/twilight-lavalink/src/node.rs index 61bdd49e3dd..c40e1bb76aa 100644 --- a/twilight-lavalink/src/node.rs +++ b/twilight-lavalink/src/node.rs @@ -41,7 +41,7 @@ use tokio::{ time as tokio_time, }; use tokio_websockets::{ - upgrade, ClientBuilder, Error as WebsocketError, MaybeTlsStream, Message, WebsocketStream, + upgrade, ClientBuilder, Error as WebsocketError, MaybeTlsStream, Message, WebSocketStream, }; use twilight_model::id::{marker::UserMarker, Id}; @@ -464,7 +464,7 @@ impl Node { struct Connection { config: NodeConfig, - stream: WebsocketStream>, + stream: WebSocketStream>, node_from: UnboundedReceiver, node_to: UnboundedSender, players: PlayerManager, @@ -635,7 +635,7 @@ fn connect_request(state: &NodeConfig) -> Result { async fn reconnect( config: &NodeConfig, -) -> Result>, NodeError> { +) -> Result>, NodeError> { let (mut stream, res) = backoff(config).await?; let headers = res.headers(); @@ -668,7 +668,7 @@ async fn backoff( config: &NodeConfig, ) -> Result< ( - WebsocketStream>, + WebSocketStream>, upgrade::Response, ), NodeError, From 15df7a0689f9ec32b0bc15ccdcf103d84e0984a7 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Mon, 11 Dec 2023 23:21:35 +0100 Subject: [PATCH 2/3] build(http): Update to hyper 1.0 and rustls 0.22 Signed-off-by: Jens Reidel --- twilight-http/Cargo.toml | 11 +++--- twilight-http/src/client/builder.rs | 6 ++-- twilight-http/src/client/connector.rs | 5 +-- twilight-http/src/client/mod.rs | 17 +++++----- twilight-http/src/error.rs | 5 +-- twilight-http/src/request/base.rs | 2 +- .../src/request/guild/ban/create_ban.rs | 2 +- twilight-http/src/request/mod.rs | 2 +- twilight-http/src/response/future.rs | 5 +-- twilight-http/src/response/mod.rs | 34 ++++++++++++------- 10 files changed, 53 insertions(+), 36 deletions(-) diff --git a/twilight-http/Cargo.toml b/twilight-http/Cargo.toml index 7d56a9aada9..dc037988a7e 100644 --- a/twilight-http/Cargo.toml +++ b/twilight-http/Cargo.toml @@ -15,10 +15,13 @@ 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" } -hyper-hickory = { default-features = false, optional = true, features = ["tokio"], version = "0.6" } +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.26" } +hyper-tls = { default-features = false, optional = true, features = ["alpn"], version = "0.6" } +hyper-hickory = { default-features = false, optional = true, version = "0.7" } percent-encoding = { default-features = false, version = "2" } serde = { default-features = false, features = ["derive"], version = "1" } serde_json = { default-features = false, features = ["std"], version = "1" } diff --git a/twilight-http/src/client/builder.rs b/twilight-http/src/client/builder.rs index b74d7617be8..db0f937128a 100644 --- a/twilight-http/src/client/builder.rs +++ b/twilight-http/src/client/builder.rs @@ -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, @@ -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))) diff --git a/twilight-http/src/client/connector.rs b/twilight-http/src/client/connector.rs index 12a6fb2d8ce..96d1752bf4a 100644 --- a/twilight-http/src/client/connector.rs +++ b/twilight-http/src/client/connector.rs @@ -15,7 +15,7 @@ type HttpsConnector = hyper_tls::HttpsConnector; 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( @@ -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(); @@ -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() diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index c77c6cd0d50..0a87a570253 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -82,11 +82,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, @@ -224,7 +225,7 @@ impl Deref for Token { pub struct Client { pub(crate) default_allowed_mentions: Option, default_headers: Option, - http: HyperClient, + http: HyperClient>, proxy: Option>, ratelimiter: Option>, timeout: Duration, @@ -2657,11 +2658,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 { diff --git a/twilight-http/src/error.rs b/twilight-http/src/error.rs index be1b98a2779..0dc86cf0987 100644 --- a/twilight-http/src/error.rs +++ b/twilight-http/src/error.rs @@ -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}, @@ -125,7 +126,7 @@ pub enum ErrorType { /// /// This may occur during Discord API stability incidents. ServiceUnavailable { - response: Response, + response: Response, }, /// Token in use has become revoked or is otherwise invalid. /// diff --git a/twilight-http/src/request/base.rs b/twilight-http/src/request/base.rs index b68fe99c993..020fb096cfa 100644 --- a/twilight-http/src/request/base.rs +++ b/twilight-http/src/request/base.rs @@ -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. diff --git a/twilight-http/src/request/guild/ban/create_ban.rs b/twilight-http/src/request/guild/ban/create_ban.rs index 6d32418e685..d2b99cc828a 100644 --- a/twilight-http/src/request/guild/ban/create_ban.rs +++ b/twilight-http/src/request/guild/ban/create_ban.rs @@ -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::{ diff --git a/twilight-http/src/request/mod.rs b/twilight-http/src/request/mod.rs index 3c77fd2b295..873abe5fe99 100644 --- a/twilight-http/src/request/mod.rs +++ b/twilight-http/src/request/mod.rs @@ -75,7 +75,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; diff --git a/twilight-http/src/response/future.rs b/twilight-http/src/response/future.rs index a8a24bf9734..74f63d3c11e 100644 --- a/twilight-http/src/response/future.rs +++ b/twilight-http/src/response/future.rs @@ -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, @@ -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))); } diff --git a/twilight-http/src/response/mod.rs b/twilight-http/src/response/mod.rs index 7ec4683908d..be62c848883 100644 --- a/twilight-http/src/response/mod.rs +++ b/twilight-http/src/response/mod.rs @@ -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, @@ -174,12 +175,12 @@ pub enum DeserializeBodyErrorType { /// ``` #[derive(Debug)] pub struct Response { - inner: HyperResponse, + inner: HyperResponse, phantom: PhantomData, } impl Response { - pub(crate) const fn new(inner: HyperResponse) -> Self { + pub(crate) const fn new(inner: HyperResponse) -> Self { Self { inner, phantom: PhantomData, @@ -237,7 +238,7 @@ impl Response { let compressed = self .inner .headers() - .get(hyper::header::CONTENT_ENCODING) + .get(http::header::CONTENT_ENCODING) .is_some(); let body = self.inner.into_body(); @@ -249,12 +250,14 @@ impl Response { 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()) } }; @@ -573,17 +576,22 @@ impl Future for TextFuture { } #[cfg(feature = "decompression")] -async fn decompress(body: Body) -> Result { +async fn decompress(body: B) -> Result +where + ::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. @@ -628,7 +636,7 @@ mod tests { #[tokio::test] async fn test_decompression() -> Result<(), Box> { use super::decompress; - use hyper::Body; + use http_body_util::Full; use twilight_model::guild::invite::Invite; const COMPRESSED: [u8; 685] = [ @@ -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::(&decompressed)?; From 3128fc1667632140589667e2ca68bece7fc5a777 Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Sat, 30 Dec 2023 20:07:09 +0100 Subject: [PATCH 3/3] build(examples): Update examples and dev-deps to hyper 1 Signed-off-by: Jens Reidel --- examples/Cargo.toml | 4 +- examples/gateway-queue-http.rs | 13 ++++-- examples/lavalink-basic-bot.rs | 16 ++++--- examples/model-webhook-slash.rs | 63 ++++++++++++++++----------- twilight-http-ratelimiting/Cargo.toml | 2 +- 5 files changed, 60 insertions(+), 38 deletions(-) diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 2b2bfd7ac22..a29f2756ec2 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -10,7 +10,9 @@ anyhow = { default-features = false, features = ["std"], version = "1" } ed25519-dalek = "2" futures-util = { default-features = false, version = "0.3" } hex = "0.4" -hyper = { features = ["client", "server", "http2", "runtime"], version = "0.14" } +http-body-util = "0.1" +hyper = { features = ["server"], version = "1" } +hyper-util = { features = ["http1", "client-legacy"], version = "0.1" } log = { default-features = false, version = "0.4" } once_cell = "1.4" serde = { version = "1", features = ["derive"] } diff --git a/examples/gateway-queue-http.rs b/examples/gateway-queue-http.rs index a37c3677e1e..e30942db4b3 100644 --- a/examples/gateway-queue-http.rs +++ b/examples/gateway-queue-http.rs @@ -1,10 +1,15 @@ -use hyper::client::{Client, HttpConnector}; +use http_body_util::Empty; +use hyper::body::Bytes; +use hyper_util::{ + client::legacy::{connect::HttpConnector, Client}, + rt::TokioExecutor, +}; use std::env; use tokio::sync::oneshot; use twilight_gateway::{queue::Queue, ConfigBuilder, Intents, Shard, ShardId}; #[derive(Debug)] -struct HttpQueue(Client); +struct HttpQueue(Client>); impl Queue for HttpQueue { fn enqueue(&self, id: u32) -> oneshot::Receiver<()> { @@ -36,7 +41,9 @@ async fn main() -> anyhow::Result<()> { let intents = Intents::GUILDS | Intents::GUILD_VOICE_STATES; let config = ConfigBuilder::new(token, intents) - .queue(HttpQueue(Client::new())) + .queue(HttpQueue( + Client::builder(TokioExecutor::new()).build_http(), + )) .build(); let mut shard = Shard::with_config(ShardId::ONE, config); diff --git a/examples/lavalink-basic-bot.rs b/examples/lavalink-basic-bot.rs index fbe6550c9d3..619fa0cd6c7 100644 --- a/examples/lavalink-basic-bot.rs +++ b/examples/lavalink-basic-bot.rs @@ -1,6 +1,8 @@ -use hyper::{ - client::{Client as HyperClient, HttpConnector}, - Body, Request, +use http_body_util::{BodyExt, Full}; +use hyper::{body::Bytes, Request}; +use hyper_util::{ + client::legacy::{connect::HttpConnector, Client as HyperClient}, + rt::TokioExecutor, }; use std::{env, future::Future, net::SocketAddr, str::FromStr, sync::Arc}; use twilight_gateway::{Event, Intents, MessageSender, Shard, ShardId}; @@ -22,7 +24,7 @@ type State = Arc; struct StateRef { http: HttpClient, lavalink: Lavalink, - hyper: HyperClient, + hyper: HyperClient>, sender: MessageSender, standby: Standby, } @@ -62,7 +64,7 @@ async fn main() -> anyhow::Result<()> { Arc::new(StateRef { http, lavalink, - hyper: HyperClient::new(), + hyper: HyperClient::builder(TokioExecutor::new()).build_http(), sender, standby: Standby::new(), }), @@ -191,9 +193,9 @@ async fn play(msg: Message, state: State) -> anyhow::Result<()> { &player.node().config().authorization, )? .into_parts(); - let req = Request::from_parts(parts, Body::from(body)); + let req = Request::from_parts(parts, Full::from(body)); let res = state.hyper.request(req).await?; - let response_bytes = hyper::body::to_bytes(res.into_body()).await?; + let response_bytes = res.collect().await?.to_bytes(); let loaded = serde_json::from_slice::(&response_bytes)?; diff --git a/examples/model-webhook-slash.rs b/examples/model-webhook-slash.rs index a4783d0e2ed..96a9a42ba39 100644 --- a/examples/model-webhook-slash.rs +++ b/examples/model-webhook-slash.rs @@ -1,13 +1,18 @@ use ed25519_dalek::{Verifier, VerifyingKey, PUBLIC_KEY_LENGTH}; use hex::FromHex; +use http_body_util::{BodyExt, Full}; use hyper::{ + body::{Bytes, Incoming}, header::CONTENT_TYPE, http::StatusCode, - service::{make_service_fn, service_fn}, - Body, Method, Request, Response, Server, + server::conn::http1, + service::service_fn, + Method, Request, Response, }; +use hyper_util::rt::TokioIo; use once_cell::sync::Lazy; -use std::future::Future; +use std::{future::Future, net::SocketAddr}; +use tokio::net::TcpListener; use twilight_model::{ application::interaction::{ application_command::CommandData, Interaction, InteractionData, InteractionType, @@ -26,9 +31,9 @@ static PUB_KEY: Lazy = Lazy::new(|| { /// Responses are made by giving a function that takes a Interaction and returns /// a InteractionResponse or a error. async fn interaction_handler( - req: Request, + req: Request, f: impl Fn(Box) -> F, -) -> anyhow::Result> +) -> anyhow::Result>> where F: Future>, { @@ -36,7 +41,7 @@ where if req.method() != Method::POST { return Ok(Response::builder() .status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty())?); + .body(Full::default())?); } // Check if the path the request is sent to is the root of the domain. @@ -46,7 +51,7 @@ where if req.uri().path() != "/" { return Ok(Response::builder() .status(StatusCode::NOT_FOUND) - .body(Body::empty())?); + .body(Full::default())?); } // Extract the timestamp header for use later to check the signature. @@ -55,7 +60,7 @@ where } else { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::empty())?); + .body(Full::default())?); }; // Extract the signature to check against. @@ -68,12 +73,12 @@ where } else { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::empty())?); + .body(Full::default())?); }; // Fetch the whole body of the request as that is needed to check the // signature against. - let whole_body = hyper::body::to_bytes(req).await?; + let whole_body = req.collect().await?.to_bytes(); // Check if the signature matches and else return a error response. if PUB_KEY @@ -85,7 +90,7 @@ where { return Ok(Response::builder() .status(StatusCode::UNAUTHORIZED) - .body(Body::empty())?); + .body(Full::default())?); } // Deserialize the body into a interaction. @@ -127,7 +132,7 @@ where // Unhandled interaction types. _ => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::empty())?), + .body(Full::default())?), } } @@ -169,18 +174,24 @@ async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); // Local address to bind the service to. - let addr = "127.0.0.1:3030".parse().unwrap(); - - // Make the interaction handler into a service function. - let interaction_service = make_service_fn(|_| async { - Ok::<_, anyhow::Error>(service_fn(|req| interaction_handler(req, handler))) - }); - - // Construct the server and serve the interaction service. - let server = Server::bind(&addr).serve(interaction_service); - - // Start the server. - server.await?; - - Ok(()) + let addr = SocketAddr::from(([127, 0, 0, 1], 3030)); + + // Bind the server and serve the interaction service. + let listener = TcpListener::bind(addr).await?; + + loop { + let (conn, _) = listener.accept().await?; + + tokio::spawn(async move { + if let Err(e) = http1::Builder::new() + .serve_connection( + TokioIo::new(conn), + service_fn(|req| interaction_handler(req, handler)), + ) + .await + { + tracing::error!("Error handling HTTP request: {e}"); + }; + }); + } } diff --git a/twilight-http-ratelimiting/Cargo.toml b/twilight-http-ratelimiting/Cargo.toml index c213edc84c1..348016c4e2b 100644 --- a/twilight-http-ratelimiting/Cargo.toml +++ b/twilight-http-ratelimiting/Cargo.toml @@ -20,7 +20,7 @@ tracing = { default-features = false, features = ["std", "attributes"], version [dev-dependencies] criterion = { default-features = false, version = "0.4" } -http = { version = "0.2", default-features = false } +http = { version = "1", default-features = false } static_assertions = { default-features = false, version = "1.1.0" } tokio = { default-features = false, features = ["macros", "rt-multi-thread"], version = "1.0" }