Skip to content

Commit a03b16c

Browse files
committed
Better version of Zeroconf connection check (#225 , #229, #231)
1 parent 6cb5960 commit a03b16c

1 file changed

Lines changed: 28 additions & 4 deletions

File tree

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

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ public class ZeroconfServer implements Closeable {
9494
private final DiffieHellman keys;
9595
private final List<SessionListener> sessionListeners;
9696
private final Zeroconf zeroconf;
97+
private final Object connectionLock = new Object();
9798
private volatile Session session;
99+
private String connectingUsername = null;
98100

99101
private ZeroconfServer(Session.Inner inner, Configuration conf) throws IOException {
100102
this.inner = inner;
@@ -230,14 +232,17 @@ private boolean hasValidSession() {
230232
}
231233
}
232234

233-
private synchronized void handleGetInfo(OutputStream out, String httpVersion) throws IOException {
235+
private void handleGetInfo(OutputStream out, String httpVersion) throws IOException {
234236
JsonObject info = DEFAULT_GET_INFO_FIELDS.deepCopy();
235-
info.addProperty("activeUser", hasValidSession() ? session.username() : "");
236237
info.addProperty("deviceID", inner.deviceId);
237238
info.addProperty("remoteName", inner.deviceName);
238239
info.addProperty("publicKey", Base64.getEncoder().encodeToString(keys.publicKeyArray()));
239240
info.addProperty("deviceType", inner.deviceType.name().toUpperCase());
240241

242+
synchronized (connectionLock) {
243+
info.addProperty("activeUser", connectingUsername != null ? connectingUsername : (hasValidSession() ? session.username() : ""));
244+
}
245+
241246
out.write(httpVersion.getBytes());
242247
out.write(" 200 OK".getBytes());
243248
out.write(EOL);
@@ -252,7 +257,7 @@ private synchronized void handleGetInfo(OutputStream out, String httpVersion) th
252257
out.flush();
253258
}
254259

255-
private synchronized void handleAddUser(OutputStream out, Map<String, String> params, String httpVersion) throws GeneralSecurityException, IOException {
260+
private void handleAddUser(OutputStream out, Map<String, String> params, String httpVersion) throws GeneralSecurityException, IOException {
256261
String username = params.get("userName");
257262
if (username == null || username.isEmpty()) {
258263
LOGGER.fatal("Missing userName!");
@@ -271,6 +276,13 @@ private synchronized void handleAddUser(OutputStream out, Map<String, String> pa
271276
return;
272277
}
273278

279+
synchronized (connectionLock) {
280+
if (username.equals(connectingUsername)) {
281+
LOGGER.info("{} is already trying to connect.", username);
282+
return;
283+
}
284+
}
285+
274286
byte[] sharedKey = Utils.toByteArray(keys.computeSharedKey(Base64.getDecoder().decode(clientKeyStr)));
275287
byte[] blobBytes = Base64.getDecoder().decode(blobStr);
276288
byte[] iv = Arrays.copyOfRange(blobBytes, 0, 16);
@@ -306,6 +318,10 @@ private synchronized void handleAddUser(OutputStream out, Map<String, String> pa
306318
byte[] decrypted = aes.doFinal(encrypted);
307319

308320
try {
321+
synchronized (connectionLock) {
322+
connectingUsername = username;
323+
}
324+
309325
Authentication.LoginCredentials credentials = inner.decryptBlob(username, decrypted);
310326

311327
session = Session.from(inner);
@@ -314,7 +330,9 @@ private synchronized void handleAddUser(OutputStream out, Map<String, String> pa
314330
session.connect();
315331
session.authenticate(credentials);
316332

317-
sessionListeners.forEach(l -> l.sessionChanged(session));
333+
synchronized (connectionLock) {
334+
connectingUsername = null;
335+
}
318336

319337
// Sending response
320338
String resp = DEFAULT_SUCCESSFUL_ADD_USER.toString();
@@ -329,9 +347,15 @@ private synchronized void handleAddUser(OutputStream out, Map<String, String> pa
329347
out.write(EOL);
330348
out.write(resp.getBytes());
331349
out.flush();
350+
351+
sessionListeners.forEach(l -> l.sessionChanged(session));
332352
} catch (Session.SpotifyAuthenticationException | MercuryClient.MercuryException ex) {
333353
LOGGER.fatal("Couldn't establish a new session.", ex);
334354

355+
synchronized (connectionLock) {
356+
connectingUsername = null;
357+
}
358+
335359
out.write(httpVersion.getBytes());
336360
out.write(" 500 Internal Server Error".getBytes()); // I don't think this is the Spotify way
337361
out.write(EOL);

0 commit comments

Comments
 (0)