mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Resolve access point when connecting and pick a random one.
Spotify’s apresolve will return the best AP based on the user’s location.
This commit is contained in:
parent
60db12ee9e
commit
25bd38fd13
7 changed files with 148 additions and 3 deletions
113
Cargo.lock
generated
113
Cargo.lock
generated
|
@ -7,6 +7,7 @@ dependencies = [
|
||||||
"dns-sd 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dns-sd 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"eventual 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"eventual 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"hyper 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"json_macros 0.3.0 (git+https://github.com/plietar/json_macros)",
|
"json_macros 0.3.0 (git+https://github.com/plietar/json_macros)",
|
||||||
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"librespot-protocol 0.1.0",
|
"librespot-protocol 0.1.0",
|
||||||
|
@ -84,6 +85,15 @@ name = "chunked_transfer"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dns-sd"
|
name = "dns-sd"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -170,6 +180,39 @@ name = "getopts"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hpack"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httparse"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cookie 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"httparse 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mime 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicase 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "json_macros"
|
name = "json_macros"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -191,6 +234,11 @@ dependencies = [
|
||||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "language-tags"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
|
@ -227,6 +275,15 @@ name = "matches"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num"
|
name = "num"
|
||||||
version = "0.1.31"
|
version = "0.1.31"
|
||||||
|
@ -236,6 +293,14 @@ dependencies = [
|
||||||
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ogg-sys"
|
name = "ogg-sys"
|
||||||
version = "0.0.9"
|
version = "0.0.9"
|
||||||
|
@ -350,6 +415,27 @@ name = "rustc-serialize"
|
||||||
version = "0.3.18"
|
version = "0.3.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.1.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "0.6.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shannon"
|
name = "shannon"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -369,6 +455,15 @@ dependencies = [
|
||||||
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "solicit"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syncbox"
|
name = "syncbox"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
|
@ -450,6 +545,11 @@ dependencies = [
|
||||||
"url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "traitobject"
|
||||||
|
version = "0.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tremor"
|
name = "tremor"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -469,6 +569,19 @@ dependencies = [
|
||||||
"ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typeable"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
|
|
@ -20,6 +20,7 @@ bit-set = "~0.2.0"
|
||||||
byteorder = "~0.4.2"
|
byteorder = "~0.4.2"
|
||||||
eventual = "~0.1.5"
|
eventual = "~0.1.5"
|
||||||
getopts = "~0.2.14"
|
getopts = "~0.2.14"
|
||||||
|
hyper = { version = "0.7.2", default-features = false }
|
||||||
#json_macros = "~0.3.0"
|
#json_macros = "~0.3.0"
|
||||||
lazy_static = "~0.1.15"
|
lazy_static = "~0.1.15"
|
||||||
num = "~0.1.30"
|
num = "~0.1.30"
|
||||||
|
|
23
src/apresolve.rs
Normal file
23
src/apresolve.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
const APRESOLVE_ENDPOINT : &'static str = "http://apresolve.spotify.com/";
|
||||||
|
|
||||||
|
use hyper;
|
||||||
|
use std::io::Read;
|
||||||
|
use rustc_serialize::json;
|
||||||
|
|
||||||
|
#[derive(RustcDecodable)]
|
||||||
|
pub struct APResolveData {
|
||||||
|
ap_list: Vec<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apresolve() -> Result<Vec<String>, ()> {
|
||||||
|
let client = hyper::client::Client::new();
|
||||||
|
let mut res = String::new();
|
||||||
|
|
||||||
|
client.get(APRESOLVE_ENDPOINT)
|
||||||
|
.send().unwrap()
|
||||||
|
.read_to_string(&mut res).unwrap();
|
||||||
|
|
||||||
|
let data : APResolveData = json::decode(&res).unwrap();
|
||||||
|
|
||||||
|
Ok(data.ap_list)
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
use apresolve::apresolve;
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
use crypto;
|
use crypto;
|
||||||
use crypto::aes;
|
use crypto::aes;
|
||||||
|
@ -8,6 +9,7 @@ use crypto::pbkdf2::pbkdf2;
|
||||||
use crypto::sha1::Sha1;
|
use crypto::sha1::Sha1;
|
||||||
use protobuf::{self, Message, ProtobufEnum};
|
use protobuf::{self, Message, ProtobufEnum};
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
|
use rand::Rng;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use rustc_serialize::base64::FromBase64;
|
use rustc_serialize::base64::FromBase64;
|
||||||
|
@ -47,7 +49,11 @@ impl Session {
|
||||||
pub fn connect(&self) -> CipherConnection {
|
pub fn connect(&self) -> CipherConnection {
|
||||||
let local_keys = DHLocalKeys::random(&mut thread_rng());
|
let local_keys = DHLocalKeys::random(&mut thread_rng());
|
||||||
|
|
||||||
let mut connection = PlainConnection::connect().unwrap();
|
let aps = apresolve().unwrap();
|
||||||
|
let ap = thread_rng().choose(&aps).expect("No APs found");
|
||||||
|
|
||||||
|
println!("Connecting to AP {}", ap);
|
||||||
|
let mut connection = PlainConnection::connect(ap).unwrap();
|
||||||
|
|
||||||
let request = protobuf_init!(protocol::keyexchange::ClientHello::new(), {
|
let request = protobuf_init!(protocol::keyexchange::ClientHello::new(), {
|
||||||
build_info => {
|
build_info => {
|
||||||
|
|
|
@ -39,9 +39,9 @@ pub struct CipherConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlainConnection {
|
impl PlainConnection {
|
||||||
pub fn connect() -> Result<PlainConnection> {
|
pub fn connect(ap: &str) -> Result<PlainConnection> {
|
||||||
Ok(PlainConnection {
|
Ok(PlainConnection {
|
||||||
stream: try!(TcpStream::connect("lon3-accesspoint-a26.ap.spotify.com:4070")),
|
stream: try!(TcpStream::connect(ap)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,4 +13,5 @@ pub mod session;
|
||||||
pub mod spirc;
|
pub mod spirc;
|
||||||
pub mod link;
|
pub mod link;
|
||||||
mod stream;
|
mod stream;
|
||||||
|
pub mod apresolve;
|
||||||
mod zeroconf;
|
mod zeroconf;
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern crate bit_set;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate crypto;
|
extern crate crypto;
|
||||||
extern crate eventual;
|
extern crate eventual;
|
||||||
|
extern crate hyper;
|
||||||
extern crate num;
|
extern crate num;
|
||||||
extern crate portaudio;
|
extern crate portaudio;
|
||||||
extern crate protobuf;
|
extern crate protobuf;
|
||||||
|
|
Loading…
Reference in a new issue