Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions api/src/main/java/xyz/gianlu/librespot/api/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.jetbrains.annotations.NotNull;
import xyz.gianlu.librespot.common.Log4JUncaughtExceptionHandler;
import xyz.gianlu.librespot.core.Session;
import xyz.gianlu.librespot.mercury.MercuryClient;
import xyz.gianlu.librespot.core.TokenProvider;
import xyz.gianlu.librespot.player.FileConfiguration;
import xyz.gianlu.librespot.player.FileConfiguration.AuthStrategy;

Expand All @@ -33,7 +33,7 @@
*/
public class Main {

public static void main(String[] args) throws IOException, MercuryClient.MercuryException, GeneralSecurityException, Session.SpotifyAuthenticationException {
public static void main(String[] args) throws IOException, TokenProvider.TokenException, GeneralSecurityException, Session.SpotifyAuthenticationException {
FileConfiguration conf = new FileConfiguration(args);
Configurator.setRootLevel(conf.loggingLevel());
Thread.setDefaultUncaughtExceptionHandler(new Log4JUncaughtExceptionHandler());
Expand All @@ -45,7 +45,7 @@ public static void main(String[] args) throws IOException, MercuryClient.Mercury
else withPlayer(port, host, conf);
}

private static void withPlayer(int port, @NotNull String host, @NotNull FileConfiguration conf) throws IOException, MercuryClient.MercuryException, GeneralSecurityException, Session.SpotifyAuthenticationException {
private static void withPlayer(int port, @NotNull String host, @NotNull FileConfiguration conf) throws IOException, TokenProvider.TokenException, GeneralSecurityException, Session.SpotifyAuthenticationException {
PlayerWrapper wrapper;
if (conf.authStrategy() == AuthStrategy.ZEROCONF)
wrapper = PlayerWrapper.fromZeroconf(conf.initZeroconfBuilder().create(), conf.toPlayer(), conf.toEventsShell());
Expand All @@ -57,7 +57,7 @@ private static void withPlayer(int port, @NotNull String host, @NotNull FileConf
server.start();
}

private static void withoutPlayer(int port, @NotNull String host, @NotNull FileConfiguration conf) throws IOException, MercuryClient.MercuryException, GeneralSecurityException, Session.SpotifyAuthenticationException {
private static void withoutPlayer(int port, @NotNull String host, @NotNull FileConfiguration conf) throws IOException, TokenProvider.TokenException, GeneralSecurityException, Session.SpotifyAuthenticationException {
SessionWrapper wrapper;
if (conf.authStrategy() == AuthStrategy.ZEROCONF)
wrapper = SessionWrapper.fromZeroconf(conf.initZeroconfBuilder().create(), conf.toEventsShell());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import xyz.gianlu.librespot.api.Utils;
import xyz.gianlu.librespot.common.ProtobufToJson;
import xyz.gianlu.librespot.core.Session;
import xyz.gianlu.librespot.core.TokenProvider;
import xyz.gianlu.librespot.dealer.ApiClient;
import xyz.gianlu.librespot.mercury.MercuryClient;
import xyz.gianlu.librespot.metadata.*;

import java.io.IOException;
Expand Down Expand Up @@ -91,7 +91,7 @@ public void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Session

Utils.internalError(exchange, ex);
LOGGER.error("Failed handling api request. {type: {}, uri: {}, code: {}}", type, uri, ex.code, ex);
} catch (IOException | MercuryClient.MercuryException ex) {
} catch (IOException | TokenProvider.TokenException ex) {
Utils.internalError(exchange, ex);
LOGGER.error("Failed handling api request. {type: {}, uri: {}}", type, uri, ex);
} catch (IllegalArgumentException ex) {
Expand All @@ -100,7 +100,7 @@ public void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Session
}

@NotNull
private JsonObject handle(@NotNull Session session, @NotNull MetadataType type, @NotNull String uri) throws IOException, MercuryClient.MercuryException, IllegalArgumentException {
private JsonObject handle(@NotNull Session session, @NotNull MetadataType type, @NotNull String uri) throws IOException, TokenProvider.TokenException, IllegalArgumentException {
switch (type) {
case ALBUM:
return ProtobufToJson.convert(session.api().getMetadata4Album(AlbumId.fromUri(uri)));
Expand All @@ -120,7 +120,7 @@ private JsonObject handle(@NotNull Session session, @NotNull MetadataType type,
}

@NotNull
private JsonObject handlePlaylist(@NotNull Session session, @NotNull String uri) throws IOException, MercuryClient.MercuryException {
private JsonObject handlePlaylist(@NotNull Session session, @NotNull String uri) throws IOException, TokenProvider.TokenException {
return ProtobufToJson.convert(session.api().getPlaylist(PlaylistId.fromUri(uri)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@
import io.undertow.server.HttpServerExchange;
import org.jetbrains.annotations.NotNull;
import xyz.gianlu.librespot.api.SessionWrapper;
import xyz.gianlu.librespot.api.Utils;
import xyz.gianlu.librespot.core.Session;
import xyz.gianlu.librespot.core.TokenProvider;

import java.util.Deque;
import java.util.Map;

public final class TokensHandler extends AbsSessionHandler {

public TokensHandler(@NotNull SessionWrapper wrapper) {
Expand All @@ -41,14 +37,7 @@ protected void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Sess
return;
}

Map<String, Deque<String>> params = Utils.readParameters(exchange);
String scope = Utils.getFirstString(params, "scope");
if (scope == null) {
Utils.invalidParameter(exchange, "scope");
return;
}

TokenProvider.StoredToken token = session.tokens().getToken(scope);
TokenProvider.StoredToken token = session.tokens().getToken();
JsonObject obj = new JsonObject();
obj.addProperty("token", token.accessToken);
obj.addProperty("timestamp", token.timestamp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import xyz.gianlu.librespot.core.TokenProvider;

public final class WebApiHandler extends AbsSessionHandler {
private static final String[] API_TOKENS_ALL = new String[]{"ugc-image-upload", "playlist-read-collaborative", "playlist-modify-private", "playlist-modify-public", "playlist-read-private", "user-read-playback-position", "user-read-recently-played", "user-top-read", "user-modify-playback-state", "user-read-currently-playing", "user-read-playback-state", "user-read-private", "user-read-email", "user-library-modify", "user-library-read", "user-follow-modify", "user-follow-read", "streaming", "app-remote-control"};
private static final HttpUrl BASE_API_URL = HttpUrl.get("https://api.spotify.com");
private static final HttpString HEADER_X_SCOPE = HttpString.tryFromString("X-Spotify-Scope");

Expand All @@ -47,11 +46,7 @@ protected void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Sess
String body = FileUtils.readFile(exchange.getInputStream());
HeaderValues contentType = exchange.getRequestHeaders().get(Headers.CONTENT_TYPE);

String[] scopes = API_TOKENS_ALL;
if (exchange.getRequestHeaders().contains(HEADER_X_SCOPE))
scopes = exchange.getRequestHeaders().get(HEADER_X_SCOPE).toArray(new String[0]);

TokenProvider.StoredToken token = session.tokens().getToken(scopes);
TokenProvider.StoredToken token = session.tokens().getToken();

HttpUrl.Builder url = BASE_API_URL.newBuilder()
.addPathSegments(exchange.getRelativePath().substring(1))
Expand Down
4 changes: 2 additions & 2 deletions lib/src/main/java/xyz/gianlu/librespot/ZeroconfServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import xyz.gianlu.librespot.common.NameThreadFactory;
import xyz.gianlu.librespot.common.Utils;
import xyz.gianlu.librespot.core.Session;
import xyz.gianlu.librespot.core.TokenProvider;
import xyz.gianlu.librespot.crypto.DiffieHellman;
import xyz.gianlu.librespot.mercury.MercuryClient;
import xyz.gianlu.zeroconf.Service;
import xyz.gianlu.zeroconf.Zeroconf;

Expand Down Expand Up @@ -371,7 +371,7 @@ private void handleAddUser(OutputStream out, Map<String, String> params, String
}

sessionListeners.forEach(l -> l.sessionChanged(session));
} catch (Session.SpotifyAuthenticationException | MercuryClient.MercuryException | IOException | GeneralSecurityException ex) {
} catch (Session.SpotifyAuthenticationException | TokenProvider.TokenException | IOException | GeneralSecurityException ex) {
LOGGER.error("Couldn't establish a new session.", ex);

synchronized (connectionLock) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import xyz.gianlu.librespot.common.NameThreadFactory;
import xyz.gianlu.librespot.common.Utils;
import xyz.gianlu.librespot.core.Session;
import xyz.gianlu.librespot.mercury.MercuryClient;
import xyz.gianlu.librespot.core.TokenProvider;
import xyz.gianlu.librespot.metadata.EpisodeId;
import xyz.gianlu.librespot.metadata.LocalId;
import xyz.gianlu.librespot.metadata.PlayableId;
Expand Down Expand Up @@ -81,7 +81,7 @@ private static Metadata.Track pickAlternativeIfNecessary(@NotNull Metadata.Track
}

@NotNull
public final LoadedStream load(@NotNull PlayableId id, @NotNull AudioQualityPicker audioQualityPicker, boolean preload, @Nullable HaltListener haltListener) throws CdnManager.CdnException, ContentRestrictedException, MercuryClient.MercuryException, IOException {
public final LoadedStream load(@NotNull PlayableId id, @NotNull AudioQualityPicker audioQualityPicker, boolean preload, @Nullable HaltListener haltListener) throws CdnManager.CdnException, ContentRestrictedException, TokenProvider.TokenException, IOException {
if (id instanceof TrackId)
return loadTrack((TrackId) id, audioQualityPicker, preload, haltListener);
else if (id instanceof EpisodeId)
Expand All @@ -91,7 +91,7 @@ else if (id instanceof EpisodeId)
}

@NotNull
private StorageResolveResponse resolveStorageInteractive(@NotNull ByteString fileId, boolean preload) throws IOException, MercuryClient.MercuryException {
private StorageResolveResponse resolveStorageInteractive(@NotNull ByteString fileId, boolean preload) throws IOException, TokenProvider.TokenException {
try (Response resp = session.api().send("GET", String.format(preload ? STORAGE_RESOLVE_INTERACTIVE_PREFETCH : STORAGE_RESOLVE_INTERACTIVE, Utils.bytesToHex(fileId)), null, null)) {
if (resp.code() != 200) throw new IOException(resp.code() + ": " + resp.message());

Expand All @@ -102,7 +102,7 @@ private StorageResolveResponse resolveStorageInteractive(@NotNull ByteString fil
}
}

private @NotNull LoadedStream loadTrack(@NotNull TrackId id, @NotNull AudioQualityPicker audioQualityPicker, boolean preload, @Nullable HaltListener haltListener) throws IOException, MercuryClient.MercuryException, ContentRestrictedException, CdnManager.CdnException {
private @NotNull LoadedStream loadTrack(@NotNull TrackId id, @NotNull AudioQualityPicker audioQualityPicker, boolean preload, @Nullable HaltListener haltListener) throws IOException, TokenProvider.TokenException, ContentRestrictedException, CdnManager.CdnException {
Metadata.Track original = session.api().getMetadata4Track(id);
Metadata.Track track = pickAlternativeIfNecessary(original);
if (track == null) {
Expand All @@ -129,7 +129,7 @@ private LoadedStream loadCdnStream(@NotNull Metadata.AudioFile file, @Nullable M

@NotNull
@Contract("_, null, null, _, _ -> fail")
private LoadedStream loadStream(@NotNull Metadata.AudioFile file, @Nullable Metadata.Track track, @Nullable Metadata.Episode episode, boolean preload, @Nullable HaltListener haltListener) throws IOException, MercuryClient.MercuryException, CdnManager.CdnException {
private LoadedStream loadStream(@NotNull Metadata.AudioFile file, @Nullable Metadata.Track track, @Nullable Metadata.Episode episode, boolean preload, @Nullable HaltListener haltListener) throws IOException, TokenProvider.TokenException, CdnManager.CdnException {
if (track == null && episode == null)
throw new IllegalStateException();

Expand All @@ -156,7 +156,7 @@ private LoadedStream loadStream(@NotNull Metadata.AudioFile file, @Nullable Meta
}

@NotNull
private LoadedStream loadTrack(@NotNull Metadata.Track track, @NotNull AudioQualityPicker audioQualityPicker, boolean preload, @Nullable HaltListener haltListener) throws IOException, CdnManager.CdnException, MercuryClient.MercuryException {
private LoadedStream loadTrack(@NotNull Metadata.Track track, @NotNull AudioQualityPicker audioQualityPicker, boolean preload, @Nullable HaltListener haltListener) throws IOException, CdnManager.CdnException, TokenProvider.TokenException {
Metadata.AudioFile file = audioQualityPicker.getFile(track.getFileList());
if (file == null) {
LOGGER.error("Couldn't find any suitable audio file, available: {}", Utils.formatsToString(track.getFileList()));
Expand All @@ -167,7 +167,7 @@ private LoadedStream loadTrack(@NotNull Metadata.Track track, @NotNull AudioQual
}

@NotNull
private LoadedStream loadEpisode(@NotNull EpisodeId id, @NotNull AudioQualityPicker audioQualityPicker, boolean preload, @Nullable HaltListener haltListener) throws IOException, MercuryClient.MercuryException, CdnManager.CdnException {
private LoadedStream loadEpisode(@NotNull EpisodeId id, @NotNull AudioQualityPicker audioQualityPicker, boolean preload, @Nullable HaltListener haltListener) throws IOException, TokenProvider.TokenException, CdnManager.CdnException {
Metadata.Episode episode = session.api().getMetadata4Episode(id);

if (episode.hasExternalUrl()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import xyz.gianlu.librespot.common.NameThreadFactory;
import xyz.gianlu.librespot.common.Utils;
import xyz.gianlu.librespot.core.Session;
import xyz.gianlu.librespot.mercury.MercuryClient;
import xyz.gianlu.librespot.core.TokenProvider;

import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -88,7 +88,7 @@ public Streamer streamFile(@NotNull Metadata.AudioFile file, @NotNull byte[] key
* This is used only to RENEW the url if needed.
*/
@NotNull
private HttpUrl getAudioUrl(@NotNull ByteString fileId) throws IOException, CdnException, MercuryClient.MercuryException {
private HttpUrl getAudioUrl(@NotNull ByteString fileId) throws IOException, CdnException, TokenProvider.TokenException {
try (Response resp = session.api().send("GET", String.format("/storage-resolve/files/audio/interactive/%s", Utils.bytesToHex(fileId)), null, null)) {
if (resp.code() != 200)
throw new IOException(resp.code() + ": " + resp.message());
Expand Down Expand Up @@ -145,7 +145,7 @@ HttpUrl url() throws CdnException {
if (expiration <= System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5)) {
try {
url = getAudioUrl(fileId);
} catch (IOException | MercuryClient.MercuryException ex) {
} catch (IOException | TokenProvider.TokenException ex) {
throw new CdnException(ex);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down
5 changes: 4 additions & 1 deletion lib/src/main/java/xyz/gianlu/librespot/core/OAuth.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
Expand Down
6 changes: 3 additions & 3 deletions lib/src/main/java/xyz/gianlu/librespot/core/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import com.spotify.connectstate.Connect;
import com.spotify.explicit.ExplicitContentPubsub;
import com.spotify.explicit.ExplicitContentPubsub.UserAttributesUpdate;
import okhttp3.Authenticator;
import okhttp3.*;
import okhttp3.Authenticator;
import okio.BufferedSink;
import okio.GzipSink;
import okio.Okio;
Expand Down Expand Up @@ -340,7 +340,7 @@ private void connect() throws IOException, GeneralSecurityException, SpotifyAuth
* Authenticates with the server and creates all the necessary components.
* All of them should be initialized inside the synchronized block and MUST NOT call any method on this {@link Session} object.
*/
private void authenticate(@NotNull Authentication.LoginCredentials credentials) throws IOException, GeneralSecurityException, SpotifyAuthenticationException, MercuryClient.MercuryException {
private void authenticate(@NotNull Authentication.LoginCredentials credentials) throws IOException, GeneralSecurityException, SpotifyAuthenticationException, TokenProvider.TokenException {
authenticatePartial(credentials, false);

if (credentials.getTyp() == Authentication.AuthenticationType.AUTHENTICATION_SPOTIFY_TOKEN)
Expand Down Expand Up @@ -1069,7 +1069,7 @@ public Builder userPass(@NotNull String username, @NotNull String password) {
* Creates a connected and fully authenticated {@link Session} object.
*/
@NotNull
public Session create() throws IOException, GeneralSecurityException, SpotifyAuthenticationException, MercuryClient.MercuryException {
public Session create() throws IOException, GeneralSecurityException, SpotifyAuthenticationException, TokenProvider.TokenException {
if (loginCredentials == null)
throw new IllegalStateException("You must select an authentication method.");

Expand Down
5 changes: 2 additions & 3 deletions lib/src/main/java/xyz/gianlu/librespot/core/TimeProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import xyz.gianlu.librespot.mercury.MercuryClient;

import java.io.IOException;
import java.net.InetAddress;
Expand Down Expand Up @@ -101,7 +100,7 @@ private static void updateMelody(@NotNull Session session) {
LOGGER.error("Failed notifying server of time request! {code: {}, msg: {}}", resp.code(), resp.message());
return;
}
} catch (IOException | MercuryClient.MercuryException ex) {
} catch (IOException | TokenProvider.TokenException ex) {
LOGGER.error("Failed notifying server of time request!", ex);
return;
}
Expand All @@ -122,7 +121,7 @@ private static void updateMelody(@NotNull Session session) {
}

LOGGER.info("Loaded time offset from melody: {}ms", diff);
} catch (IOException | MercuryClient.MercuryException ex) {
} catch (IOException | TokenProvider.TokenException ex) {
LOGGER.error("Failed requesting time!", ex);
}
}
Expand Down
Loading