|
| 1 | +package xyz.gianlu.librespot.api.handlers; |
| 2 | + |
| 3 | +import io.undertow.server.HttpServerExchange; |
| 4 | +import io.undertow.util.FileUtils; |
| 5 | +import io.undertow.util.HeaderValues; |
| 6 | +import io.undertow.util.Headers; |
| 7 | +import io.undertow.util.HttpString; |
| 8 | +import okhttp3.*; |
| 9 | +import org.jetbrains.annotations.NotNull; |
| 10 | +import xyz.gianlu.librespot.api.SessionWrapper; |
| 11 | +import xyz.gianlu.librespot.core.Session; |
| 12 | +import xyz.gianlu.librespot.core.TokenProvider; |
| 13 | + |
| 14 | +public final class WebApiHandler extends AbsSessionHandler { |
| 15 | + 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"}; |
| 16 | + private static final HttpUrl BASE_API_URL = HttpUrl.get("https://api.spotify.com"); |
| 17 | + private static final HttpString HEADER_X_SCOPE = HttpString.tryFromString("X-Spotify-Scope"); |
| 18 | + |
| 19 | + public WebApiHandler(@NotNull SessionWrapper wrapper) { |
| 20 | + super(wrapper); |
| 21 | + } |
| 22 | + |
| 23 | + @Override |
| 24 | + protected void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Session session) throws Exception { |
| 25 | + exchange.startBlocking(); |
| 26 | + if (exchange.isInIoThread()) { |
| 27 | + exchange.dispatch(this); |
| 28 | + return; |
| 29 | + } |
| 30 | + |
| 31 | + String body = FileUtils.readFile(exchange.getInputStream()); |
| 32 | + HeaderValues contentType = exchange.getRequestHeaders().get(Headers.CONTENT_TYPE); |
| 33 | + |
| 34 | + String[] scopes = API_TOKENS_ALL; |
| 35 | + if (exchange.getRequestHeaders().contains(HEADER_X_SCOPE)) |
| 36 | + scopes = exchange.getRequestHeaders().get(HEADER_X_SCOPE).toArray(new String[0]); |
| 37 | + |
| 38 | + TokenProvider.StoredToken token = session.tokens().getToken(scopes); |
| 39 | + |
| 40 | + HttpUrl.Builder url = BASE_API_URL.newBuilder() |
| 41 | + .addPathSegments(exchange.getRelativePath().substring(1)) |
| 42 | + .query(exchange.getQueryString()); |
| 43 | + |
| 44 | + Request.Builder req = new Request.Builder() |
| 45 | + .url(url.build()) |
| 46 | + .addHeader("Authorization", "Bearer " + token.accessToken); |
| 47 | + |
| 48 | + String method = exchange.getRequestMethod().toString(); |
| 49 | + if (!body.isEmpty() && contentType != null) |
| 50 | + req.method(method, RequestBody.create(body, MediaType.get(contentType.getFirst()))); |
| 51 | + else |
| 52 | + req.method(method, null); |
| 53 | + |
| 54 | + try (Response resp = session.client().newCall(req.build()).execute()) { |
| 55 | + exchange.setStatusCode(resp.code()); |
| 56 | + |
| 57 | + String respContentType = resp.header("Content-Type"); |
| 58 | + if (respContentType != null) exchange.getResponseHeaders().add(Headers.CONTENT_TYPE, respContentType); |
| 59 | + |
| 60 | + ResponseBody respBody = resp.body(); |
| 61 | + if (respBody != null) exchange.getOutputStream().write(respBody.bytes()); |
| 62 | + } |
| 63 | + } |
| 64 | +} |
0 commit comments