]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/http/HttpServerHandler.java
Reformat files
[signal-cli] / src / main / java / org / asamk / signal / http / HttpServerHandler.java
index a62139291e36e1394e02698682c1536bd6a14fca..e178066561489515c22047eee91400bd1c7f2739 100644 (file)
@@ -13,7 +13,6 @@ import org.asamk.signal.jsonrpc.SignalJsonRpcCommandHandler;
 import org.asamk.signal.manager.Manager;
 import org.asamk.signal.manager.MultiAccountManager;
 import org.asamk.signal.manager.api.Pair;
-import org.asamk.signal.manager.util.Utils;
 import org.asamk.signal.util.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -25,9 +24,9 @@ import java.util.Map;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-public class HttpServerHandler {
+public class HttpServerHandler implements AutoCloseable {
 
-    private final static Logger logger = LoggerFactory.getLogger(HttpServerHandler.class);
+    private static final Logger logger = LoggerFactory.getLogger(HttpServerHandler.class);
 
     private final ObjectMapper objectMapper = Util.createJsonObjectMapper();
 
@@ -36,6 +35,8 @@ public class HttpServerHandler {
     private final SignalJsonRpcCommandHandler commandHandler;
     private final MultiAccountManager c;
     private final Manager m;
+    private HttpServer server;
+    private final AtomicBoolean shutdown = new AtomicBoolean(false);
 
     public HttpServerHandler(final InetSocketAddress address, final Manager m) {
         this.address = address;
@@ -52,16 +53,34 @@ public class HttpServerHandler {
     }
 
     public void init() throws IOException {
-        logger.info("Starting server on " + address.toString());
+        if (server != null) {
+            throw new AssertionError("HttpServerHandler already initialized");
+        }
+        logger.debug("Starting HTTP server on {}", address);
 
-        final var server = HttpServer.create(address, 0);
-        server.setExecutor(Executors.newFixedThreadPool(10));
+        server = HttpServer.create(address, 0);
+        server.setExecutor(Executors.newCachedThreadPool());
 
         server.createContext("/api/v1/rpc", this::handleRpcEndpoint);
         server.createContext("/api/v1/events", this::handleEventsEndpoint);
         server.createContext("/api/v1/check", this::handleCheckEndpoint);
 
         server.start();
+        logger.info("Started HTTP server on {}", address);
+    }
+
+    @Override
+    public void close() {
+        if (server != null) {
+            shutdown.set(true);
+            synchronized (this) {
+                this.notifyAll();
+            }
+            // Increase this delay when https://bugs.openjdk.org/browse/JDK-8304065 is fixed
+            server.stop(2);
+            server = null;
+            shutdown.set(false);
+        }
     }
 
     private void sendResponse(int status, Object response, HttpExchange httpExchange) throws IOException {
@@ -89,7 +108,8 @@ public class HttpServerHandler {
             return;
         }
 
-        if (!"application/json".equals(httpExchange.getRequestHeaders().getFirst("Content-Type"))) {
+        final var contentType = httpExchange.getRequestHeaders().getFirst("Content-Type");
+        if (contentType == null || !contentType.startsWith("application/json")) {
             sendResponse(415, null, httpExchange);
             return;
         }
@@ -137,7 +157,7 @@ public class HttpServerHandler {
 
         try {
             final var queryString = httpExchange.getRequestURI().getQuery();
-            final var query = queryString == null ? Map.<String, String>of() : Utils.getQueryMap(queryString);
+            final var query = queryString == null ? Map.<String, String>of() : Util.getQueryMap(queryString);
 
             List<Manager> managers = getManagerFromQuery(query);
             if (managers == null) {
@@ -153,7 +173,7 @@ public class HttpServerHandler {
             final var handlers = subscribeReceiveHandlers(managers, sender, () -> {
                 shouldStop.set(true);
                 synchronized (this) {
-                    this.notify();
+                    this.notifyAll();
                 }
             });
 
@@ -162,7 +182,7 @@ public class HttpServerHandler {
                     synchronized (this) {
                         wait(15_000);
                     }
-                    if (shouldStop.get()) {
+                    if (shouldStop.get() || shutdown.get()) {
                         break;
                     }
 
@@ -201,26 +221,28 @@ public class HttpServerHandler {
     }
 
     private List<Manager> getManagerFromQuery(final Map<String, String> query) {
-        List<Manager> managers;
         if (m != null) {
-            managers = List.of(m);
-        } else {
+            return List.of(m);
+        }
+        if (c != null) {
             final var account = query.get("account");
             if (account == null || account.isEmpty()) {
-                managers = c.getManagers();
+                return c.getManagers();
             } else {
                 final var manager = c.getManager(account);
                 if (manager == null) {
                     return null;
                 }
-                managers = List.of(manager);
+                return List.of(manager);
             }
         }
-        return managers;
+        throw new AssertionError("Unreachable state");
     }
 
     private List<Pair<Manager, Manager.ReceiveMessageHandler>> subscribeReceiveHandlers(
-            final List<Manager> managers, final ServerSentEventSender sender, Callable unsubscribe
+            final List<Manager> managers,
+            final ServerSentEventSender sender,
+            Callable unsubscribe
     ) {
         return managers.stream().map(m1 -> {
             final var receiveMessageHandler = new JsonReceiveMessageHandler(m1, s -> {