Skip to content

Commit 9d17a72

Browse files
authored
Merge pull request #441 from Iscle/apresolver-proxy
Make ApResolver use the proxy (if there's one configured)
2 parents e709421 + d240c5a commit 9d17a72

4 files changed

Lines changed: 59 additions & 46 deletions

File tree

lib/src/main/java/xyz/gianlu/librespot/core/ApResolver.java

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@
2020
import com.google.gson.JsonElement;
2121
import com.google.gson.JsonObject;
2222
import com.google.gson.JsonParser;
23+
import okhttp3.OkHttpClient;
24+
import okhttp3.Request;
25+
import okhttp3.Response;
26+
import okhttp3.ResponseBody;
2327
import org.jetbrains.annotations.NotNull;
2428
import org.slf4j.Logger;
2529
import org.slf4j.LoggerFactory;
2630

2731
import java.io.IOException;
28-
import java.io.InputStreamReader;
2932
import java.io.Reader;
30-
import java.net.HttpURLConnection;
31-
import java.net.URL;
3233
import java.util.ArrayList;
3334
import java.util.HashMap;
3435
import java.util.List;
@@ -40,18 +41,25 @@
4041
*/
4142
public final class ApResolver {
4243
private static final String BASE_URL = "http://apresolve.spotify.com/";
43-
private static final Map<String, List<String>> pool = new HashMap<>(3);
4444
private static final Logger LOGGER = LoggerFactory.getLogger(ApResolver.class);
45-
private static volatile boolean poolReady = false;
4645

47-
public static void fillPool() throws IOException {
48-
if (!poolReady) request("accesspoint", "dealer", "spclient");
46+
private final OkHttpClient client;
47+
private final Map<String, List<String>> pool = new HashMap<>(3);
48+
private volatile boolean poolReady = false;
49+
50+
public ApResolver(OkHttpClient client) throws IOException {
51+
this.client = client;
52+
fillPool();
53+
}
54+
55+
private void fillPool() throws IOException {
56+
request("accesspoint", "dealer", "spclient");
4957
}
5058

51-
public static void refreshPool() throws IOException {
59+
public void refreshPool() throws IOException {
5260
poolReady = false;
5361
pool.clear();
54-
request("accesspoint", "dealer", "spclient");
62+
fillPool();
5563
}
5664

5765
@NotNull
@@ -62,8 +70,7 @@ private static List<String> getUrls(@NotNull JsonObject body, @NotNull String ty
6270
return list;
6371
}
6472

65-
@NotNull
66-
private static Map<String, List<String>> request(@NotNull String... types) throws IOException {
73+
private void request(@NotNull String... types) throws IOException {
6774
if (types.length == 0) throw new IllegalArgumentException();
6875

6976
StringBuilder url = new StringBuilder(BASE_URL + "?");
@@ -72,30 +79,30 @@ private static Map<String, List<String>> request(@NotNull String... types) throw
7279
url.append("type=").append(types[i]);
7380
}
7481

75-
HttpURLConnection conn = (HttpURLConnection) new URL(url.toString()).openConnection();
76-
conn.connect();
77-
78-
try (Reader reader = new InputStreamReader(conn.getInputStream())) {
79-
JsonObject obj = JsonParser.parseReader(reader).getAsJsonObject();
80-
HashMap<String, List<String>> map = new HashMap<>();
81-
for (String type : types)
82-
map.put(type, getUrls(obj, type));
82+
Request request = new Request.Builder()
83+
.url(url.toString())
84+
.build();
85+
try (Response response = client.newCall(request).execute()) {
86+
ResponseBody body = response.body();
87+
if (body == null) throw new IOException("No body");
88+
try (Reader reader = body.charStream()) {
89+
JsonObject obj = JsonParser.parseReader(reader).getAsJsonObject();
90+
HashMap<String, List<String>> map = new HashMap<>();
91+
for (String type : types)
92+
map.put(type, getUrls(obj, type));
93+
94+
synchronized (pool) {
95+
pool.putAll(map);
96+
poolReady = true;
97+
pool.notifyAll();
98+
}
8399

84-
synchronized (pool) {
85-
pool.putAll(map);
86-
poolReady = true;
87-
pool.notifyAll();
100+
LOGGER.info("Loaded aps into pool: " + pool);
88101
}
89-
90-
LOGGER.info("Loaded aps into pool: " + pool);
91-
92-
return map;
93-
} finally {
94-
conn.disconnect();
95102
}
96103
}
97104

98-
private static void waitForPool() {
105+
private void waitForPool() {
99106
if (!poolReady) {
100107
synchronized (pool) {
101108
try {
@@ -108,7 +115,7 @@ private static void waitForPool() {
108115
}
109116

110117
@NotNull
111-
private static String getRandomOf(@NotNull String type) {
118+
private String getRandomOf(@NotNull String type) {
112119
waitForPool();
113120

114121
List<String> urls = pool.get(type);
@@ -117,17 +124,17 @@ private static String getRandomOf(@NotNull String type) {
117124
}
118125

119126
@NotNull
120-
public static String getRandomDealer() {
127+
public String getRandomDealer() {
121128
return getRandomOf("dealer");
122129
}
123130

124131
@NotNull
125-
public static String getRandomSpclient() {
132+
public String getRandomSpclient() {
126133
return getRandomOf("spclient");
127134
}
128135

129136
@NotNull
130-
public static String getRandomAccesspoint() {
137+
public String getRandomAccesspoint() {
131138
return getRandomOf("accesspoint");
132139
}
133140
}

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public final class Session implements Closeable {
100100
(byte) 0xeb, (byte) 0x00, (byte) 0x06, (byte) 0xa2, (byte) 0x5a, (byte) 0xee, (byte) 0xa1, (byte) 0x1b, (byte) 0x13, (byte) 0x87, (byte) 0x3c, (byte) 0xd7,
101101
(byte) 0x19, (byte) 0xe6, (byte) 0x55, (byte) 0xbd
102102
};
103+
private final ApResolver apResolver;
103104
private final DiffieHellman keys;
104105
private final Inner inner;
105106
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new NameThreadFactory(r -> "session-scheduler-" + r.hashCode()));
@@ -128,11 +129,13 @@ public final class Session implements Closeable {
128129
private volatile boolean closing = false;
129130
private volatile ScheduledFuture<?> scheduledReconnect = null;
130131

131-
private Session(@NotNull Inner inner, @NotNull String addr) throws IOException {
132+
private Session(@NotNull Inner inner) throws IOException {
132133
this.inner = inner;
133134
this.keys = new DiffieHellman(inner.random);
134-
this.conn = ConnectionHolder.create(addr, inner.conf);
135135
this.client = createClient(inner.conf);
136+
this.apResolver = new ApResolver(client);
137+
String addr = apResolver.getRandomAccesspoint();
138+
this.conn = ConnectionHolder.create(addr, inner.conf);
136139

137140
LOGGER.info("Created new session! {deviceId: {}, ap: {}, proxy: {}} ", inner.deviceId, addr, inner.conf.proxyEnabled);
138141
}
@@ -566,6 +569,11 @@ public void send(Packet.Type cmd, byte[] payload) throws IOException {
566569
}
567570
}
568571

572+
@NotNull
573+
public ApResolver apResolver() {
574+
return apResolver;
575+
}
576+
569577
@NotNull
570578
public MercuryClient mercury() {
571579
waitAuthLock();
@@ -710,14 +718,14 @@ private void reconnect() {
710718
}
711719

712720
try {
713-
ApResolver.refreshPool();
721+
apResolver.refreshPool();
714722

715723
if (conn != null) {
716724
conn.socket.close();
717725
receiver.stop();
718726
}
719727

720-
conn = ConnectionHolder.create(ApResolver.getRandomAccesspoint(), inner.conf);
728+
conn = ConnectionHolder.create(apResolver.getRandomAccesspoint(), inner.conf);
721729
connect();
722730
authenticatePartial(Authentication.LoginCredentials.newBuilder()
723731
.setUsername(apWelcome.getCanonicalUsername())
@@ -1021,10 +1029,9 @@ public Session create() throws IOException, GeneralSecurityException, SpotifyAut
10211029
if (loginCredentials == null)
10221030
throw new IllegalStateException("You must select an authentication method.");
10231031

1024-
ApResolver.fillPool();
10251032
TimeProvider.init(conf);
10261033

1027-
Session session = new Session(new Inner(deviceType, deviceName, deviceId, preferredLocale, conf), ApResolver.getRandomAccesspoint());
1034+
Session session = new Session(new Inner(deviceType, deviceName, deviceId, preferredLocale, conf));
10281035
session.connect();
10291036
session.authenticate(loginCredentials);
10301037
return session;
@@ -1253,9 +1260,9 @@ private ConnectionHolder(@NotNull Socket socket) throws IOException {
12531260

12541261
@NotNull
12551262
static ConnectionHolder create(@NotNull String addr, @NotNull Configuration conf) throws IOException {
1256-
int colon = addr.indexOf(':');
1257-
String apAddr = addr.substring(0, colon);
1258-
int apPort = Integer.parseInt(addr.substring(colon + 1));
1263+
String[] split = addr.split(":");
1264+
String apAddr = split[0];
1265+
int apPort = Integer.parseInt(split[1]);
12591266
if (!conf.proxyEnabled || conf.proxyType == Proxy.Type.DIRECT)
12601267
return new ConnectionHolder(new Socket(apAddr, apPort));
12611268

lib/src/main/java/xyz/gianlu/librespot/dealer/ApiClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public final class ApiClient {
4646

4747
public ApiClient(@NotNull Session session) {
4848
this.session = session;
49-
this.baseUrl = "https://" + ApResolver.getRandomSpclient();
49+
this.baseUrl = "https://" + session.apResolver().getRandomSpclient();
5050
}
5151

5252
@NotNull

lib/src/main/java/xyz/gianlu/librespot/dealer/DealerClient.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import xyz.gianlu.librespot.common.BytesArrayList;
3232
import xyz.gianlu.librespot.common.NameThreadFactory;
3333
import xyz.gianlu.librespot.common.Utils;
34-
import xyz.gianlu.librespot.core.ApResolver;
3534
import xyz.gianlu.librespot.core.Session;
3635
import xyz.gianlu.librespot.mercury.MercuryClient;
3736

@@ -76,7 +75,7 @@ private static Map<String, String> getHeaders(@NotNull JsonObject obj) {
7675
*/
7776
public synchronized void connect() throws IOException, MercuryClient.MercuryException {
7877
conn = new ConnectionHolder(session, new Request.Builder()
79-
.url(String.format("wss://%s/?access_token=%s", ApResolver.getRandomDealer(), session.tokens().get("playlist-read")))
78+
.url(String.format("wss://%s/?access_token=%s", session.apResolver().getRandomDealer(), session.tokens().get("playlist-read")))
8079
.build());
8180
}
8281

0 commit comments

Comments
 (0)