1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-03 01:39:28 +02:00

Update core to hyper 1.x

This commit is contained in:
George Hahn 2024-06-06 01:38:46 -06:00
parent 98a97588d3
commit 0a7a874ca0
6 changed files with 187 additions and 273 deletions

View file

@ -10,11 +10,13 @@ use governor::{
clock::MonotonicClock, middleware::NoOpMiddleware, state::InMemoryState, Quota, RateLimiter,
};
use http::{header::HeaderValue, Uri};
use http_body_util::{BodyExt, Full};
use hyper::{
body::HttpBody, client::{HttpConnector, ResponseFuture}, header::USER_AGENT, Body, Client, HeaderMap, Request, Response, StatusCode
body::Incoming, header::USER_AGENT, HeaderMap, Request, Response, StatusCode
};
use hyper_proxy::{Intercept, Proxy, ProxyConnector};
use hyper_proxy2::{Intercept, Proxy, ProxyConnector};
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
use hyper_util::{client::legacy::{connect::HttpConnector, Client, ResponseFuture}, rt::TokioExecutor};
use nonzero_ext::nonzero;
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
@ -87,7 +89,7 @@ impl From<HttpClientError> for Error {
}
}
type HyperClient = Client<ProxyConnector<HttpsConnector<HttpConnector>>, Body>;
type HyperClient = Client<ProxyConnector<HttpsConnector<HttpConnector>>, Full<bytes::Bytes>>;
pub struct HttpClient {
user_agent: HeaderValue,
@ -144,7 +146,7 @@ impl HttpClient {
fn try_create_hyper_client(proxy_url: Option<&Url>) -> Result<HyperClient, Error> {
// configuring TLS is expensive and should be done once per process
let https_connector = HttpsConnectorBuilder::new()
.with_native_roots()
.with_native_roots()?
.https_or_http()
.enable_http1()
.enable_http2()
@ -158,7 +160,7 @@ impl HttpClient {
};
let proxy_connector = ProxyConnector::from_proxy(https_connector, proxy)?;
let client = Client::builder()
let client = Client::builder(TokioExecutor::new())
.http2_adaptive_window(true)
.build(proxy_connector);
Ok(client)
@ -169,21 +171,20 @@ impl HttpClient {
.get_or_try_init(|| Self::try_create_hyper_client(self.proxy_url.as_ref()))
}
pub async fn request(&self, req: Request<Body>) -> Result<Response<Body>, Error> {
pub async fn request(&self, req: Request<Bytes>) -> Result<Response<Incoming>, Error> {
debug!("Requesting {}", req.uri().to_string());
// `Request` does not implement `Clone` because its `Body` may be a single-shot stream.
// As correct as that may be technically, we now need all this boilerplate to clone it
// ourselves, as any `Request` is moved in the loop.
let (parts, body) = req.into_parts();
let body_as_bytes = body.collect().await.map(|b| b.to_bytes()).unwrap_or_default();
let (parts, body_as_bytes) = req.into_parts();
loop {
let mut req = Request::builder()
.method(parts.method.clone())
.uri(parts.uri.clone())
.version(parts.version)
.body(Body::from(body_as_bytes.clone()))?;
.body(body_as_bytes.clone())?;
*req.headers_mut() = parts.headers.clone();
let request = self.request_fut(req)?;
@ -208,20 +209,21 @@ impl HttpClient {
}
}
return Ok(response?);
let response = response?;
return Ok(response);
}
}
pub async fn request_body(&self, req: Request<Body>) -> Result<Bytes, Error> {
pub async fn request_body(&self, req: Request<Bytes>) -> Result<Bytes, Error> {
let response = self.request(req).await?;
Ok(response.into_body().collect().await?.to_bytes())
}
pub fn request_stream(&self, req: Request<Body>) -> Result<IntoStream<ResponseFuture>, Error> {
pub fn request_stream(&self, req: Request<Bytes>) -> Result<IntoStream<ResponseFuture>, Error> {
Ok(self.request_fut(req)?.into_stream())
}
pub fn request_fut(&self, mut req: Request<Body>) -> Result<ResponseFuture, Error> {
pub fn request_fut(&self, mut req: Request<Bytes>) -> Result<ResponseFuture, Error> {
let headers_mut = req.headers_mut();
headers_mut.insert(USER_AGENT, self.user_agent.clone());
@ -247,7 +249,8 @@ impl HttpClient {
))
})?;
Ok(self.hyper_client()?.request(req))
Ok(self.hyper_client()?.request(req.map(Full::new)))
}
pub fn get_retry_after(headers: &HeaderMap<HeaderValue>) -> Option<Duration> {