Skip to content

Commit 1504430

Browse files
authored
Merge pull request #1291 from GeorgeHahn/hyper-update
Update hyper to 1.x
2 parents 8f9bec2 + bd5c284 commit 1504430

12 files changed

Lines changed: 281 additions & 334 deletions

File tree

Cargo.lock

Lines changed: 148 additions & 243 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

audio/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ bytes = "1"
1919
ctr = "0.9"
2020
futures-core = "0.3"
2121
futures-util = "0.3"
22-
hyper = { version = "0.14", features = ["client"] }
22+
hyper = { version = "1.3", features = [] }
23+
hyper-util = { version = "0.1", features = ["client"] }
24+
http-body-util = "0.1.1"
2325
log = "0.4"
2426
parking_lot = { version = "0.12", features = ["deadlock_detection"] }
2527
tempfile = "3"

audio/src/fetch/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use std::{
1212
};
1313

1414
use futures_util::{future::IntoStream, StreamExt, TryFutureExt};
15-
use hyper::{client::ResponseFuture, header::CONTENT_RANGE, Body, Response, StatusCode};
15+
use hyper::{body::Incoming, header::CONTENT_RANGE, Response, StatusCode};
16+
use hyper_util::client::legacy::ResponseFuture;
1617
use parking_lot::{Condvar, Mutex};
1718
use tempfile::NamedTempFile;
1819
use thiserror::Error;
@@ -133,7 +134,7 @@ pub enum AudioFile {
133134
#[derive(Debug)]
134135
pub struct StreamingRequest {
135136
streamer: IntoStream<ResponseFuture>,
136-
initial_response: Option<Response<Body>>,
137+
initial_response: Option<Response<Incoming>>,
137138
offset: usize,
138139
length: usize,
139140
}

audio/src/fetch/receive.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::{
77

88
use bytes::Bytes;
99
use futures_util::StreamExt;
10+
use http_body_util::BodyExt;
1011
use hyper::StatusCode;
1112
use tempfile::NamedTempFile;
1213
use tokio::sync::{mpsc, oneshot};
@@ -97,7 +98,7 @@ async fn receive_data(
9798
}
9899

99100
let body = response.into_body();
100-
let data = match hyper::body::to_bytes(body).await {
101+
let data = match body.collect().await.map(|b| b.to_bytes()) {
101102
Ok(bytes) => bytes,
102103
Err(e) => break Err(e.into()),
103104
};

core/Cargo.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ futures-util = { version = "0.3", features = ["alloc", "bilock", "sink", "unstab
2525
governor = { version = "0.6", default-features = false, features = ["std", "jitter"] }
2626
hmac = "0.12"
2727
httparse = "1.7"
28-
http = "0.2"
29-
hyper = { version = "0.14", features = ["client", "http1", "http2", "tcp"] }
30-
hyper-proxy = { version = "0.9", default-features = false, features = ["rustls"] }
31-
hyper-rustls = { version = "0.24", features = ["http2"] }
28+
http = "1.0"
29+
hyper = { version = "1.3", features = ["http1", "http2"] }
30+
hyper-util = { version = "0.1", features = ["client"] }
31+
http-body-util = "0.1.1"
32+
hyper-proxy2 = { version = "0.1", default-features = false, features = ["rustls"] }
33+
hyper-rustls = { version = "0.26", features = ["http2"] }
3234
log = "0.4"
3335
nonzero_ext = "0.3"
3436
num-bigint = { version = "0.4", features = ["rand"] }

core/src/apresolve.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::VecDeque;
22

3-
use hyper::{Body, Method, Request};
3+
use bytes::Bytes;
4+
use hyper::{Method, Request};
45
use serde::Deserialize;
56

67
use crate::Error;
@@ -85,7 +86,7 @@ impl ApResolver {
8586
let req = Request::builder()
8687
.method(Method::GET)
8788
.uri("https://apresolve.spotify.com/?type=accesspoint&type=dealer&type=spclient")
88-
.body(Body::empty())?;
89+
.body(Bytes::new())?;
8990

9091
let body = self.session().http_client().request_body(req).await?;
9192
let data: ApResolveData = serde_json::from_slice(body.as_ref())?;

core/src/error.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -321,18 +321,14 @@ impl From<http::Error> for Error {
321321

322322
impl From<hyper::Error> for Error {
323323
fn from(err: hyper::Error) -> Self {
324-
if err.is_parse() || err.is_parse_too_large() || err.is_parse_status() || err.is_user() {
324+
if err.is_parse() || err.is_parse_status() || err.is_user() {
325325
return Self::new(ErrorKind::Internal, err);
326326
}
327327

328328
if err.is_canceled() {
329329
return Self::new(ErrorKind::Cancelled, err);
330330
}
331331

332-
if err.is_connect() {
333-
return Self::new(ErrorKind::Unavailable, err);
334-
}
335-
336332
if err.is_incomplete_message() {
337333
return Self::new(ErrorKind::DataLoss, err);
338334
}
@@ -349,6 +345,16 @@ impl From<hyper::Error> for Error {
349345
}
350346
}
351347

348+
impl From<hyper_util::client::legacy::Error> for Error {
349+
fn from(err: hyper_util::client::legacy::Error) -> Self {
350+
if err.is_connect() {
351+
return Self::new(ErrorKind::Unavailable, err);
352+
}
353+
354+
Self::new(ErrorKind::Unknown, err)
355+
}
356+
}
357+
352358
impl From<time::error::Parse> for Error {
353359
fn from(err: time::error::Parse) -> Self {
354360
Self::new(ErrorKind::FailedPrecondition, err)

core/src/http_client.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ use governor::{
1010
clock::MonotonicClock, middleware::NoOpMiddleware, state::InMemoryState, Quota, RateLimiter,
1111
};
1212
use http::{header::HeaderValue, Uri};
13-
use hyper::{
14-
client::{HttpConnector, ResponseFuture},
15-
header::USER_AGENT,
16-
Body, Client, HeaderMap, Request, Response, StatusCode,
17-
};
18-
use hyper_proxy::{Intercept, Proxy, ProxyConnector};
13+
use http_body_util::{BodyExt, Full};
14+
use hyper::{body::Incoming, header::USER_AGENT, HeaderMap, Request, Response, StatusCode};
15+
use hyper_proxy2::{Intercept, Proxy, ProxyConnector};
1916
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
17+
use hyper_util::{
18+
client::legacy::{connect::HttpConnector, Client, ResponseFuture},
19+
rt::TokioExecutor,
20+
};
2021
use nonzero_ext::nonzero;
2122
use once_cell::sync::OnceCell;
2223
use parking_lot::Mutex;
@@ -89,7 +90,7 @@ impl From<HttpClientError> for Error {
8990
}
9091
}
9192

92-
type HyperClient = Client<ProxyConnector<HttpsConnector<HttpConnector>>, Body>;
93+
type HyperClient = Client<ProxyConnector<HttpsConnector<HttpConnector>>, Full<bytes::Bytes>>;
9394

9495
pub struct HttpClient {
9596
user_agent: HeaderValue,
@@ -146,7 +147,7 @@ impl HttpClient {
146147
fn try_create_hyper_client(proxy_url: Option<&Url>) -> Result<HyperClient, Error> {
147148
// configuring TLS is expensive and should be done once per process
148149
let https_connector = HttpsConnectorBuilder::new()
149-
.with_native_roots()
150+
.with_native_roots()?
150151
.https_or_http()
151152
.enable_http1()
152153
.enable_http2()
@@ -160,7 +161,7 @@ impl HttpClient {
160161
};
161162
let proxy_connector = ProxyConnector::from_proxy(https_connector, proxy)?;
162163

163-
let client = Client::builder()
164+
let client = Client::builder(TokioExecutor::new())
164165
.http2_adaptive_window(true)
165166
.build(proxy_connector);
166167
Ok(client)
@@ -171,23 +172,20 @@ impl HttpClient {
171172
.get_or_try_init(|| Self::try_create_hyper_client(self.proxy_url.as_ref()))
172173
}
173174

174-
pub async fn request(&self, req: Request<Body>) -> Result<Response<Body>, Error> {
175+
pub async fn request(&self, req: Request<Bytes>) -> Result<Response<Incoming>, Error> {
175176
debug!("Requesting {}", req.uri().to_string());
176177

177178
// `Request` does not implement `Clone` because its `Body` may be a single-shot stream.
178179
// As correct as that may be technically, we now need all this boilerplate to clone it
179180
// ourselves, as any `Request` is moved in the loop.
180-
let (parts, body) = req.into_parts();
181-
let body_as_bytes = hyper::body::to_bytes(body)
182-
.await
183-
.unwrap_or_else(|_| Bytes::new());
181+
let (parts, body_as_bytes) = req.into_parts();
184182

185183
loop {
186184
let mut req = Request::builder()
187185
.method(parts.method.clone())
188186
.uri(parts.uri.clone())
189187
.version(parts.version)
190-
.body(Body::from(body_as_bytes.clone()))?;
188+
.body(body_as_bytes.clone())?;
191189
*req.headers_mut() = parts.headers.clone();
192190

193191
let request = self.request_fut(req)?;
@@ -212,20 +210,21 @@ impl HttpClient {
212210
}
213211
}
214212

215-
return Ok(response?);
213+
let response = response?;
214+
return Ok(response);
216215
}
217216
}
218217

219-
pub async fn request_body(&self, req: Request<Body>) -> Result<Bytes, Error> {
218+
pub async fn request_body(&self, req: Request<Bytes>) -> Result<Bytes, Error> {
220219
let response = self.request(req).await?;
221-
Ok(hyper::body::to_bytes(response.into_body()).await?)
220+
Ok(response.into_body().collect().await?.to_bytes())
222221
}
223222

224-
pub fn request_stream(&self, req: Request<Body>) -> Result<IntoStream<ResponseFuture>, Error> {
223+
pub fn request_stream(&self, req: Request<Bytes>) -> Result<IntoStream<ResponseFuture>, Error> {
225224
Ok(self.request_fut(req)?.into_stream())
226225
}
227226

228-
pub fn request_fut(&self, mut req: Request<Body>) -> Result<ResponseFuture, Error> {
227+
pub fn request_fut(&self, mut req: Request<Bytes>) -> Result<ResponseFuture, Error> {
229228
let headers_mut = req.headers_mut();
230229
headers_mut.insert(USER_AGENT, self.user_agent.clone());
231230

@@ -251,7 +250,7 @@ impl HttpClient {
251250
))
252251
})?;
253252

254-
Ok(self.hyper_client()?.request(req))
253+
Ok(self.hyper_client()?.request(req.map(Full::new)))
255254
}
256255

257256
pub fn get_retry_after(headers: &HeaderMap<HeaderValue>) -> Option<Duration> {

core/src/spclient.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ use data_encoding::HEXUPPER_PERMISSIVE;
1010
use futures_util::future::IntoStream;
1111
use http::header::HeaderValue;
1212
use hyper::{
13-
client::ResponseFuture,
1413
header::{HeaderName, ACCEPT, AUTHORIZATION, CONTENT_TYPE, RANGE},
15-
Body, HeaderMap, Method, Request,
14+
HeaderMap, Method, Request,
1615
};
16+
use hyper_util::client::legacy::ResponseFuture;
1717
use protobuf::{Enum, Message, MessageFull};
1818
use rand::RngCore;
1919
use sha1::{Digest, Sha1};
@@ -156,7 +156,7 @@ impl SpClient {
156156
.method(&Method::POST)
157157
.uri("https://clienttoken.spotify.com/v1/clienttoken")
158158
.header(ACCEPT, HeaderValue::from_static("application/x-protobuf"))
159-
.body(Body::from(body))?;
159+
.body(body.into())?;
160160

161161
self.session().http_client().request_body(request).await
162162
}
@@ -465,7 +465,7 @@ impl SpClient {
465465
let mut request = Request::builder()
466466
.method(method)
467467
.uri(url)
468-
.body(Body::from(body.to_owned()))?;
468+
.body(body.to_owned().into())?;
469469

470470
// Reconnection logic: keep getting (cached) tokens because they might have expired.
471471
let token = self
@@ -727,7 +727,7 @@ impl SpClient {
727727
RANGE,
728728
HeaderValue::from_str(&format!("bytes={}-{}", offset, offset + length - 1))?,
729729
)
730-
.body(Body::empty())?;
730+
.body(Bytes::new())?;
731731

732732
let stream = self.session().http_client().request_stream(req)?;
733733

@@ -738,7 +738,7 @@ impl SpClient {
738738
let request = Request::builder()
739739
.method(&Method::GET)
740740
.uri(url)
741-
.body(Body::empty())?;
741+
.body(Bytes::new())?;
742742

743743
self.session().http_client().request_body(request).await
744744
}

discovery/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ edition = "2021"
1111
[dependencies]
1212
aes = "0.8"
1313
base64 = "0.21"
14+
bytes = "1"
1415
cfg-if = "1.0"
1516
ctr = "0.9"
1617
dns-sd = { version = "0.1.3", optional = true }
1718
form_urlencoded = "1.0"
1819
futures-core = "0.3"
1920
futures-util = "0.3"
2021
hmac = "0.12"
21-
hyper = { version = "0.14", features = ["http1", "server", "tcp"] }
22+
hyper = { version = "1.3", features = ["http1"] }
23+
hyper-util = { version = "0.1", features = ["server-auto", "server-graceful", "service"] }
24+
http-body-util = "0.1.1"
2225
libmdns = "0.8"
2326
log = "0.4"
2427
rand = "0.8"

0 commit comments

Comments
 (0)