From 6d465e886ae46c9da99117cc4302948f700a51c4 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Thu, 14 May 2020 17:10:18 +0200 Subject: [PATCH] merge from master --- Main.java | 19 +++++++--- library/RemoteLibrary.java | 2 +- library/WebLibrary.java | 10 ++++++ library/WebLibraryServer.java | 58 +++++++++++++++++++++++++++++++ library/WebLibraryServerHtml.java | 13 +++++++ library/WebLibraryUrls.java | 8 +++-- 6 files changed, 102 insertions(+), 8 deletions(-) diff --git a/Main.java b/Main.java index 7be305a..e48f4f5 100644 --- a/Main.java +++ b/Main.java @@ -19,6 +19,7 @@ import be.nikiroo.fanfix.library.CacheLibrary; import be.nikiroo.fanfix.library.LocalLibrary; import be.nikiroo.fanfix.library.RemoteLibrary; import be.nikiroo.fanfix.library.RemoteLibraryServer; +import be.nikiroo.fanfix.library.WebLibrary; import be.nikiroo.fanfix.library.WebLibraryServer; import be.nikiroo.fanfix.output.BasicOutput; import be.nikiroo.fanfix.output.BasicOutput.OutputType; @@ -351,7 +352,14 @@ public class Main { } else if (port == null) { port = Integer.parseInt(args[i]); - BasicLibrary lib = new RemoteLibrary(key, host, port); + BasicLibrary lib; + if (host.startsWith("http://") + || host.startsWith("https://")) { + lib = new WebLibrary(key, host, port); + } else { + lib = new RemoteLibrary(key, host, port); + } + lib = new CacheLibrary( Instance.getInstance().getRemoteDir(host), lib, Instance.getInstance().getUiConfig()); @@ -1070,10 +1078,13 @@ public class Main { * @throws SSLException * when the key was not accepted */ - private void stopServer( - String key, String host, Integer port) + private void stopServer(String key, String host, Integer port) throws IOException, SSLException { - new RemoteLibrary(key, host, port).exit(); + if (host.startsWith("http://") || host.startsWith("https://")) { + new WebLibrary(key, host, port).stop(); + } else { + new RemoteLibrary(key, host, port).stop(); + } } /** diff --git a/library/RemoteLibrary.java b/library/RemoteLibrary.java index ad92800..3e0e192 100644 --- a/library/RemoteLibrary.java +++ b/library/RemoteLibrary.java @@ -446,7 +446,7 @@ public class RemoteLibrary extends BasicLibrary { * @throws SSLException * when the key was not accepted */ - public void exit() throws IOException, SSLException { + public void stop() throws IOException, SSLException { connectRemoteAction(new RemoteAction() { @Override public void action(ConnectActionClientObject action) diff --git a/library/WebLibrary.java b/library/WebLibrary.java index 42f7ea5..7566877 100644 --- a/library/WebLibrary.java +++ b/library/WebLibrary.java @@ -126,6 +126,16 @@ public class WebLibrary extends BasicLibrary { return new Version(); } + /** + * Stop the server. + * + * @throws IOException + * in case of I/O errors + */ + public void stop() throws IOException { + post(WebLibraryUrls.EXIT_URL, null).close(); + } + @Override public Status getStatus() { try { diff --git a/library/WebLibraryServer.java b/library/WebLibraryServer.java index 9073b8c..50dc3d9 100644 --- a/library/WebLibraryServer.java +++ b/library/WebLibraryServer.java @@ -70,6 +70,8 @@ public class WebLibraryServer extends WebLibraryServerHtml { private Map imprts = new HashMap(); + private boolean exiting; + public WebLibraryServer(boolean secure) throws IOException { super(secure); @@ -97,6 +99,42 @@ public class WebLibraryServer extends WebLibraryServerHtml { new Thread(this).start(); } + @Override + protected Response stop(WLoginResult login) { + if (!login.isRw()) { + return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN, + NanoHTTPD.MIME_PLAINTEXT, "Exit not allowed"); + } + + if (exiting) { + return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, + NanoHTTPD.MIME_PLAINTEXT, "Server is already exiting..."); + } + + exiting = true; + Instance.getInstance().getTraceHandler().trace("Exiting"); + + boolean ok; + do { + synchronized (imprts) { + ok = imprts.isEmpty(); + } + if (!ok) { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + Instance.getInstance().getTraceHandler() + .trace("Waiting to exit..."); + } + } + } while (!ok); + + doStop(); + + return NanoHTTPD.newFixedLengthResponse(Status.OK, + NanoHTTPD.MIME_PLAINTEXT, "Exited"); + } + @Override protected WLoginResult login(boolean badLogin, boolean badCookie) { return new WLoginResult(false, false); @@ -303,6 +341,11 @@ public class WebLibraryServer extends WebLibraryServerHtml { return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "SET story part not allowed"); } + + if (exiting) { + return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, + NanoHTTPD.MIME_PLAINTEXT, "Server is exiting..."); + } String luid = uriParts[off + 0]; String type = uriParts[off + 1]; @@ -383,6 +426,11 @@ public class WebLibraryServer extends WebLibraryServerHtml { return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "Cover request not allowed"); } + + if (exiting) { + return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, + NanoHTTPD.MIME_PLAINTEXT, "Server is exiting..."); + } String type = uriParts[off + 0]; String id = uriParts[off + 1]; @@ -409,6 +457,11 @@ public class WebLibraryServer extends WebLibraryServerHtml { return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "Import not allowed"); } + + if (exiting) { + return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, + NanoHTTPD.MIME_PLAINTEXT, "Server is exiting..."); + } final URL url = new URL(urlStr); final Progress pg = new Progress(); @@ -476,6 +529,11 @@ public class WebLibraryServer extends WebLibraryServerHtml { return NanoHTTPD.newFixedLengthResponse(Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "Delete not allowed"); } + + if (exiting) { + return NanoHTTPD.newFixedLengthResponse(Status.SERVICE_UNAVAILABLE, + NanoHTTPD.MIME_PLAINTEXT, "Server is exiting..."); + } String luid = uriParts[off + 0]; diff --git a/library/WebLibraryServerHtml.java b/library/WebLibraryServerHtml.java index ac0631d..7351d0d 100644 --- a/library/WebLibraryServerHtml.java +++ b/library/WebLibraryServerHtml.java @@ -70,6 +70,13 @@ abstract class WebLibraryServerHtml implements Runnable { protected abstract Response delete(String uri, WLoginResult login) throws IOException; + /** + * Wait until all operations are done and stop the server. + *

+ * All the new R/W operations will be refused after a call to stop. + */ + protected abstract Response stop(WLoginResult login); + public WebLibraryServerHtml(boolean secure) throws IOException { Integer port = Instance.getInstance().getConfig() .getInteger(Config.SERVER_PORT); @@ -210,6 +217,8 @@ abstract class WebLibraryServerHtml implements Runnable { } } else if (WebLibraryUrls.isDeleteUrl(uri)) { rep = delete(uri, login); + } else if (WebLibraryUrls.EXIT_URL.equals(uri)) { + rep = WebLibraryServerHtml.this.stop(login); } else { getTraceHandler().error( "Supported URL was not processed: " @@ -272,6 +281,10 @@ abstract class WebLibraryServerHtml implements Runnable { } } + protected void doStop() { + server.stop(); + } + /** * The traces handler for this {@link WebLibraryServerHtml}. * diff --git a/library/WebLibraryUrls.java b/library/WebLibraryUrls.java index 5ec669f..c02fc38 100644 --- a/library/WebLibraryUrls.java +++ b/library/WebLibraryUrls.java @@ -7,6 +7,8 @@ class WebLibraryUrls { static public final String LOGOUT_URL = "/logout"; + static public final String EXIT_URL = "/exit"; + static private final String VIEWER_URL_BASE = "/view/story/"; static private final String VIEWER_URL = VIEWER_URL_BASE + "{luid}/{chap}/{para}"; @@ -103,9 +105,9 @@ class WebLibraryUrls { static public boolean isSupportedUrl(String url) { return INDEX_URL.equals(url) || VERSION_URL.equals(url) - || LOGOUT_URL.equals(url) || isViewUrl(url) || isStoryUrl(url) - || isListUrl(url) || isCoverUrl(url) || isImprtUrl(url) - || isDeleteUrl(url); + || LOGOUT_URL.equals(url) || EXIT_URL.equals(url) + || isViewUrl(url) || isStoryUrl(url) || isListUrl(url) + || isCoverUrl(url) || isImprtUrl(url) || isDeleteUrl(url); } static public String getCoverUrlStory(String luid) { -- 2.27.0