1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-04 10:19:27 +02:00

Put apresolve behind feature flag

This commit is contained in:
johannesd3 2021-02-10 22:50:08 +01:00 committed by Johannesd3
parent 9253be7bc9
commit 8cff10e983
6 changed files with 124 additions and 101 deletions

View file

@ -1,61 +1,72 @@
const AP_FALLBACK: &'static str = "ap.spotify.com:443";
const APRESOLVE_ENDPOINT: &'static str = "http://apresolve.spotify.com:80";
use hyper::{Body, Client, Method, Request, Uri};
use std::error::Error;
use url::Url;
use crate::proxytunnel::ProxyTunnel;
cfg_if! {
if #[cfg(feature = "apresolve")] {
const APRESOLVE_ENDPOINT: &'static str = "http://apresolve.spotify.com:80";
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct APResolveData {
ap_list: Vec<String>,
}
use std::error::Error;
async fn apresolve(proxy: &Option<Url>, ap_port: &Option<u16>) -> Result<String, Box<dyn Error>> {
let port = ap_port.unwrap_or(443);
use hyper::{Body, Client, Method, Request, Uri};
let req = Request::builder()
.method(Method::GET)
.uri(
APRESOLVE_ENDPOINT
.parse::<Uri>()
.expect("invalid AP resolve URL"),
)
.body(Body::empty())?;
use crate::proxytunnel::ProxyTunnel;
let response = if let Some(url) = proxy {
Client::builder()
.build(ProxyTunnel::new(url)?)
.request(req)
.await?
} else {
Client::new().request(req).await?
};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct APResolveData {
ap_list: Vec<String>,
}
let body = hyper::body::to_bytes(response.into_body()).await?;
let data: APResolveData = serde_json::from_slice(body.as_ref())?;
async fn apresolve(proxy: &Option<Url>, ap_port: &Option<u16>) -> Result<String, Box<dyn Error>> {
let port = ap_port.unwrap_or(443);
let ap = if ap_port.is_some() || proxy.is_some() {
data.ap_list.into_iter().find_map(|ap| {
if ap.parse::<Uri>().ok()?.port()? == port {
Some(ap)
let req = Request::builder()
.method(Method::GET)
.uri(
APRESOLVE_ENDPOINT
.parse::<Uri>()
.expect("invalid AP resolve URL"),
)
.body(Body::empty())?;
let response = if let Some(url) = proxy {
Client::builder()
.build(ProxyTunnel::new(url)?)
.request(req)
.await?
} else {
None
Client::new().request(req).await?
};
let body = hyper::body::to_bytes(response.into_body()).await?;
let data: APResolveData = serde_json::from_slice(body.as_ref())?;
let ap = if ap_port.is_some() || proxy.is_some() {
data.ap_list.into_iter().find_map(|ap| {
if ap.parse::<Uri>().ok()?.port()? == port {
Some(ap)
} else {
None
}
})
} else {
data.ap_list.into_iter().next()
}
})
.ok_or("empty AP List")?;
Ok(ap)
}
pub async fn apresolve_or_fallback(proxy: &Option<Url>, ap_port: &Option<u16>) -> String {
apresolve(proxy, ap_port).await.unwrap_or_else(|e| {
warn!("Failed to resolve Access Point: {}", e);
warn!("Using fallback \"{}\"", AP_FALLBACK);
AP_FALLBACK.into()
})
}
} else {
data.ap_list.into_iter().next()
pub async fn apresolve_or_fallback(_: &Option<Url>, _: &Option<u16>) -> String {
AP_FALLBACK.to_string()
}
}
.ok_or("empty AP List")?;
Ok(ap)
}
pub async fn apresolve_or_fallback(proxy: &Option<Url>, ap_port: &Option<u16>) -> String {
apresolve(proxy, ap_port).await.unwrap_or_else(|e| {
warn!("Failed to resolve Access Point: {}", e);
warn!("Using fallback \"{}\"", AP_FALLBACK);
AP_FALLBACK.into()
})
}