mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Retrieve client token (not working)
This commit is contained in:
parent
0630586cd6
commit
1528292583
4 changed files with 74 additions and 9 deletions
|
@ -5,7 +5,7 @@ use futures_util::future::IntoStream;
|
|||
use http::header::HeaderValue;
|
||||
use hyper::{
|
||||
client::ResponseFuture,
|
||||
header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE, RANGE},
|
||||
header::{ACCEPT, AUTHORIZATION, CONTENT_ENCODING, CONTENT_TYPE, RANGE},
|
||||
Body, HeaderMap, Method, Request,
|
||||
};
|
||||
use protobuf::Message;
|
||||
|
@ -17,16 +17,19 @@ use crate::{
|
|||
cdn_url::CdnUrl,
|
||||
error::ErrorKind,
|
||||
protocol::{
|
||||
canvaz::EntityCanvazRequest, connect::PutStateRequest,
|
||||
canvaz::EntityCanvazRequest,
|
||||
clienttoken_http::{ClientTokenRequest, ClientTokenRequestType, ClientTokenResponse},
|
||||
connect::PutStateRequest,
|
||||
extended_metadata::BatchedEntityRequest,
|
||||
},
|
||||
Error, FileId, SpotifyId,
|
||||
version, Error, FileId, SpotifyId,
|
||||
};
|
||||
|
||||
component! {
|
||||
SpClient : SpClientInner {
|
||||
accesspoint: Option<SocketAddress> = None,
|
||||
strategy: RequestStrategy = RequestStrategy::default(),
|
||||
client_token: String = String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +91,51 @@ impl SpClient {
|
|||
Ok(format!("https://{}:{}", ap.0, ap.1))
|
||||
}
|
||||
|
||||
pub async fn client_token(&self) -> Result<String, Error> {
|
||||
// TODO: implement expiry
|
||||
let client_token = self.lock(|inner| inner.client_token.clone());
|
||||
if !client_token.is_empty() {
|
||||
return Ok(client_token);
|
||||
}
|
||||
|
||||
let mut message = ClientTokenRequest::new();
|
||||
message.set_request_type(ClientTokenRequestType::REQUEST_CLIENT_DATA_REQUEST);
|
||||
|
||||
let client_data = message.mut_client_data();
|
||||
client_data.set_client_id(self.session().client_id());
|
||||
client_data.set_client_version(version::SEMVER.to_string());
|
||||
|
||||
let connectivity_data = client_data.mut_connectivity_sdk_data();
|
||||
connectivity_data.set_device_id(self.session().device_id().to_string());
|
||||
|
||||
let platform_data = connectivity_data.mut_platform_specific_data();
|
||||
let windows_data = platform_data.mut_windows();
|
||||
windows_data.set_os_version(10);
|
||||
windows_data.set_os_build(21370);
|
||||
windows_data.set_unknown_value_4(2);
|
||||
windows_data.set_unknown_value_6(9);
|
||||
windows_data.set_unknown_value_7(332);
|
||||
windows_data.set_unknown_value_8(34404);
|
||||
windows_data.set_unknown_value_10(true);
|
||||
|
||||
let body = protobuf::text_format::print_to_string(&message);
|
||||
|
||||
let request = Request::builder()
|
||||
.method(&Method::POST)
|
||||
.uri("https://clienttoken.spotify.com/v1/clienttoken")
|
||||
.header(ACCEPT, HeaderValue::from_static("application/x-protobuf"))
|
||||
.header(CONTENT_ENCODING, HeaderValue::from_static(""))
|
||||
.body(Body::from(body))?;
|
||||
|
||||
let response = self.session().http_client().request_body(request).await?;
|
||||
let response = ClientTokenResponse::parse_from_bytes(&response)?;
|
||||
|
||||
let client_token = response.get_granted_token().get_token().to_owned();
|
||||
self.lock(|inner| inner.client_token = client_token.clone());
|
||||
|
||||
Ok(client_token)
|
||||
}
|
||||
|
||||
pub async fn request_with_protobuf(
|
||||
&self,
|
||||
method: &Method,
|
||||
|
@ -100,7 +148,7 @@ impl SpClient {
|
|||
let mut headers = headers.unwrap_or_else(HeaderMap::new);
|
||||
headers.insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_static("application/protobuf"),
|
||||
HeaderValue::from_static("application/x-protobuf"),
|
||||
);
|
||||
|
||||
self.request(method, endpoint, Some(headers), Some(body))
|
||||
|
@ -132,6 +180,9 @@ impl SpClient {
|
|||
|
||||
let body = body.unwrap_or_else(String::new);
|
||||
|
||||
let client_token = self.client_token().await;
|
||||
trace!("CLIENT TOKEN: {:?}", client_token);
|
||||
|
||||
loop {
|
||||
tries += 1;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ fn compile() {
|
|||
|
||||
let files = &[
|
||||
proto_dir.join("connect.proto"),
|
||||
proto_dir.join("connectivity.proto"),
|
||||
proto_dir.join("devices.proto"),
|
||||
proto_dir.join("entity_extension_data.proto"),
|
||||
proto_dir.join("extended_metadata.proto"),
|
||||
|
@ -26,6 +27,7 @@ fn compile() {
|
|||
proto_dir.join("playlist_annotate3.proto"),
|
||||
proto_dir.join("playlist_permission.proto"),
|
||||
proto_dir.join("playlist4_external.proto"),
|
||||
proto_dir.join("spotify/clienttoken/v0/clienttoken_http.proto"),
|
||||
proto_dir.join("storage-resolve.proto"),
|
||||
proto_dir.join("user_attributes.proto"),
|
||||
// TODO: remove these legacy protobufs when we are on the new API completely
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// Extracted from: Spotify 1.1.33.569 (Windows)
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package spotify.clienttoken.data.v0;
|
||||
|
@ -17,6 +15,7 @@ message PlatformSpecificData {
|
|||
oneof data {
|
||||
NativeAndroidData android = 1;
|
||||
NativeIOSData ios = 2;
|
||||
NativeWindowsData windows = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +35,16 @@ message NativeIOSData {
|
|||
string simulator_model_identifier = 5;
|
||||
}
|
||||
|
||||
message NativeWindowsData {
|
||||
int32 os_version = 1;
|
||||
int32 os_build = 3;
|
||||
int32 unknown_value_4 = 4;
|
||||
int32 unknown_value_6 = 6;
|
||||
int32 unknown_value_7 = 7;
|
||||
int32 unknown_value_8 = 8;
|
||||
bool unknown_value_10 = 10;
|
||||
}
|
||||
|
||||
message Screen {
|
||||
int32 width = 1;
|
||||
int32 height = 2;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// Extracted from: Spotify 1.1.33.569 (Windows)
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package spotify.clienttoken.http.v0;
|
||||
|
@ -24,7 +22,7 @@ message ClientDataRequest {
|
|||
string client_id = 2;
|
||||
|
||||
oneof data {
|
||||
data.v0.ConnectivitySdkData connectivity_sdk_data = 3;
|
||||
spotify.clienttoken.data.v0.ConnectivitySdkData connectivity_sdk_data = 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,10 +40,15 @@ message ClientTokenResponse {
|
|||
}
|
||||
}
|
||||
|
||||
message TokenDomain {
|
||||
string domain = 1;
|
||||
}
|
||||
|
||||
message GrantedTokenResponse {
|
||||
string token = 1;
|
||||
int32 expires_after_seconds = 2;
|
||||
int32 refresh_after_seconds = 3;
|
||||
repeated TokenDomain domains = 4;
|
||||
}
|
||||
|
||||
message ChallengesResponse {
|
||||
|
|
Loading…
Reference in a new issue