Преглед изворни кода

Resolve access point when connecting and pick a random one.

Spotify’s apresolve will return the best AP based on the user’s location.
Paul Lietar пре 9 година
родитељ
комит
25bd38fd13
7 измењених фајлова са 148 додато и 3 уклоњено
  1. 113 0
      Cargo.lock
  2. 1 0
      Cargo.toml
  3. 23 0
      src/apresolve.rs
  4. 7 1
      src/authentication.rs
  5. 2 2
      src/connection.rs
  6. 1 0
      src/lib.in.rs
  7. 1 0
      src/lib.rs

+ 113 - 0
Cargo.lock

@@ -7,6 +7,7 @@ dependencies = [
  "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)",
  "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)",
  "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "librespot-protocol 0.1.0",
@@ -84,6 +85,15 @@ name = "chunked_transfer"
 version = "0.3.1"
 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]]
 name = "dns-sd"
 version = "0.1.3"
@@ -170,6 +180,39 @@ name = "getopts"
 version = "0.2.14"
 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]]
 name = "json_macros"
 version = "0.3.0"
@@ -191,6 +234,11 @@ dependencies = [
  "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]]
 name = "lazy_static"
 version = "0.1.15"
@@ -227,6 +275,15 @@ name = "matches"
 version = "0.1.2"
 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]]
 name = "num"
 version = "0.1.31"
@@ -236,6 +293,14 @@ dependencies = [
  "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]]
 name = "ogg-sys"
 version = "0.0.9"
@@ -350,6 +415,27 @@ name = "rustc-serialize"
 version = "0.3.18"
 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]]
 name = "shannon"
 version = "0.1.1"
@@ -369,6 +455,15 @@ dependencies = [
  "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]]
 name = "syncbox"
 version = "0.2.4"
@@ -450,6 +545,11 @@ dependencies = [
  "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]]
 name = "tremor"
 version = "0.1.0"
@@ -469,6 +569,19 @@ dependencies = [
  "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]]
 name = "unicode-bidi"
 version = "0.2.3"

+ 1 - 0
Cargo.toml

@@ -20,6 +20,7 @@ bit-set         = "~0.2.0"
 byteorder       = "~0.4.2"
 eventual        = "~0.1.5"
 getopts         = "~0.2.14"
+hyper           = { version = "0.7.2", default-features = false }
 #json_macros     = "~0.3.0"
 lazy_static     = "~0.1.15"
 num             = "~0.1.30"

+ 23 - 0
src/apresolve.rs

@@ -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)
+}

+ 7 - 1
src/authentication.rs

@@ -1,3 +1,4 @@
+use apresolve::apresolve;
 use byteorder::{BigEndian, ByteOrder};
 use crypto;
 use crypto::aes;
@@ -8,6 +9,7 @@ use crypto::pbkdf2::pbkdf2;
 use crypto::sha1::Sha1;
 use protobuf::{self, Message, ProtobufEnum};
 use rand::thread_rng;
+use rand::Rng;
 use std::io::{self, Read, Write};
 use std::result::Result;
 use rustc_serialize::base64::FromBase64;
@@ -47,7 +49,11 @@ impl Session {
     pub fn connect(&self) -> CipherConnection {
         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(), {
             build_info => {

+ 2 - 2
src/connection.rs

@@ -39,9 +39,9 @@ pub struct CipherConnection {
 }
 
 impl PlainConnection {
-    pub fn connect() -> Result<PlainConnection> {
+    pub fn connect(ap: &str) -> Result<PlainConnection> {
         Ok(PlainConnection {
-            stream: try!(TcpStream::connect("lon3-accesspoint-a26.ap.spotify.com:4070")),
+            stream: try!(TcpStream::connect(ap)),
         })
     }
 

+ 1 - 0
src/lib.in.rs

@@ -13,4 +13,5 @@ pub mod session;
 pub mod spirc;
 pub mod link;
 mod stream;
+pub mod apresolve;
 mod zeroconf;

+ 1 - 0
src/lib.rs

@@ -11,6 +11,7 @@ extern crate bit_set;
 extern crate byteorder;
 extern crate crypto;
 extern crate eventual;
+extern crate hyper;
 extern crate num;
 extern crate portaudio;
 extern crate protobuf;