diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 77785e3c..cb196ec3 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -14,10 +14,12 @@ use crate::playback::mixer::Mixer; use crate::playback::player::{Player, PlayerEvent, PlayerEventChannel}; use crate::protocol; use crate::protocol::spirc::{DeviceState, Frame, MessageType, PlayStatus, State, TrackRef}; + use librespot_core::config::ConnectConfig; use librespot_core::mercury::MercuryError; use librespot_core::session::Session; use librespot_core::spotify_id::{SpotifyAudioType, SpotifyId, SpotifyIdError}; +use librespot_core::util::url_encode; use librespot_core::util::SeqGenerator; use librespot_core::version; use librespot_core::volume::Volume; @@ -249,7 +251,8 @@ impl Spirc { let ident = session.device_id().to_owned(); // Uri updated in response to issue #288 - let uri = format!("hm://remote/user/{}/", session.username()); + debug!("canonical_username: {}", url_encode(&session.username())); + let uri = format!("hm://remote/user/{}/", url_encode(&session.username())); let subscription = session.mercury().subscribe(&uri as &str); let subscription = subscription @@ -919,7 +922,7 @@ impl SpircTask { if (context_uri.starts_with("spotify:station:") || context_uri.starts_with("spotify:dailymix:") // spotify:user:xxx:collection - || context_uri.starts_with(&format!("spotify:user:{}:collection",self.session.username()))) + || context_uri.starts_with(&format!("spotify:user:{}:collection",url_encode(&self.session.username())))) && ((self.state.get_track().len() as u32) - new_index) < CONTEXT_FETCH_THRESHOLD { self.context_fut = self.resolve_station(&context_uri); diff --git a/core/src/mercury/mod.rs b/core/src/mercury/mod.rs index e167f9c9..20e3f0db 100644 --- a/core/src/mercury/mod.rs +++ b/core/src/mercury/mod.rs @@ -1,4 +1,5 @@ use crate::protocol; +use crate::util::url_encode; use byteorder::{BigEndian, ByteOrder}; use bytes::Bytes; use futures::sync::{mpsc, oneshot}; @@ -192,7 +193,7 @@ impl MercuryManager { let header: protocol::mercury::Header = protobuf::parse_from_bytes(&header_data).unwrap(); let response = MercuryResponse { - uri: header.get_uri().to_owned(), + uri: url_encode(header.get_uri()).to_owned(), status_code: header.get_status_code(), payload: pending.parts, }; diff --git a/core/src/util/mod.rs b/core/src/util/mod.rs index 800e04e1..c55d9601 100644 --- a/core/src/util/mod.rs +++ b/core/src/util/mod.rs @@ -12,6 +12,21 @@ pub fn rand_vec(rng: &mut G, size: usize) -> Vec { .collect() } +pub fn url_encode(inp: &str) -> String { + let mut encoded = String::new(); + + for c in inp.as_bytes().iter() { + match *c as char { + 'A'..='Z' | 'a'..='z' | '0'..='9' | '-' | '_' | '.' | '~' | ':' | '/' => { + encoded.push(*c as char) + } + c => encoded.push_str(format!("%{:02X}", c as u32).as_str()), + }; + } + + encoded +} + pub fn powm(base: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint { let mut base = base.clone(); let mut exp = exp.clone();