Skip to content

Commit 5839d5b

Browse files
committed
Added logout feature + close old session in Zeroconf + send response for errors
1 parent 5d709e2 commit 5839d5b

2 files changed

Lines changed: 40 additions & 10 deletions

File tree

core/src/main/java/xyz/gianlu/librespot/core/Session.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
/**
6161
* @author Gianlu
6262
*/
63-
public final class Session implements Closeable, SubListener {
63+
public final class Session implements Closeable, SubListener, DealerClient.MessageListener {
6464
private static final Logger LOGGER = LogManager.getLogger(Session.class);
6565
private static final byte[] serverKey = new byte[]{
6666
(byte) 0xac, (byte) 0xe0, (byte) 0x46, (byte) 0x0b, (byte) 0xff, (byte) 0xc2, (byte) 0x30, (byte) 0xaf, (byte) 0xf4, (byte) 0x6b, (byte) 0xfe, (byte) 0xc3,
@@ -354,7 +354,8 @@ void authenticate(@NotNull Authentication.LoginCredentials credentials) throws I
354354
dealer.connect();
355355

356356
LOGGER.info("Authenticated as {}!", apWelcome.getCanonicalUsername());
357-
mercuryClient.interestedIn("spotify:user:attributes:update", this);
357+
mercury().interestedIn("spotify:user:attributes:update", this);
358+
dealer().addMessageListener(this, "hm://connect-state/v1/connect/logout");
358359
}
359360

360361
/**
@@ -780,6 +781,17 @@ public void event(@NotNull MercuryClient.Response resp) {
780781
}
781782
}
782783

784+
@Override
785+
public void onMessage(@NotNull String uri, @NotNull Map<String, String> headers, @NotNull byte[] payload) throws IOException {
786+
if (uri.equals("hm://connect-state/v1/connect/logout")) {
787+
try {
788+
close();
789+
} catch (IOException ex) {
790+
LOGGER.error("Failed closing session due to logout.", ex);
791+
}
792+
}
793+
}
794+
783795
public interface ReconnectionListener {
784796
void onConnectionDropped();
785797

core/src/main/java/xyz/gianlu/librespot/core/ZeroconfServer.java

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ public void close() throws IOException {
217217

218218
public void closeSession() throws IOException {
219219
if (session != null) session.close();
220-
221220
session = null;
222221
}
223222

@@ -279,6 +278,12 @@ private void handleAddUser(OutputStream out, Map<String, String> params, String
279278
synchronized (connectionLock) {
280279
if (username.equals(connectingUsername)) {
281280
LOGGER.info("{} is already trying to connect.", username);
281+
282+
out.write(httpVersion.getBytes());
283+
out.write(" 403 Forbidden".getBytes()); // I don't think this is the Spotify way
284+
out.write(EOL);
285+
out.write(EOL);
286+
out.flush();
282287
return;
283288
}
284289
}
@@ -310,13 +315,25 @@ private void handleAddUser(OutputStream out, Map<String, String> params, String
310315

311316
if (!Arrays.equals(mac, checksum)) {
312317
LOGGER.fatal("Mac and checksum don't match!");
318+
319+
out.write(httpVersion.getBytes());
320+
out.write(" 400 Bad Request".getBytes()); // I don't think this is the Spotify way
321+
out.write(EOL);
322+
out.write(EOL);
323+
out.flush();
313324
return;
314325
}
315326

316327
Cipher aes = Cipher.getInstance("AES/CTR/NoPadding");
317328
aes.init(Cipher.DECRYPT_MODE, new SecretKeySpec(Arrays.copyOfRange(encryptionKey, 0, 16), "AES"), new IvParameterSpec(iv));
318329
byte[] decrypted = aes.doFinal(encrypted);
319330

331+
try {
332+
closeSession();
333+
} catch (IOException ex) {
334+
LOGGER.warn("Failed closing previous session.", ex);
335+
}
336+
320337
try {
321338
synchronized (connectionLock) {
322339
connectingUsername = username;
@@ -327,13 +344,6 @@ private void handleAddUser(OutputStream out, Map<String, String> params, String
327344
session = Session.from(inner);
328345
LOGGER.info("Accepted new user from {}. {deviceId: {}}", params.get("deviceName"), session.deviceId());
329346

330-
session.connect();
331-
session.authenticate(credentials);
332-
333-
synchronized (connectionLock) {
334-
connectingUsername = null;
335-
}
336-
337347
// Sending response
338348
String resp = DEFAULT_SUCCESSFUL_ADD_USER.toString();
339349
out.write(httpVersion.getBytes());
@@ -348,6 +358,14 @@ private void handleAddUser(OutputStream out, Map<String, String> params, String
348358
out.write(resp.getBytes());
349359
out.flush();
350360

361+
362+
session.connect();
363+
session.authenticate(credentials);
364+
365+
synchronized (connectionLock) {
366+
connectingUsername = null;
367+
}
368+
351369
sessionListeners.forEach(l -> l.sessionChanged(session));
352370
} catch (Session.SpotifyAuthenticationException | MercuryClient.MercuryException ex) {
353371
LOGGER.fatal("Couldn't establish a new session.", ex);

0 commit comments

Comments
 (0)