Browse Source

Move authentication to a different directory, and make discover use hyper.

Paul Lietar 10 năm trước cách đây
mục cha
commit
0770f6ce61
12 tập tin đã thay đổi với 223 bổ sung và 328 xóa
  1. 0 100
      Cargo.lock
  2. 0 1
      Cargo.toml
  3. 188 0
      src/authentication/discovery.rs
  4. 1 1
      src/authentication/facebook.rs
  5. 17 0
      src/authentication/mod.rs
  6. 0 167
      src/discovery.rs
  7. 0 5
      src/lib.in.rs
  8. 0 1
      src/lib.rs
  9. 11 17
      src/main.rs
  10. 5 5
      src/session.rs
  11. 1 1
      src/spirc.rs
  12. 0 30
      src/zeroconf.rs

+ 0 - 100
Cargo.lock

@@ -26,7 +26,6 @@ dependencies = [
  "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "tiny_http 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tremor 0.1.0 (git+https://github.com/plietar/rust-tremor)",
  "url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -41,11 +40,6 @@ dependencies = [
  "memchr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "ascii"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "aster"
 version = "0.13.1"
@@ -92,20 +86,6 @@ name = "byteorder"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "chrono"
-version = "0.2.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "chunked_transfer"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "clippy"
 version = "0.0.53"
@@ -137,63 +117,6 @@ dependencies = [
  "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "encoding"
-version = "0.2.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "encoding-index-japanese"
-version = "1.20141219.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "encoding-index-korean"
-version = "1.20141219.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "encoding-index-simpchinese"
-version = "1.20141219.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "encoding-index-singlebyte"
-version = "1.20141219.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "encoding-index-tradchinese"
-version = "1.20141219.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "encoding_index_tests"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "eventual"
 version = "0.1.5"
@@ -691,19 +614,6 @@ dependencies = [
  "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "tiny_http"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "ascii 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "chrono 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
- "chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "toml"
 version = "0.1.28"
@@ -767,16 +677,6 @@ name = "unicode-xid"
 version = "0.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "url"
-version = "0.2.38"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "url"
 version = "0.5.7"

+ 0 - 1
Cargo.toml

@@ -32,7 +32,6 @@ rust-crypto     = "~0.2.34"
 rustc-serialize = "~0.3.16"
 tempfile        = "~2.0.0"
 time            = "~0.1.34"
-tiny_http       = "~0.5.1"
 url             = "~0.5.2"
 vorbis          = "~0.0.14"
 

+ 188 - 0
src/authentication/discovery.rs

@@ -0,0 +1,188 @@
+use crypto;
+use crypto::mac::Mac;
+use crypto::digest::Digest;
+use dns_sd::DNSService;
+use hyper;
+use hyper::net::NetworkListener;
+use num::BigUint;
+use url;
+use rand;
+use rustc_serialize::base64::{self, ToBase64, FromBase64};
+use std::collections::BTreeMap;
+use std::io::{Read, Write};
+use std::sync::{mpsc, Mutex};
+
+use authentication::Credentials;
+use diffie_hellman::{DH_GENERATOR, DH_PRIME};
+use util;
+
+struct ServerHandler {
+    credentials_tx: Mutex<mpsc::Sender<Credentials>>,
+    private_key: BigUint,
+    public_key: BigUint,
+    device_id: String,
+    device_name: String,
+}
+
+impl ServerHandler {
+    fn handle_get_info(&self, _params: &BTreeMap<String, String>,
+                       mut response: hyper::server::Response<hyper::net::Fresh>) {
+
+        let public_key = self.public_key.to_bytes_be()
+                                        .to_base64(base64::STANDARD);
+
+        let result = json!({
+            "status": 101,
+            "statusString": "ERROR-OK",
+            "spotifyError": 0,
+            "version": "2.1.0",
+            "deviceID": (self.device_id),
+            "remoteName": (self.device_name),
+            "activeUser": "",
+            "publicKey": (public_key),
+            "deviceType": "UNKNOWN",
+            "libraryVersion": "0.1.0",
+            "accountReq": "PREMIUM",
+            "brandDisplayName": "librespot",
+            "modelDisplayName": "librespot",
+        });
+
+        *response.status_mut() = hyper::status::StatusCode::Ok;
+        response.start().unwrap().write_all(result.to_string().as_bytes()).unwrap();
+    }
+
+    fn handle_add_user(&self, params: &BTreeMap<String, String>,
+                       mut response: hyper::server::Response<hyper::net::Fresh>) {
+
+        let username = params.get("userName").unwrap();
+        let encrypted_blob = params.get("blob").unwrap();
+        let client_key = params.get("clientKey").unwrap();
+
+        let encrypted_blob = encrypted_blob.from_base64().unwrap();
+
+        let client_key = client_key.from_base64().unwrap();
+        let client_key = BigUint::from_bytes_be(&client_key);
+
+        let shared_key = util::powm(&client_key, &self.private_key, &DH_PRIME);
+
+        let iv = &encrypted_blob[0..16];
+        let encrypted = &encrypted_blob[16..encrypted_blob.len() - 20];
+        let cksum = &encrypted_blob[encrypted_blob.len() - 20..encrypted_blob.len()];
+
+        let base_key = {
+            let mut data = [0u8; 20];
+            let mut h = crypto::sha1::Sha1::new();
+            h.input(&shared_key.to_bytes_be());
+            h.result(&mut data);
+            data[..16].to_owned()
+        };
+
+        let checksum_key = {
+            let mut h = crypto::hmac::Hmac::new(crypto::sha1::Sha1::new(), &base_key);
+            h.input("checksum".as_bytes());
+            h.result().code().to_owned()
+        };
+
+        let encryption_key = {
+            let mut h = crypto::hmac::Hmac::new(crypto::sha1::Sha1::new(), &base_key);
+            h.input("encryption".as_bytes());
+            h.result().code().to_owned()
+        };
+
+        let mac = {
+            let mut h = crypto::hmac::Hmac::new(crypto::sha1::Sha1::new(), &checksum_key);
+            h.input(encrypted);
+            h.result().code().to_owned()
+        };
+
+        assert_eq!(&mac[..], cksum);
+
+        let decrypted = {
+            let mut data = vec![0u8; encrypted.len()];
+            let mut cipher = crypto::aes::ctr(crypto::aes::KeySize::KeySize128,
+                                              &encryption_key[0..16],
+                                              &iv);
+            cipher.process(&encrypted, &mut data);
+            String::from_utf8(data).unwrap()
+        };
+
+        let credentials = Credentials::with_blob(username.to_owned(), &decrypted, &self.device_id);
+
+        self.credentials_tx.lock().unwrap().send(credentials).unwrap();
+
+        let result = json!({
+            "status": 101,
+            "spotifyError": 0,
+            "statusString": "ERROR-OK"
+        });
+
+        *response.status_mut() = hyper::status::StatusCode::Ok;
+        response.start().unwrap().write_all(result.to_string().as_bytes()).unwrap();
+    }
+
+    fn not_found(&self, mut response: hyper::server::Response<hyper::net::Fresh>) {
+
+        *response.status_mut() = hyper::status::StatusCode::NotFound
+    }
+}
+
+impl hyper::server::Handler for ServerHandler {
+    fn handle<'a, 'k>(&'a self,
+                      mut request: hyper::server::Request<'a, 'k>,
+                      response: hyper::server::Response<'a, hyper::net::Fresh>) {
+
+        if let hyper::uri::RequestUri::AbsolutePath(path) = request.uri.clone() {
+            let (_, query, _) = url::parse_path(&path).unwrap();
+            let mut params = query.map_or(vec![], |q| url::form_urlencoded::parse(q.as_bytes()))
+                                  .into_iter().collect::<BTreeMap<_,_>>();
+
+            if request.method == hyper::method::Method::Post {
+                let mut body = Vec::new();
+                request.read_to_end(&mut body).unwrap();
+                let form = url::form_urlencoded::parse(&body);
+                params.extend(form);
+            }
+
+            match params.get("action").map(AsRef::as_ref) {
+                Some("getInfo") => self.handle_get_info(&params, response),
+                Some("addUser") => self.handle_add_user(&params, response),
+                _ => self.not_found(response),
+            }
+        } else {
+            self.not_found(response)
+        }
+    }
+}
+
+pub fn discovery_login(device_name: &str, device_id: &str) -> Result<Credentials, ()> {
+    let (tx, rx) = mpsc::channel();
+
+    let key_data = util::rand_vec(&mut rand::thread_rng(), 95);
+    let private_key = BigUint::from_bytes_be(&key_data);
+    let public_key = util::powm(&DH_GENERATOR, &private_key, &DH_PRIME);
+
+    let handler = ServerHandler {
+        device_name: device_name.to_owned(),
+        device_id: device_id.to_owned(),
+        private_key: private_key,
+        public_key: public_key,
+        credentials_tx: Mutex::new(tx),
+    };
+
+    let mut listener = hyper::net::HttpListener::new("0.0.0.0:0").unwrap();
+    let port = listener.local_addr().unwrap().port();
+
+    let mut server = hyper::Server::new(listener).handle(handler).unwrap();
+
+    let _svc = DNSService::register(Some(device_name),
+                                    "_spotify-connect._tcp",
+                                    None,
+                                    None,
+                                    port,
+                                    &["VERSION=1.0", "CPath=/"]
+                                    ).unwrap();
+
+    let cred = rx.recv().unwrap();
+    server.close().unwrap();
+    Ok(cred)
+}

+ 1 - 1
src/facebook.rs → src/authentication/facebook.rs

@@ -72,7 +72,7 @@ impl hyper::server::Handler for ServerHandler {
     }
 }
 
-pub fn facebook_get_me_id(token: &str) -> Result<String, ()> {
+fn facebook_get_me_id(token: &str) -> Result<String, ()> {
     let url = format!("https://graph.facebook.com/me?fields=id&access_token={}", token);
 
     let client = hyper::Client::new();

+ 17 - 0
src/authentication.rs → src/authentication/mod.rs

@@ -163,3 +163,20 @@ impl From<StoredCredentials> for Credentials {
     }
 }
 
+#[cfg(feature = "discovery")]
+mod discovery;
+#[cfg(feature = "discovery")]
+pub use self::discovery::discovery_login;
+#[cfg(not(feature = "discovery"))]
+pub fn discovery_login(device_name: &str, device_id: &str) -> Result<Credentials, ()> {
+    Err(())
+}
+
+#[cfg(feature = "facebook")]
+mod facebook;
+#[cfg(feature = "facebook")]
+pub use self::facebook::facebook_login;
+#[cfg(not(feature = "facebook"))]
+pub fn facebook_login() -> Result<Credentials, ()> {
+    Err(())
+}

+ 0 - 167
src/discovery.rs

@@ -1,167 +0,0 @@
-use crypto;
-use crypto::mac::Mac;
-use crypto::digest::Digest;
-use num::BigUint;
-use url;
-use rand;
-use rustc_serialize::base64::{self, ToBase64, FromBase64};
-use tiny_http::{Method, Request, Response, ResponseBox, Server};
-use zeroconf::DNSService;
-
-use authentication::Credentials;
-use session::Session;
-use diffie_hellman::{DH_GENERATOR, DH_PRIME};
-use util;
-
-pub struct DiscoveryManager {
-    session: Session,
-    private_key: BigUint,
-    public_key: BigUint,
-}
-
-fn not_found() -> ResponseBox {
-    Response::from_string("Not found").with_status_code(404).boxed()
-}
-
-impl DiscoveryManager {
-    pub fn new(session: Session) -> DiscoveryManager {
-        let key_data = util::rand_vec(&mut rand::thread_rng(), 95);
-        let private_key = BigUint::from_bytes_be(&key_data);
-        let public_key = util::powm(&DH_GENERATOR, &private_key, &DH_PRIME);
-
-        DiscoveryManager {
-            session: session,
-            private_key: private_key,
-            public_key: public_key,
-        }
-    }
-
-    fn get_info(&self) -> ResponseBox {
-        let public_key = self.public_key.to_bytes_be().to_base64(base64::STANDARD);
-        Response::from_string(json!({
-            "status": 101,
-            "statusString": "ERROR-OK",
-            "spotifyError": 0,
-            "version": "2.1.0",
-            "deviceID": (self.session.device_id()),
-            "remoteName": (self.session.config().device_name),
-            "activeUser": "",
-            "publicKey": (public_key),
-            "deviceType": "UNKNOWN",
-            "libraryVersion": "0.1.0",
-            "accountReq": "PREMIUM",
-            "brandDisplayName": "librespot",
-            "modelDisplayName": "librespot",
-        }).to_string()).boxed()
-    }
-
-    fn add_user(&self, params: &[(String, String)]) -> (ResponseBox, Credentials) {
-        let &(_, ref username) = params.iter().find(|&&(ref key, _)| key == "userName").unwrap();
-        let &(_, ref encrypted_blob) = params.iter().find(|&&(ref key, _)| key == "blob").unwrap();
-        let &(_, ref client_key) = params.iter().find(|&&(ref key, _)| key == "clientKey").unwrap();
-
-        let encrypted_blob = encrypted_blob.from_base64().unwrap();
-
-        let client_key = client_key.from_base64().unwrap();
-        let client_key = BigUint::from_bytes_be(&client_key);
-
-        let shared_key = util::powm(&client_key, &self.private_key, &DH_PRIME);
-
-        let iv = &encrypted_blob[0..16];
-        let encrypted = &encrypted_blob[16..encrypted_blob.len() - 20];
-        let cksum = &encrypted_blob[encrypted_blob.len() - 20..encrypted_blob.len()];
-
-        let base_key = {
-            let mut data = [0u8; 20];
-            let mut h = crypto::sha1::Sha1::new();
-            h.input(&shared_key.to_bytes_be());
-            h.result(&mut data);
-            data[..16].to_owned()
-        };
-
-        let checksum_key = {
-            let mut h = crypto::hmac::Hmac::new(crypto::sha1::Sha1::new(), &base_key);
-            h.input("checksum".as_bytes());
-            h.result().code().to_owned()
-        };
-
-        let encryption_key = {
-            let mut h = crypto::hmac::Hmac::new(crypto::sha1::Sha1::new(), &base_key);
-            h.input("encryption".as_bytes());
-            h.result().code().to_owned()
-        };
-
-        let mac = {
-            let mut h = crypto::hmac::Hmac::new(crypto::sha1::Sha1::new(), &checksum_key);
-            h.input(encrypted);
-            h.result().code().to_owned()
-        };
-
-        assert_eq!(&mac[..], cksum);
-
-        let decrypted = {
-            let mut data = vec![0u8; encrypted.len()];
-            let mut cipher = crypto::aes::ctr(crypto::aes::KeySize::KeySize128,
-                                              &encryption_key[0..16],
-                                              &iv);
-            cipher.process(&encrypted, &mut data);
-            String::from_utf8(data).unwrap()
-        };
-
-        let response = Response::from_string(json!({
-            "status": 101,
-            "spotifyError": 0,
-            "statusString": "ERROR-OK"
-        }).to_string()).boxed();
-
-        let credentials = Credentials::with_blob(username.to_owned(), &decrypted, &self.session.device_id());
-
-        (response, credentials)
-    }
-
-    fn handle_request(&self, mut request: Request) -> Option<Credentials> {
-        let (_, query, _) = url::parse_path(request.url()).unwrap();
-        let mut params = query.map_or(vec![], |q| url::form_urlencoded::parse(q.as_bytes()));
-
-        if *request.method() == Method::Post {
-            let mut body = Vec::new();
-            request.as_reader().read_to_end(&mut body).unwrap();
-            let form = url::form_urlencoded::parse(&body);
-            params.extend(form);
-        }
-
-        println!("{:?}", params);
-
-        let &(_, ref action) = params.iter().find(|&&(ref key, _)| key == "action").unwrap();
-        let (response, credentials) = match action.as_ref() {
-            "getInfo" => (self.get_info(), None),
-            "addUser" => {
-                let (response, credentials) = self.add_user(&params);
-                (response, Some(credentials))
-            }
-            _ => (not_found(), None)
-        };
-
-        request.respond(response).unwrap();
-        credentials
-    }
-
-    pub fn run(&mut self) -> Credentials {
-        let server = Server::http("0.0.0.0:8000").unwrap();
-        let _svc = DNSService::register(Some(&self.session.config().device_name),
-                                        "_spotify-connect._tcp",
-                                        None,
-                                        None,
-                                        8000,
-                                        &["VERSION=1.0", "CPath=/"]
-                                        ).unwrap();
-
-        for request in server.incoming_requests() {
-            if let Some(credentials) = self.handle_request(request) {
-                return credentials;
-            }
-        }
-
-        panic!("No credentials obtained !");
-    }
-}

+ 0 - 5
src/lib.in.rs

@@ -8,7 +8,6 @@ pub mod authentication;
 pub mod cache;
 mod connection;
 mod diffie_hellman;
-pub mod discovery;
 pub mod mercury;
 pub mod metadata;
 pub mod player;
@@ -17,9 +16,5 @@ pub mod spirc;
 pub mod link;
 pub mod stream;
 pub mod apresolve;
-mod zeroconf;
-
-#[cfg(feature = "facebook")]
-pub mod facebook;
 
 pub use album_cover::get_album_cover;

+ 0 - 1
src/lib.rs

@@ -23,7 +23,6 @@ extern crate shannon;
 extern crate rand;
 extern crate rustc_serialize;
 extern crate time;
-extern crate tiny_http;
 extern crate tempfile;
 extern crate url;
 

+ 11 - 17
src/main.rs

@@ -10,20 +10,12 @@ use std::path::PathBuf;
 use std::thread;
 
 use librespot::audio_sink::DefaultSink;
-use librespot::authentication::Credentials;
-use librespot::discovery::DiscoveryManager;
+use librespot::authentication::{Credentials, facebook_login, discovery_login};
+use librespot::cache::{Cache, DefaultCache, NoCache};
 use librespot::player::Player;
 use librespot::session::{Bitrate, Config, Session};
 use librespot::spirc::SpircManager;
 use librespot::util::version::version_string;
-use librespot::cache::{Cache, DefaultCache, NoCache};
-
-#[cfg(feature = "facebook")]
-use librespot::facebook::facebook_login;
-#[cfg(not(feature = "facebook"))]
-fn facebook_login() -> Result<Credentials, ()> {
-    Err(())
-}
 
 static PASSWORD_ENV_NAME: &'static str = "SPOTIFY_PASSWORD";
 
@@ -117,13 +109,15 @@ fn main() {
         } else {
             None
         }
-    }).or_else(|| session.cache().get_credentials())
-      .unwrap_or_else(|| {
-        println!("No username provided and no stored credentials, starting discovery ...");
-
-        let mut discovery = DiscoveryManager::new(session.clone());
-        discovery.run()
-    });
+    }).or_else(|| {
+        if cfg!(feature = "discovery") {
+            println!("No username provided and no stored credentials, starting discovery ...");
+            Some(discovery_login(&session.config().device_name,
+                                 session.device_id()).unwrap())
+        } else {
+            None
+        }
+    }).expect("No username provided and no stored credentials.");
 
     std::env::remove_var(PASSWORD_ENV_NAME);
 

+ 5 - 5
src/session.rs

@@ -42,11 +42,11 @@ pub struct Config {
 pub struct SessionData {
     country: String,
     canonical_username: String,
-    device_id: String,
 }
 
 pub struct SessionInternal {
     config: Config,
+    device_id: String,
     data: RwLock<SessionData>,
 
     cache: Box<Cache + Send + Sync>,
@@ -71,10 +71,10 @@ impl Session {
 
         Session(Arc::new(SessionInternal {
             config: config,
+            device_id: device_id,
             data: RwLock::new(SessionData {
                 country: String::new(),
                 canonical_username: String::new(),
-                device_id: device_id,
             }),
 
             rx_connection: Mutex::new(None),
@@ -190,7 +190,7 @@ impl Session {
                 cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN,
                 os: protocol::authentication::Os::OS_UNKNOWN,
                 system_information_string: "librespot".to_owned(),
-                device_id: self.device_id(),
+                device_id: self.device_id().to_owned(),
             },
             version_string: util::version::version_string(),
             appkey => {
@@ -348,7 +348,7 @@ impl Session {
         self.0.data.read().unwrap().country.clone()
     }
 
-    pub fn device_id(&self) -> String {
-        self.0.data.read().unwrap().device_id.clone()
+    pub fn device_id(&self) -> &str {
+        &self.0.device_id
     }
 }

+ 1 - 1
src/spirc.rs

@@ -46,7 +46,7 @@ struct SpircInternal {
 
 impl SpircManager {
     pub fn new(session: Session, player: Player) -> SpircManager {
-        let ident = session.device_id();
+        let ident = session.device_id().to_owned();
         let name = session.config().device_name.clone();
 
         SpircManager(Arc::new(Mutex::new(SpircInternal {

+ 0 - 30
src/zeroconf.rs

@@ -1,30 +0,0 @@
-#[cfg(feature = "dns-sd")]
-pub use dns_sd::*;
-#[cfg(not(feature = "dns-sd"))]
-pub use self::stub::*;
-
-#[cfg(not(feature = "dns-sd"))]
-pub mod stub {
-    use std;
-    use std::io::Write;
-
-    #[derive(Debug)]
-    pub struct DNSService;
-
-    pub type DNSError = ();
-
-    impl DNSService {
-        pub fn register(_: Option<&str>,
-                        _: &str,
-                        _: Option<&str>,
-                        _: Option<&str>,
-                        _: u16,
-                        _: &[&str])
-                        -> std::result::Result<DNSService, DNSError> {
-            writeln!(&mut std::io::stderr(),
-                     "WARNING: dns-sd is not enabled. Service will probably not be visible")
-                .unwrap();
-            Ok(DNSService)
-        }
-    }
-}