mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-03 01:39:28 +02:00
Add spclient and HTTPS support
* Change metadata to use spclient * Add support for HTTPS proxies * Start purging unwraps and using Result instead
This commit is contained in:
parent
56585cabb6
commit
d19fd24074
19 changed files with 652 additions and 100 deletions
|
@ -1,12 +1,25 @@
|
|||
use hyper::client::HttpConnector;
|
||||
use hyper::{Body, Client, Request, Response};
|
||||
use hyper::{Body, Client, Request, Response, StatusCode};
|
||||
use hyper_proxy::{Intercept, Proxy, ProxyConnector};
|
||||
use hyper_rustls::HttpsConnector;
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
pub struct HttpClient {
|
||||
proxy: Option<Url>,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum HttpClientError {
|
||||
#[error("could not parse request: {0}")]
|
||||
Parsing(#[from] http::uri::InvalidUri),
|
||||
#[error("could not send request: {0}")]
|
||||
Request(hyper::Error),
|
||||
#[error("could not read response: {0}")]
|
||||
Response(hyper::Error),
|
||||
#[error("could not build proxy connector: {0}")]
|
||||
ProxyBuilder(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
impl HttpClient {
|
||||
pub fn new(proxy: Option<&Url>) -> Self {
|
||||
Self {
|
||||
|
@ -14,21 +27,41 @@ impl HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn request(&self, req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
|
||||
if let Some(url) = &self.proxy {
|
||||
// Panic safety: all URLs are valid URIs
|
||||
let uri = url.to_string().parse().unwrap();
|
||||
pub async fn request(&self, req: Request<Body>) -> Result<Response<Body>, HttpClientError> {
|
||||
let connector = HttpsConnector::with_native_roots();
|
||||
let uri = req.uri().clone();
|
||||
|
||||
let response = if let Some(url) = &self.proxy {
|
||||
let uri = url.to_string().parse()?;
|
||||
let proxy = Proxy::new(Intercept::All, uri);
|
||||
let connector = HttpConnector::new();
|
||||
let proxy_connector = ProxyConnector::from_proxy_unsecured(connector, proxy);
|
||||
Client::builder().build(proxy_connector).request(req).await
|
||||
let proxy_connector = ProxyConnector::from_proxy(connector, proxy)?;
|
||||
|
||||
Client::builder()
|
||||
.build(proxy_connector)
|
||||
.request(req)
|
||||
.await
|
||||
.map_err(HttpClientError::Request)
|
||||
} else {
|
||||
Client::new().request(req).await
|
||||
Client::builder()
|
||||
.build(connector)
|
||||
.request(req)
|
||||
.await
|
||||
.map_err(HttpClientError::Request)
|
||||
};
|
||||
|
||||
if let Ok(response) = &response {
|
||||
if response.status() != StatusCode::OK {
|
||||
debug!("{} returned status {}", uri, response.status());
|
||||
}
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
pub async fn request_body(&self, req: Request<Body>) -> Result<bytes::Bytes, hyper::Error> {
|
||||
pub async fn request_body(&self, req: Request<Body>) -> Result<bytes::Bytes, HttpClientError> {
|
||||
let response = self.request(req).await?;
|
||||
hyper::body::to_bytes(response.into_body()).await
|
||||
hyper::body::to_bytes(response.into_body())
|
||||
.await
|
||||
.map_err(HttpClientError::Response)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue