merge from master
authorNiki Roo <niki@nikiroo.be>
Thu, 14 May 2020 15:10:18 +0000 (17:10 +0200)
committerNiki Roo <niki@nikiroo.be>
Thu, 14 May 2020 15:10:18 +0000 (17:10 +0200)
Main.java
library/RemoteLibrary.java
library/WebLibrary.java
library/WebLibraryServer.java
library/WebLibraryServerHtml.java
library/WebLibraryUrls.java

index 7be305a0977abc17c0fd227f10d1f18c97dca70a..e48f4f53ec7ab7d1951ea4760cacdb64afbccc51 100644 (file)
--- 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();
+               }
        }
 
        /**
index ad92800878f63e31587fa449a07c4618a971bc49..3e0e192d1806abb2e7d4bd270f0e808821c20991 100644 (file)
@@ -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)
index 42f7ea5ccadd4eb40d6b86cfd1f6842abab0db50..7566877cebd48343b47c1764ed31045ee8de78dd 100644 (file)
@@ -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 {
index 9073b8cad58895f02ccbd88d2a8d2a9deebf6397..50dc3d942dcf39aeeadeb68d88c58a714e7551cf 100644 (file)
@@ -70,6 +70,8 @@ public class WebLibraryServer extends WebLibraryServerHtml {
 
        private Map<String, Progress> imprts = new HashMap<String, Progress>();
 
+       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];
 
index ac0631dd60ba32abc8f34b7297510bbc78039c95..7351d0dd3665bceffb58b02574345dfcb498d940 100644 (file)
@@ -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.
+        * <p>
+        * 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}.
         * 
index 5ec669fea4d313dda921209a4d693c5f4ee5d16a..c02fc382341481ed9c8a95a74a16faf13544648b 100644 (file)
@@ -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) {