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;
} 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());
* @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();
+ }
}
/**
* @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)
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 {
private Map<String, Progress> imprts = new HashMap<String, Progress>();
+ private boolean exiting;
+
public WebLibraryServer(boolean secure) throws IOException {
super(secure);
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);
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];
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];
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();
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];
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);
}
} 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: "
}
}
+ protected void doStop() {
+ server.stop();
+ }
+
/**
* The traces handler for this {@link WebLibraryServerHtml}.
*
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}";
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) {