allox subkeys, step 1 (keys not active)
authorNiki Roo <niki@nikiroo.be>
Fri, 10 May 2019 17:19:02 +0000 (19:19 +0200)
committerNiki Roo <niki@nikiroo.be>
Fri, 10 May 2019 17:19:02 +0000 (19:19 +0200)
libs/nikiroo-utils-4.7.2-dev-sources.jar
src/be/nikiroo/fanfix/Instance.java
src/be/nikiroo/fanfix/Main.java
src/be/nikiroo/fanfix/bundles/Config.java
src/be/nikiroo/fanfix/bundles/config.properties
src/be/nikiroo/fanfix/bundles/resources_core.properties
src/be/nikiroo/fanfix/bundles/resources_core_fr.properties
src/be/nikiroo/fanfix/library/RemoteLibrary.java
src/be/nikiroo/fanfix/library/RemoteLibraryServer.java
src/be/nikiroo/fanfix/package-info.java

index c4f532dfe98705c805819c33f9d373d787aad704..180d3871ed71b53e6217cfd007b9b1bc92145852 100644 (file)
Binary files a/libs/nikiroo-utils-4.7.2-dev-sources.jar and b/libs/nikiroo-utils-4.7.2-dev-sources.jar differ
index b6849c279dd298f3b1d1f139367c613a87d9c980..ef7799fbc497d246e7d64ddaf80f8d0cde59546f 100644 (file)
@@ -441,6 +441,7 @@ public class Instance {
                                                                + getFile(libDir), e));
                        }
                } else {
+                       Exception ex = null;
                        int pos = remoteLib.lastIndexOf(":");
                        if (pos >= 0) {
                                String port = remoteLib.substring(pos + 1).trim();
@@ -459,13 +460,14 @@ public class Instance {
                                                                lib);
 
                                        } catch (Exception e) {
+                                               ex = e;
                                        }
                                }
                        }
 
                        if (lib == null) {
                                tracer.error(new IOException(
-                                               "Cannot create remote library for: " + remoteLib));
+                                               "Cannot create remote library for: " + remoteLib, ex));
                        }
                }
 
index 995251d16d0ee7ca6a0438ce21c8268efa6c51cc..f8c0ca25f486b3d0f082bf0874cd6689d26bf42b 100644 (file)
@@ -7,6 +7,7 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 
+import be.nikiroo.fanfix.bundles.Config;
 import be.nikiroo.fanfix.bundles.StringId;
 import be.nikiroo.fanfix.data.Chapter;
 import be.nikiroo.fanfix.data.MetaData;
