diff --git a/src/main/java/org/asamk/signal/commands/Commands.java b/src/main/java/org/asamk/signal/commands/Commands.java index 368b6a4d..1c4251da 100644 --- a/src/main/java/org/asamk/signal/commands/Commands.java +++ b/src/main/java/org/asamk/signal/commands/Commands.java @@ -16,7 +16,6 @@ public class Commands { addCommand(new DeleteLocalAccountDataCommand()); addCommand(new FinishLinkCommand()); addCommand(new GetUserStatusCommand()); - addCommand(new HttpServerCommand()); addCommand(new JoinGroupCommand()); addCommand(new JsonRpcDispatcherCommand()); addCommand(new LinkCommand()); diff --git a/src/main/java/org/asamk/signal/commands/DaemonCommand.java b/src/main/java/org/asamk/signal/commands/DaemonCommand.java index 01d0326f..79014ee0 100644 --- a/src/main/java/org/asamk/signal/commands/DaemonCommand.java +++ b/src/main/java/org/asamk/signal/commands/DaemonCommand.java @@ -13,6 +13,7 @@ import org.asamk.signal.commands.exceptions.UnexpectedErrorException; import org.asamk.signal.commands.exceptions.UserErrorException; import org.asamk.signal.dbus.DbusSignalControlImpl; import org.asamk.signal.dbus.DbusSignalImpl; +import org.asamk.signal.http.HttpServerHandler; import org.asamk.signal.json.JsonReceiveMessageHandler; import org.asamk.signal.jsonrpc.SignalJsonRpcDispatcherHandler; import org.asamk.signal.manager.Manager; @@ -69,6 +70,10 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { .nargs("?") .setConst("localhost:7583") .help("Expose a JSON-RPC interface on a TCP socket (default localhost:7583)."); + subparser.addArgument("--http") + .nargs("?") + .setConst("localhost:8080") + .help("Expose a JSON-RPC interface as http endpoint."); subparser.addArgument("--no-receive-stdout") .help("Don’t print received messages to stdout.") .action(Arguments.storeTrue()); @@ -128,6 +133,12 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { final var serverChannel = IOUtils.bindSocket(address); runSocketSingleAccount(m, serverChannel, receiveMode == ReceiveMode.MANUAL); } + final var httpAddress = ns.getString("http"); + if (httpAddress != null) { + final var address = IOUtils.parseInetSocketAddress(httpAddress); + final var handler = new HttpServerHandler(address.getPort(), m); + handler.init(); + } final var isDbusSystem = Boolean.TRUE.equals(ns.getBoolean("dbus-system")); if (isDbusSystem) { runDbusSingleAccount(m, true, receiveMode != ReceiveMode.ON_START); @@ -199,6 +210,12 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { final var serverChannel = IOUtils.bindSocket(address); runSocketMultiAccount(c, serverChannel, receiveMode == ReceiveMode.MANUAL); } + final var httpAddress = ns.getString("http"); + if (httpAddress != null) { + final var address = IOUtils.parseInetSocketAddress(httpAddress); + final var handler = new HttpServerHandler(address.getPort(), c); + handler.init(); + } final var isDbusSystem = Boolean.TRUE.equals(ns.getBoolean("dbus-system")); if (isDbusSystem) { runDbusMultiAccount(c, receiveMode != ReceiveMode.ON_START, true); diff --git a/src/main/java/org/asamk/signal/commands/HttpServerCommand.java b/src/main/java/org/asamk/signal/commands/HttpServerCommand.java deleted file mode 100644 index c170a85c..00000000 --- a/src/main/java/org/asamk/signal/commands/HttpServerCommand.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.asamk.signal.commands; - -import net.sourceforge.argparse4j.inf.Namespace; -import net.sourceforge.argparse4j.inf.Subparser; - -import org.asamk.signal.commands.exceptions.CommandException; -import org.asamk.signal.http.HttpServerHandler; -import org.asamk.signal.manager.MultiAccountManager; -import org.asamk.signal.output.OutputWriter; - -public class HttpServerCommand implements MultiLocalCommand { - - @Override - public String getName() { - return "http"; - } - - @Override - public void attachToSubparser(final Subparser subparser) { - subparser.help("Takes commands via an http connection"); - subparser.addArgument("--port") - .help("The port on which to open the HTTP service") - .type(Integer.class) - .setDefault(8080); - } - - @Override - public void handleCommand( - final Namespace ns, - final MultiAccountManager m, - final OutputWriter outputWriter - ) throws CommandException { - - final var port = ns.getInt("port"); - - final var handler = new HttpServerHandler(); - handler.init(port, m); - - } -} diff --git a/src/main/java/org/asamk/signal/http/HttpServerHandler.java b/src/main/java/org/asamk/signal/http/HttpServerHandler.java index c7804ef6..c4544e60 100644 --- a/src/main/java/org/asamk/signal/http/HttpServerHandler.java +++ b/src/main/java/org/asamk/signal/http/HttpServerHandler.java @@ -38,7 +38,25 @@ public class HttpServerHandler { private final ObjectMapper objectMapper = Util.createJsonObjectMapper(); - public void init(int port, MultiAccountManager m) { + private final int port; + + private final Manager m; + + private final MultiAccountManager c; + + public HttpServerHandler(final int port, final Manager m) { + this.port = port; + this.m = m; + this.c = null; + } + + public HttpServerHandler(final int port, final MultiAccountManager c) { + this.port = port; + this.m = null; + this.c = c; + } + + public void init() { try { @@ -63,7 +81,7 @@ public class HttpServerHandler { final var ns = new JsonRpcNamespace(params); - final var responseBody = processRequest(m, ns, request); + final var responseBody = processRequest(ns, request); sendResponse(200, responseBody, httpExchange); @@ -88,15 +106,6 @@ public class HttpServerHandler { server.start(); - // TODO there may be a better way to keep the main thread running. - try { - while (true) { - Thread.sleep(1000); - } - } catch (InterruptedException ex) { } - - logger.info("Server shut down"); - } catch (Throwable ex) { ex.printStackTrace(); } @@ -104,7 +113,6 @@ public class HttpServerHandler { } private JsonRpcResponse processRequest( - final MultiAccountManager m, final JsonRpcNamespace ns, final JsonRpcRequest request ) throws JsonRpcException, CommandException, IOException { @@ -113,12 +121,27 @@ public class HttpServerHandler { final var command = Commands.getCommand(request.getMethod()); if (command instanceof LocalCommand) { - final var manager = getManagerFromParams(request.getParams(), m); + final Manager manager; + if (c != null) { + manager = getManagerFromParams(request.getParams(), c); + } else { + manager = m; + } ((LocalCommand) command).handleCommand(ns, manager, new JsonWriterImpl(writer)); } else if (command instanceof MultiLocalCommand) { - ((MultiLocalCommand) command).handleCommand(ns, m, new JsonWriterImpl(writer)); + if (c == null) { + throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.INVALID_PARAMS, + "Cannot run multi command when running in single mode.", + null)); + } + ((MultiLocalCommand) command).handleCommand(ns, c, new JsonWriterImpl(writer)); } else if (command instanceof RegistrationCommand) { - final var registrationManager = getRegistrationManagerFromParams(request.getParams(), m); + if (c == null) { + throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.INVALID_PARAMS, + "Cannot run multi command when running in single mode.", + null)); + } + final var registrationManager = getRegistrationManagerFromParams(request.getParams(), c); if (registrationManager != null) { ((RegistrationCommand) command).handleCommand(ns, registrationManager); } else {