From a77fad717f625663b2944591c35e3220f0e26e7c Mon Sep 17 00:00:00 2001 From: Twinki Date: Wed, 15 Sep 2021 11:59:37 -0500 Subject: [PATCH 1/3] feat: Add GET /instance endpoint, which returns some basic information about the current session - `device_id`, `device_name`,`device_type`, `country_code`, and `preferred_locale` --- api/README.md | 1 + .../xyz/gianlu/librespot/api/ApiServer.java | 1 + .../api/handlers/InstanceHandler.java | 82 +++++++++++++------ 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/api/README.md b/api/README.md index 771ba6db..77c3f8ed 100644 --- a/api/README.md +++ b/api/README.md @@ -42,6 +42,7 @@ All the endpoints will respond with `200` if successful or: - `GET /profile/{user_id}/following` Retrieve a list of profiles that the specified user is following ### Instance +- `GET /instance` Returns a json model that contains basic information about the current session; `device_id`, `device_name`,`device_type`, `country_code`, and `preferred_locale` - `POST /instance/terminate` Terminates the API server. - `POST /instance/close` Closes the current session (and player). diff --git a/api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java b/api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java index 2f264282..bbd9aedb 100644 --- a/api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java +++ b/api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java @@ -45,6 +45,7 @@ public ApiServer(int port, @NotNull String host, @NotNull SessionWrapper wrapper .post("/token/{scope}", new TokensHandler(wrapper)) .post("/profile/{user_id}/{action}", new ProfileHandler(wrapper)) .post("/web-api/{endpoint}", new WebApiHandler(wrapper)) + .get("/instance", InstanceHandler.forSession(this, wrapper)) .post("/instance/{action}", InstanceHandler.forSession(this, wrapper)) .post("/discovery/{action}", new DiscoveryHandler()) .get("/events", events) diff --git a/api/src/main/java/xyz/gianlu/librespot/api/handlers/InstanceHandler.java b/api/src/main/java/xyz/gianlu/librespot/api/handlers/InstanceHandler.java index d5c0b776..36a0a72a 100644 --- a/api/src/main/java/xyz/gianlu/librespot/api/handlers/InstanceHandler.java +++ b/api/src/main/java/xyz/gianlu/librespot/api/handlers/InstanceHandler.java @@ -16,7 +16,10 @@ package xyz.gianlu.librespot.api.handlers; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; import io.undertow.server.HttpServerExchange; +import io.undertow.util.Headers; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.gianlu.librespot.api.ApiServer; @@ -55,6 +58,16 @@ private static String getAction(@NotNull HttpServerExchange exchange) throws IOE return action; } + private static String getInstanceInfo(@NotNull Session session) throws JsonSyntaxException { + JsonObject infoObj = new JsonObject(); + infoObj.addProperty("device_id", session.deviceId()); + infoObj.addProperty("device_name", session.deviceName()); + infoObj.addProperty("device_type", session.deviceType().toString()); + infoObj.addProperty("country_code", session.countryCode()); + infoObj.addProperty("preferred_locale", session.preferredLocale()); + return infoObj.toString(); + } + private static class SessionHandler extends AbsSessionHandler { private final ApiServer server; @@ -71,19 +84,31 @@ protected void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Sess return; } - String action = getAction(exchange); - if (action == null) return; - - switch (action) { - case "terminate": - exchange.endExchange(); - new Thread(server::stop).start(); - break; - case "close": - session.close(); + String requestMethod = exchange.getRequestMethod().toString(); + switch(requestMethod) { + case "GET": + String info = getInstanceInfo(session); + exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json"); + exchange.getResponseSender().send(info); + return; + case "POST": + String action = getAction(exchange); + if (action == null) return; + + switch (action) { + case "terminate": + exchange.endExchange(); + new Thread(server::stop).start(); + break; + case "close": + session.close(); + break; + default: + Utils.invalidParameter(exchange, "action"); + break; + } break; default: - Utils.invalidParameter(exchange, "action"); break; } } @@ -105,20 +130,31 @@ protected void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Sess return; } - String action = getAction(exchange); - if (action == null) return; - - switch (action) { - case "terminate": - exchange.endExchange(); - new Thread(server::stop).start(); - break; - case "close": - player.close(); - session.close(); + String requestMethod = exchange.getRequestMethod().toString(); + switch(requestMethod) { + case "GET": + String info = getInstanceInfo(session); + exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json"); + exchange.getResponseSender().send(info); + return; + case "POST": + String action = getAction(exchange); + if (action == null) return; + + switch (action) { + case "terminate": + exchange.endExchange(); + new Thread(server::stop).start(); + break; + case "close": + session.close(); + break; + default: + Utils.invalidParameter(exchange, "action"); + break; + } break; default: - Utils.invalidParameter(exchange, "action"); break; } } From 8e115561ecd7070c94a8a9a293ee6baf0803953a Mon Sep 17 00:00:00 2001 From: Twinki Date: Thu, 16 Sep 2021 08:48:38 -0500 Subject: [PATCH 2/3] resolve: extract InstanceHandler.forSession into a variable - 'Please extract this to a variable instead of calling forSession twice.' --- api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java b/api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java index bbd9aedb..fa001a7a 100644 --- a/api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java +++ b/api/src/main/java/xyz/gianlu/librespot/api/ApiServer.java @@ -35,6 +35,8 @@ public class ApiServer { private Undertow undertow = null; public ApiServer(int port, @NotNull String host, @NotNull SessionWrapper wrapper) { + AbsSessionHandler instanceHandler = InstanceHandler.forSession(this, wrapper); + this.port = port; this.host = host; this.wrapper = wrapper; @@ -45,8 +47,8 @@ public ApiServer(int port, @NotNull String host, @NotNull SessionWrapper wrapper .post("/token/{scope}", new TokensHandler(wrapper)) .post("/profile/{user_id}/{action}", new ProfileHandler(wrapper)) .post("/web-api/{endpoint}", new WebApiHandler(wrapper)) - .get("/instance", InstanceHandler.forSession(this, wrapper)) - .post("/instance/{action}", InstanceHandler.forSession(this, wrapper)) + .get("/instance", instanceHandler) + .post("/instance/{action}", instanceHandler) .post("/discovery/{action}", new DiscoveryHandler()) .get("/events", events) .setFallbackHandler(new PathHandler(ResponseCodeHandler.HANDLE_404) From ef4e95d9d380808a45895c6511a17275c419fcf4 Mon Sep 17 00:00:00 2001 From: Twinki Date: Thu, 16 Sep 2021 08:51:01 -0500 Subject: [PATCH 3/3] resolve: add Utils.methodNotAllowed - Switch to 405 / method not allowed in InstanceHandler --- api/src/main/java/xyz/gianlu/librespot/api/Utils.java | 5 +++++ .../xyz/gianlu/librespot/api/handlers/InstanceHandler.java | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/xyz/gianlu/librespot/api/Utils.java b/api/src/main/java/xyz/gianlu/librespot/api/Utils.java index 5ef09309..bdafceae 100644 --- a/api/src/main/java/xyz/gianlu/librespot/api/Utils.java +++ b/api/src/main/java/xyz/gianlu/librespot/api/Utils.java @@ -83,4 +83,9 @@ public static void internalError(@NotNull HttpServerExchange exchange, @NotNull exchange.setStatusCode(StatusCodes.INTERNAL_SERVER_ERROR); exchange.getResponseSender().send(String.format(INTERNAL_ERROR_BODY, reason)); } + + public static void methodNotAllowed(@NotNull HttpServerExchange exchange) { + exchange.setStatusCode(StatusCodes.METHOD_NOT_ALLOWED); + exchange.getResponseSender().send(StatusCodes.METHOD_NOT_ALLOWED_STRING); + } } diff --git a/api/src/main/java/xyz/gianlu/librespot/api/handlers/InstanceHandler.java b/api/src/main/java/xyz/gianlu/librespot/api/handlers/InstanceHandler.java index 36a0a72a..1cb54c67 100644 --- a/api/src/main/java/xyz/gianlu/librespot/api/handlers/InstanceHandler.java +++ b/api/src/main/java/xyz/gianlu/librespot/api/handlers/InstanceHandler.java @@ -104,7 +104,7 @@ protected void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Sess session.close(); break; default: - Utils.invalidParameter(exchange, "action"); + Utils.methodNotAllowed(exchange); break; } break; @@ -150,7 +150,7 @@ protected void handleRequest(@NotNull HttpServerExchange exchange, @NotNull Sess session.close(); break; default: - Utils.invalidParameter(exchange, "action"); + Utils.methodNotAllowed(exchange); break; } break;