@@ -76,9 +77,8 @@ public class Main {
         * <li>--set-reader [reader type]: set the reader type to CLI, TUI or LOCAL
         * for this command</li>
         * <li>--version: get the version of the program</li>
-        * <li>--server [key] [port]: start a server on this port</li>
-        * <li>--stop-server [key] [port]: stop the running server on this port if
-        * any</li>
+        * <li>--server: start the server mode (see config file for parameters)</li>
+        * <li>--stop-server: stop the running server on this port if any</li>
         * <li>--remote [key] [host] [port]: use a the given remote library</li>
         * </ul>
         * 
@@ -326,14 +326,10 @@ public class Main {
                                exitCode = 255; // no arguments for this option
                                break;
                        case SERVER:
+                               exitCode = 255; // no arguments for this option
+                               break;
                        case STOP_SERVER:
-                               if (key == null) {
-                                       key = args[i];
-                               } else if (port == null) {
-                                       port = Integer.parseInt(args[i]);
-                               } else {
-                                       exitCode = 255;
-                               }
+                               exitCode = 255; // no arguments for this option
                                break;
                        case REMOTE:
                                if (key == null) {
@@ -571,8 +567,11 @@ public class Main {
                                BasicReader.getReader().browse(null);
                                break;
                        case SERVER:
+                               key = Instance.getConfig().getString(Config.SERVER_KEY);
+                               port = Instance.getConfig().getInteger(Config.SERVER_PORT);
                                if (port == null) {
-                                       exitCode = 255;
+                                       System.err.println("No port configured in the config file");
+                                       exitCode = 15;
                                        break;
                                }
                                try {
@@ -584,8 +583,11 @@ public class Main {
                                }
                                return;
                        case STOP_SERVER:
+                               key = Instance.getConfig().getString(Config.SERVER_KEY);
+                               port = Instance.getConfig().getInteger(Config.SERVER_PORT);
                                if (port == null) {
-                                       exitCode = 255;
+                                       System.err.println("No port configured in the config file");
+                                       exitCode = 15;
                                        break;
                                }
 
index 74beeaec6c713e8bf5fa8d5124640de59dd54124..35f63d6dca7e06925ec08e799c348bf4778c7178 100644 (file)
@@ -32,6 +32,16 @@ public enum Config {
        DEFAULT_COVERS_DIR, //
        @Meta(description = "string", info = "The default library to use (KEY:SERVER:PORT), or empty for the local library")
        DEFAULT_LIBRARY, //
+       @Meta(def = "58365", description = "The port on which we can start the server", format = Format.INT, info = "A valid port")
+       SERVER_PORT, //
+       @Meta(def = "", description = "The encryption key for the server (NOT including a subkey)", format = Format.PASSWORD, info = "cannot contain the pipe character (|)")
+       SERVER_KEY, //
+       @Meta(def = "TRUE", description = "Allow write access to the clients by default (download story, move story...)", format = Format.BOOLEAN)
+       SERVER_RW, //
+       @Meta(def = "", description = "If not empty, only the EXACT listed sources will be available for clients", info = "list is comma-separated (,) and values are surrounded by double quotes (\"); any double quote in the value must be backslash-escaped (with \\\")")
+       SERVER_WHITELIST, //
+       @Meta(def = "", description = "The subkeys that the server will allow, including the modes", info = "list is comma-separated (,) and values are surrounded by double quotes (\"); any double quote in the value must be backslash-escaped (with \\\")")
+       SERVER_ALLOWED_SUBKEYS, //
        @Meta(def = "$HOME/Books", description = "absolute path, $HOME variable supported, / is always accepted as dir separator", format = Format.DIRECTORY, info = "The directory where to store the library")
        LIBRARY_DIR, //
        @Meta(def = "false", description = "boolean", format = Format.BOOLEAN, info = "Show debug information on errors")
@@ -65,8 +75,7 @@ public enum Config {
        @Meta(description = "If the last update check was done at least that many days, check for updates at startup (-1 for 'no checks' -- default is 1 day)", format = Format.INT)
        UPDATE_INTERVAL, //
        @Meta(def = "", description = "", info = "Format is ((user(:pass)@)proxy:port), with ':' being system proxy and an empty String being no proxy")
-       USE_PROXY,
-       @Meta(description = "An API key required to create a token from FimFiction", format = Format.STRING)
+       USE_PROXY, @Meta(description = "An API key required to create a token from FimFiction", format = Format.STRING)
        LOGIN_FIMFICTION_APIKEY_CLIENT_ID, //
        @Meta(description = "An API key required to create a token from FimFiction", format = Format.PASSWORD)
        LOGIN_FIMFICTION_APIKEY_CLIENT_SECRET, //
index 640953972b3b56a108e8dfde37d4f31dc9ef0914..63b7642a769e5773d183ec93422367a59c0bbf8d 100644 (file)
@@ -33,6 +33,21 @@ USER_AGENT = Mozilla/5.0 (X11; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.
 DEFAULT_COVERS_DIR = $HOME/.fanfix/covers/
 # string (FORMAT: STRING) The default library to use (KEY:SERVER:PORT), or empty for the local library
 DEFAULT_LIBRARY = 
+# The port on which we can start the server
+# (FORMAT: INT) A valid port
+SERVER_PORT = 58365
+# The encryption key for the server (NOT including a subkey)
+# (FORMAT: PASSWORD) cannot contain the pipe character (|)
+SERVER_KEY = 
+# Allow write access to the clients by default (download story, move story...)
+# (FORMAT: BOOLEAN) 
+SERVER_RW = 
+# If not empty, only the EXACT listed sources will be available for clients
+# (FORMAT: STRING) list is comma-separated (,) and values are surrounded by double quotes ("); any double quote in the value must be backslash-escaped (with \")
+SERVER_WHITELIST = 
+# The subkeys that the server will allow, including the modes
+# (FORMAT: STRING) list is comma-separated (,) and values are surrounded by double quotes ("); any double quote in the value must be backslash-escaped (with \")
+SERVER_ALLOWED_SUBKEYS = 
 # absolute path, $HOME variable supported, / is always accepted as dir separator
 # (FORMAT: DIRECTORY) The directory where to store the library
 LIBRARY_DIR = $HOME/Books
index 363a59b268cb0ae1936b012131de1c1e5b00cb5c..1ebc3d5932a5f86ef8cf87b3a1143058ee172939 100644 (file)
@@ -34,8 +34,8 @@ HELP_SYNTAX = Valid options:\n\
 \t--set-author [id] [new author]: change the author of the given story\n\
 \t--set-reader [reader type]: set the reader type to CLI, TUI or GUI for \n\
 \t\tthis command\n\
-\t--server [key] [port]: start a remote server on this port\n\
-\t--stop-server [key] [port]: stop the remote server running on this port\n\
+\t--server: start the server mode (see config file for parameters)\n\
+\t--stop-server: stop the remote server running on this port\n\
 \t\tif any (key must be set to the same value)\n\
 \t--remote [key] [host] [port]: select this remote server to get \n\
 \t\t(or update or...) the stories from (key must be set to the \n\
index 1ce9f64f681d79e3508fe2962d080e7f8fb12219..e64651b3275d781953f4f8ba3ad9b66a993c1907 100644 (file)
@@ -28,8 +28,8 @@ HELP_SYNTAX = Options reconnues :\n\
 \t--set-title [id] [nouveau titre]: change le titre de l'histoire\n\
 \t--set-author [id] [nouvel auteur]: change l'auteur de l'histoire\n\
 \t--set-reader [reader type]: changer le type de lecteur pour la commande en cours sur CLI, TUI ou GUI\n\
-\t--server [key] [port]: démarrer un serveur d'histoires sur ce port\n\
-\t--stop-server [key] [port]: arrêter le serveur distant sur ce port (key doit avoir la même valeur) \n\
+\t--server: démarre le mode serveur (les paramètres sont dans le fichier de config)\n\
+\t--stop-server: arrêter le serveur distant sur ce port (key doit avoir la même valeur) \n\
 \t--remote [key] [host] [port]: contacter ce server au lieu de la librairie habituelle (key doit avoir la même valeur)\n\
 \t--help: afficher la liste des options disponibles\n\
 \t--version: retourne la version du programme\n\
index e35c57d146387ee3c582e08b398ba46dda792779..e7b98282b422786eb95a077056a987039984cbfd 100644 (file)
@@ -14,6 +14,7 @@ import be.nikiroo.fanfix.data.MetaData;
 import be.nikiroo.fanfix.data.Story;
 import be.nikiroo.utils.Image;
 import be.nikiroo.utils.Progress;
+import be.nikiroo.utils.Version;
 import be.nikiroo.utils.serial.server.ConnectActionClientObject;
 
 /**
@@ -27,11 +28,47 @@ public class RemoteLibrary extends BasicLibrary {
        private String host;
        private int port;
        private final String key;
+       private final String subkey;
+
+       // informative only (server will make the actual checks)
+       private boolean rw;
 
        // TODO: error handling is not up to par!
 
        /**
         * Create a {@link RemoteLibrary} linked to the given server.
+        * <p>
+        * Note that the key is structured:
+        * <tt><b><i>xxx</i></b>(|<b><i>yyy</i></b>|<b>wl</b>)(|<b>rw</b>)</tt>
+        * <p>
+        * Note that anything before the first pipe (<tt>|</tt>) character is
+        * considered to be the encryption key, anything after that character is
+        * called the subkey (including the other pipe characters and flags!).
+        * <p>
+        * This is important because the subkey (including the pipe characters and
+        * flags) must be present as-is in the server configuration file to be
+        * allowed.
+        * <ul>
+        * <li><b><i>xxx</i></b>: the encryption key used to communicate with the
+        * server</li>
+        * <li><b><i>yyy</i></b>: the secondary key</li>
+        * <li><b>rw</b>: flag to allow read and write access if it is not the
+        * default on this server</li>
+        * <li><b>wl</b>: flag to allow access to all the stories (bypassing the
+        * whitelist if it exists)</li>
+        * </ul>
+        * 
+        * Some examples:
+        * <ul>
+        * <li><b>my_key</b>: normal connection, will take the default server
+        * options</li>
+        * <li><b>my_key|agzyzz|wl</b>: will ask to bypass the white list (if it
+        * exists)</li>
+        * <li><b>my_key|agzyzz|rw</b>: will ask read-write access (if the default
+        * is read-only)</li>
+        * <li><b>my_key|agzyzz|wl|rw</b>: will ask both read-write access and white
+        * list bypass</li>
+        * </ul>
         * 
         * @param key
         *            the key that will allow us to exchange information with the
@@ -42,7 +79,19 @@ public class RemoteLibrary extends BasicLibrary {
         *            the port to contact it on
         */
        public RemoteLibrary(String key, String host, int port) {
-               this.key = key;
+               int index = -1;
+               if (key != null) {
+                       key.indexOf('|');
+               }
+
+               if (index >= 0) {
+                       this.key = key.substring(index + 1);
+                       this.subkey = key.substring(0, index);
+               } else {
+                       this.key = key;
+                       this.subkey = "";
+               }
+
                this.host = host;
                this.port = port;
        }
@@ -78,10 +127,14 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
-                                       Object rep = send(new Object[] { "PING" });
+                               public void action(Version serverVersion) throws Exception {
+                                       Object rep = send(new Object[] { subkey, "PING" });
 
-                                       if ("PONG".equals(rep)) {
+                                       if ("r/w".equals(rep)) {
+                                               rw = true;
+                                               result[0] = Status.READY;
+                                       } else if ("r/o".equals(rep)) {
+                                               rw = false;
                                                result[0] = Status.READY;
                                        } else {
                                                result[0] = Status.UNAUTHORIZED;
@@ -119,8 +172,8 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
-                                       Object rep = send(new Object[] { "GET_COVER", luid });
+                               public void action(Version serverVersion) throws Exception {
+                                       Object rep = send(new Object[] { subkey, "GET_COVER", luid });
                                        result[0] = (Image) rep;
                                }
 
@@ -170,9 +223,9 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
-                                       Object rep = send(new Object[] { "GET_CUSTOM_COVER", type,
-                                                       source });
+                               public void action(Version serverVersion) throws Exception {
+                                       Object rep = send(new Object[] { subkey,
+                                                       "GET_CUSTOM_COVER", type, source });
                                        result[0] = (Image) rep;
                                }
 
@@ -205,13 +258,13 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
+                               public void action(Version serverVersion) throws Exception {
                                        Progress pg = pgF;
                                        if (pg == null) {
                                                pg = new Progress();
                                        }
 
-                                       Object rep = send(new Object[] { "GET_STORY", luid });
+                                       Object rep = send(new Object[] { subkey, "GET_STORY", luid });
 
                                        MetaData meta = null;
                                        if (rep instanceof MetaData) {
@@ -270,13 +323,13 @@ public class RemoteLibrary extends BasicLibrary {
 
                new ConnectActionClientObject(host, port, key) {
                        @Override
-                       public void action() throws Exception {
+                       public void action(Version serverVersion) throws Exception {
                                Progress pg = pgF;
                                if (story.getMeta().getWords() <= Integer.MAX_VALUE) {
                                        pg.setMinMax(0, (int) story.getMeta().getWords());
                                }
 
-                               send(new Object[] { "SAVE_STORY", luid });
+                               send(new Object[] { subkey, "SAVE_STORY", luid });
 
                                List<Object> list = RemoteLibraryServer.breakStory(story);
                                for (Object obj : list) {
@@ -324,8 +377,8 @@ public class RemoteLibrary extends BasicLibrary {
 
                new ConnectActionClientObject(host, port, key) {
                        @Override
-                       public void action() throws Exception {
-                               send(new Object[] { "DELETE_STORY", luid });
+                       public void action(Version serverVersion) throws Exception {
+                               send(new Object[] { subkey, "DELETE_STORY", luid });
                        }
 
                        @Override
@@ -368,8 +421,8 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
-                                       send(new Object[] { "SET_COVER", type, value, luid });
+                               public void action(Version serverVersion) throws Exception {
+                                       send(new Object[] { subkey, "SET_COVER", type, value, luid });
                                }
 
                                @Override
@@ -417,10 +470,11 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
+                               public void action(Version serverVersion) throws Exception {
                                        Progress pg = pgF;
 
-                                       Object rep = send(new Object[] { "IMPORT", url.toString() });
+                                       Object rep = send(new Object[] { subkey, "IMPORT",
+                                                       url.toString() });
 
                                        while (true) {
                                                if (!RemoteLibraryServer.updateProgress(pg, rep)) {
@@ -473,11 +527,11 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
+                               public void action(Version serverVersion) throws Exception {
                                        Progress pg = pgF;
 
-                                       Object rep = send(new Object[] { "CHANGE_STA", luid,
-                                                       newSource, newTitle, newAuthor });
+                                       Object rep = send(new Object[] { subkey, "CHANGE_STA",
+                                                       luid, newSource, newTitle, newAuthor });
                                        while (true) {
                                                if (!RemoteLibraryServer.updateProgress(pg, rep)) {
                                                        break;
@@ -519,8 +573,8 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
-                                       send(new Object[] { "EXIT" });
+                               public void action(Version serverVersion) throws Exception {
+                                       send(new Object[] { subkey, "EXIT" });
                                }
 
                                @Override
@@ -611,13 +665,14 @@ public class RemoteLibrary extends BasicLibrary {
                try {
                        new ConnectActionClientObject(host, port, key) {
                                @Override
-                               public void action() throws Exception {
+                               public void action(Version serverVersion) throws Exception {
                                        Progress pg = pgF;
                                        if (pg == null) {
                                                pg = new Progress();
                                        }
 
-                                       Object rep = send(new Object[] { "GET_METADATA", luid });
+                                       Object rep = send(new Object[] { subkey, "GET_METADATA",
+                                                       luid });
 
                                        while (true) {
                                                if (!RemoteLibraryServer.updateProgress(pg, rep)) {
index 62548d678f2b04c6e59e8bb3e455a578e9f68f8c..f4075dd7bf5df4e9fb1d734bc8d47fdb95852b5e 100644 (file)
@@ -11,6 +11,7 @@ import java.util.Map;
 import javax.net.ssl.SSLException;
 
 import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix.bundles.Config;
 import be.nikiroo.fanfix.data.Chapter;
 import be.nikiroo.fanfix.data.MetaData;
 import be.nikiroo.fanfix.data.Paragraph;
@@ -18,6 +19,7 @@ import be.nikiroo.fanfix.data.Story;
 import be.nikiroo.utils.Progress;
 import be.nikiroo.utils.Progress.ProgressListener;
 import be.nikiroo.utils.StringUtils;
+import be.nikiroo.utils.Version;
 import be.nikiroo.utils.serial.server.ConnectActionServerObject;
 import be.nikiroo.utils.serial.server.ServerObject;
 
@@ -27,8 +29,12 @@ import be.nikiroo.utils.serial.server.ServerObject;
  * The available commands are given as arrays of objects (first item is the
  * command, the rest are the arguments).
  * <p>
+ * All the commands are always prefixed by the subkey (which can be EMPTY if
+ * none).
+ * <p>
  * <ul>
- * <li>PING: will return PONG if the key is accepted</li>
+ * <li>PING: will return the mode if the key is accepted (mode can be: "r/o" or
+ * "r/w")</li>
  * <li>GET_METADATA *: will return the metadata of all the stories in the
  * library (array)</li> *
  * <li>GET_METADATA [luid]: will return the metadata of the story of LUID luid</li>
@@ -54,10 +60,15 @@ import be.nikiroo.utils.serial.server.ServerObject;
 public class RemoteLibraryServer extends ServerObject {
        private Map<Long, String> commands = new HashMap<Long, String>();
        private Map<Long, Long> times = new HashMap<Long, Long>();
+       private Map<Long, Boolean> wls = new HashMap<Long, Boolean>();
+       private Map<Long, Boolean> rws = new HashMap<Long, Boolean>();
 
        /**
         * Create a new remote server (will not be active until
         * {@link RemoteLibraryServer#start()} is called).
+        * <p>
+        * Note: the key we use here is the encryption key (it must not contain a
+        * subkey).
         * 
         * @param key
         *            the key that will restrict access to this server
@@ -73,53 +84,109 @@ public class RemoteLibraryServer extends ServerObject {
        }
 
        @Override
-       protected Object onRequest(ConnectActionServerObject action, Object data,
-                       long id) throws Exception {
+       protected Object onRequest(ConnectActionServerObject action,
+                       Version clientVersion, Object data, long id) throws Exception {
                long start = new Date().getTime();
 
+               // defaults are positive (as previous versions without the feature)
+               boolean rw = true;
+               boolean wl = true;
+
+               String subkey = "";
                String command = "";
                Object[] args = new Object[0];
                if (data instanceof Object[]) {
                        Object[] dataArray = (Object[]) data;
                        if (dataArray.length > 0) {
-                               command = "" + dataArray[0];
+                               subkey = "" + dataArray[0];
+                       }
+                       if (dataArray.length > 1) {
+                               command = "" + dataArray[1];
+
+                               args = new Object[dataArray.length - 2];
+                               for (int i = 2; i < dataArray.length; i++) {
+                                       args[i - 2] = dataArray[i];
+                               }
+                       }
+               }
+
+               List<String> whitelist = Instance.getConfig().getList(
+                               Config.SERVER_WHITELIST);
+               if (whitelist == null) {
+                       whitelist = new ArrayList<String>();
+               }
+
+               if (whitelist.isEmpty()) {
+                       wl = false;
+               }
 
-                               args = new Object[dataArray.length - 1];
-                               for (int i = 1; i < dataArray.length; i++) {
-                                       args[i - 1] = dataArray[i];
+               rw = Instance.getConfig().getBoolean(Config.SERVER_RW, rw);
+               if (!subkey.isEmpty()) {
+                       List<String> allowed = Instance.getConfig().getList(
+                                       Config.SERVER_ALLOWED_SUBKEYS);
+                       if (allowed.contains(subkey)) {
+                               if ((subkey + "|").contains("|rw|")) {
+                                       rw = true;
+                               }
+                               if ((subkey + "|").contains("|wl|")) {
+                                       wl = false; // |wl| = bypass whitelist
                                }
                        }
                }
 
-               String trace = "[ " + command + "] ";
+               String mode = display(wl, rw);
+
+               String trace = mode + "[ " + command + "] ";
                for (Object arg : args) {
                        trace += arg + " ";
                }
                System.out.println(trace);
 
-               Object rep = doRequest(action, command, args);
+               Object rep = doRequest(action, command, args, rw, whitelist);
 
                commands.put(id, command);
+               wls.put(id, wl);
+               rws.put(id, rw);
                times.put(id, (new Date().getTime() - start));
 
                return rep;
        }
 
+       private String display(boolean whitelist, boolean rw) {
+               String mode = "";
+               if (!rw) {
+                       mode += "RO: ";
+               }
+               if (whitelist) {
+                       mode += "WL: ";
+               }
+
+               return mode;
+       }
+
        @Override
        protected void onRequestDone(long id, long bytesReceived, long bytesSent) {
+               boolean whitelist = wls.get(id);
+               boolean rw = rws.get(id);
+               wls.remove(id);
+               rws.remove(id);
+
                String rec = StringUtils.formatNumber(bytesReceived) + "b";
                String sent = StringUtils.formatNumber(bytesSent) + "b";
-               System.out.println(String.format("[>%s]: (%s sent, %s rec) in %d ms",
-                               commands.get(id), sent, rec, times.get(id)));
+               System.out.println(String.format("%s[>%s]: (%s sent, %s rec) in %d ms",
+                               display(whitelist, rw), commands.get(id), sent, rec,
+                               times.get(id)));
+
                commands.remove(id);
                times.remove(id);
        }
 
        private Object doRequest(ConnectActionServerObject action, String command,
-                       Object[] args) throws NoSuchFieldException, NoSuchMethodException,
+                       Object[] args, boolean rw, List<String> whitelist)
+                       throws NoSuchFieldException, NoSuchMethodException,
                        ClassNotFoundException, IOException {
                if ("PING".equals(command)) {
-                       return "PONG";
+                       return rw ? "r/w" : "r/o";
                } else if ("GET_METADATA".equals(command)) {
                        if ("*".equals(args[0])) {
                                Progress pg = createPgForwarder(action);
index 6929cac7141e865f9fea140482e062aa05c31d8b..cfd9cbef050ad9e0c9aeaa57877e5abf8d465b02 100644 (file)
@@ -4,7 +4,7 @@
  * files that you can read anywhere.
  * <p>
  * It has support for a {@link be.nikiroo.fanfix.library.BasicLibrary} system, 
- * too.
+ * too, and can even offer its services over the network.
  * 
  * @author niki
  */