Add ap-port option to specify preferred port

This commit is contained in:
Harold 2018-07-03 13:09:22 +02:00
parent 00e89343fb
commit 4fb3d5f271
4 changed files with 31 additions and 14 deletions

View file

@ -17,7 +17,11 @@ pub struct APResolveData {
ap_list: Vec<String>, ap_list: Vec<String>,
} }
fn apresolve(handle: &Handle, proxy: &Option<Url>) -> Box<Future<Item = String, Error = Error>> { fn apresolve(
handle: &Handle,
proxy: &Option<Url>,
ap_port: &Option<u16>,
) -> Box<Future<Item = String, Error = Error>> {
let url = Uri::from_str(APRESOLVE_ENDPOINT).expect("invalid AP resolve URL"); let url = Uri::from_str(APRESOLVE_ENDPOINT).expect("invalid AP resolve URL");
let use_proxy = proxy.is_some(); let use_proxy = proxy.is_some();
@ -53,9 +57,15 @@ fn apresolve(handle: &Handle, proxy: &Option<Url>) -> Box<Future<Item = String,
let data = let data =
body.and_then(|body| serde_json::from_str::<APResolveData>(&body).chain_err(|| "invalid JSON")); body.and_then(|body| serde_json::from_str::<APResolveData>(&body).chain_err(|| "invalid JSON"));
let p = ap_port.clone();
let ap = data.and_then(move |data| { let ap = data.and_then(move |data| {
let mut aps = data.ap_list.iter().filter(|ap| { let mut aps = data.ap_list.iter().filter(|ap| {
if use_proxy { if p.is_some() {
Uri::from_str(ap)
.ok()
.map_or(false, |uri| uri.port().map_or(false, |port| port == p.unwrap()))
} else if use_proxy {
// It is unlikely that the proxy will accept CONNECT on anything other than 443. // It is unlikely that the proxy will accept CONNECT on anything other than 443.
Uri::from_str(ap) Uri::from_str(ap)
.ok() .ok()
@ -75,11 +85,12 @@ fn apresolve(handle: &Handle, proxy: &Option<Url>) -> Box<Future<Item = String,
pub(crate) fn apresolve_or_fallback<E>( pub(crate) fn apresolve_or_fallback<E>(
handle: &Handle, handle: &Handle,
proxy: &Option<Url>, proxy: &Option<Url>,
ap_port: &Option<u16>,
) -> Box<Future<Item = String, Error = E>> ) -> Box<Future<Item = String, Error = E>>
where where
E: 'static, E: 'static,
{ {
let ap = apresolve(handle, proxy).or_else(|e| { let ap = apresolve(handle, proxy, ap_port).or_else(|e| {
warn!("Failed to resolve Access Point: {}", e.description()); warn!("Failed to resolve Access Point: {}", e.description());
warn!("Using fallback \"{}\"", AP_FALLBACK); warn!("Using fallback \"{}\"", AP_FALLBACK);
Ok(AP_FALLBACK.into()) Ok(AP_FALLBACK.into())

View file

@ -10,6 +10,7 @@ pub struct SessionConfig {
pub user_agent: String, pub user_agent: String,
pub device_id: String, pub device_id: String,
pub proxy: Option<Url>, pub proxy: Option<Url>,
pub ap_port: Option<u16>,
} }
impl Default for SessionConfig { impl Default for SessionConfig {
@ -19,6 +20,7 @@ impl Default for SessionConfig {
user_agent: version::version_string(), user_agent: version::version_string(),
device_id: device_id, device_id: device_id,
proxy: None, proxy: None,
ap_port: None,
} }
} }
} }

View file

@ -51,7 +51,7 @@ impl Session {
cache: Option<Cache>, cache: Option<Cache>,
handle: Handle, handle: Handle,
) -> Box<Future<Item = Session, Error = io::Error>> { ) -> Box<Future<Item = Session, Error = io::Error>> {
let access_point = apresolve_or_fallback::<io::Error>(&handle, &config.proxy); let access_point = apresolve_or_fallback::<io::Error>(&handle, &config.proxy, &config.ap_port);
let handle_ = handle.clone(); let handle_ = handle.clone();
let proxy = config.proxy.clone(); let proxy = config.proxy.clone();

View file

@ -129,6 +129,7 @@ fn setup(args: &[String]) -> Setup {
.optopt("u", "username", "Username to sign in with", "USERNAME") .optopt("u", "username", "Username to sign in with", "USERNAME")
.optopt("p", "password", "Password", "PASSWORD") .optopt("p", "password", "Password", "PASSWORD")
.optopt("", "proxy", "HTTP proxy to use when connecting", "PROXY") .optopt("", "proxy", "HTTP proxy to use when connecting", "PROXY")
.optopt("", "ap-port", "Connect to AP with specified port. If no AP with that port are present fallback AP will be used. Available ports are usually 80, 443 and 4070", "AP_PORT")
.optflag("", "disable-discovery", "Disable discovery mode") .optflag("", "disable-discovery", "Disable discovery mode")
.optopt( .optopt(
"", "",
@ -255,20 +256,23 @@ fn setup(args: &[String]) -> Setup {
proxy: matches.opt_str("proxy").or(std::env::var("http_proxy").ok()).map( proxy: matches.opt_str("proxy").or(std::env::var("http_proxy").ok()).map(
|s| { |s| {
match Url::parse(&s) { match Url::parse(&s) {
Ok(url) => { Ok(url) => {
if url.host().is_none() || url.port().is_none() { if url.host().is_none() || url.port().is_none() {
panic!("Invalid proxy url, only urls on the format \"http://host:port\" are allowed"); panic!("Invalid proxy url, only urls on the format \"http://host:port\" are allowed");
} }
if url.scheme() != "http" { if url.scheme() != "http" {
panic!("Only unsecure http:// proxies are supported"); panic!("Only unsecure http:// proxies are supported");
}
url
},
Err(err) => panic!("Invalid proxy url: {}, only urls on the format \"http://host:port\" are allowed", err)
} }
url
},
Err(err) => panic!("Invalid proxy url: {}, only urls on the format \"http://host:port\" are allowed", err)
}
}, },
), ),
ap_port: matches
.opt_str("ap-port")
.map(|port| port.parse::<u16>().expect("Invalid port")),
} }
}; };