2018-03-23 05:15:15 +00:00
|
|
|
const AP_FALLBACK: &'static str = "ap.spotify.com:443";
|
2016-03-13 20:03:09 +00:00
|
|
|
|
2018-03-24 08:00:38 +00:00
|
|
|
use url::Url;
|
2016-03-13 20:03:09 +00:00
|
|
|
|
2021-02-10 21:50:08 +00:00
|
|
|
cfg_if! {
|
|
|
|
if #[cfg(feature = "apresolve")] {
|
|
|
|
const APRESOLVE_ENDPOINT: &'static str = "http://apresolve.spotify.com:80";
|
2021-01-30 13:45:31 +00:00
|
|
|
|
2021-02-10 21:50:08 +00:00
|
|
|
use std::error::Error;
|
2016-03-13 20:03:09 +00:00
|
|
|
|
2021-02-10 21:50:08 +00:00
|
|
|
use hyper::{Body, Client, Method, Request, Uri};
|
|
|
|
|
|
|
|
use crate::proxytunnel::ProxyTunnel;
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
pub struct APResolveData {
|
|
|
|
ap_list: Vec<String>,
|
|
|
|
}
|
2017-01-18 15:17:10 +00:00
|
|
|
|
2021-02-10 21:50:08 +00:00
|
|
|
async fn apresolve(proxy: &Option<Url>, ap_port: &Option<u16>) -> Result<String, Box<dyn Error>> {
|
|
|
|
let port = ap_port.unwrap_or(443);
|
2018-07-03 11:09:22 +00:00
|
|
|
|
2021-02-10 21:50:08 +00:00
|
|
|
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?
|
2018-03-23 15:52:24 +00:00
|
|
|
} else {
|
2021-02-10 21:50:08 +00:00
|
|
|
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()
|
2018-03-23 15:52:24 +00:00
|
|
|
}
|
2021-02-10 21:50:08 +00:00
|
|
|
.ok_or("empty AP List")?;
|
2021-01-25 19:55:49 +00:00
|
|
|
|
2021-02-10 21:50:08 +00:00
|
|
|
Ok(ap)
|
|
|
|
}
|
2016-12-31 13:30:01 +00:00
|
|
|
|
2021-02-10 21:50:08 +00:00
|
|
|
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 {
|
|
|
|
pub async fn apresolve_or_fallback(_: &Option<Url>, _: &Option<u16>) -> String {
|
|
|
|
AP_FALLBACK.to_string()
|
|
|
|
}
|
|
|
|
}
|
2016-03-13 20:03:09 +00:00
|
|
|
}
|