diff --git a/defaults/yacy.init b/defaults/yacy.init index 2aa3109e3..357dd83ca 100644 --- a/defaults/yacy.init +++ b/defaults/yacy.init @@ -13,6 +13,9 @@ port = 8090 # optinal ssl port (https port) the server should bind to port.ssl = 8443 +# port to listen for a shutdown signal ( -1 = disable use of a shutdown port, 8005 = recommended default ) +port.shutdown = -1 + # prefix for new default peer names peernameprefix=_anon diff --git a/htroot/SettingsAck_p.html b/htroot/SettingsAck_p.html index cb0c346d1..04c5be21d 100644 --- a/htroot/SettingsAck_p.html +++ b/htroot/SettingsAck_p.html @@ -194,7 +194,20 @@ ::

Debug/Analysis settings have been saved.

:: -

Referrer policy settings have been saved.

+

Referrer policy settings have been saved.

+ :: +

The ports are now configured as follows (active on next start).

+ + + + + + + + + + +
HTTP port #[port]#
HTTPS port #[port.ssl]#
Shutdown port #[port.shutdown]#
#(/info)#

#(needsRestart)# diff --git a/htroot/SettingsAck_p.java b/htroot/SettingsAck_p.java index 2ee5608bc..2380f5882 100644 --- a/htroot/SettingsAck_p.java +++ b/htroot/SettingsAck_p.java @@ -531,6 +531,22 @@ public class SettingsAck_p { return prop; } + // server port settings + if (post.containsKey("serverports")) { + int port = post.getInt("port", 8090); + if (port > 0) env.setConfig(SwitchboardConstants.SERVER_PORT, port); + int portssl = post.getInt("port.ssl", 8443); + if (portssl > 0) env.setConfig(SwitchboardConstants.SERVER_SSLPORT, portssl); + int portshutdown = post.getInt("port.shutdown", -1); + env.setConfig(SwitchboardConstants.SERVER_SHUTDOWNPORT, portshutdown); + prop.put("info_port", port); + prop.put("info_port.ssl", portssl); + prop.put("info_port.shutdown", portshutdown); + prop.put("needsRestart_referer", "Settings_p.html?page=ServerAccess"); + prop.put("info", "36"); + return prop; + } + // change https port if (post.containsKey("port.ssl")) { diff --git a/htroot/Settings_ServerAccess.inc b/htroot/Settings_ServerAccess.inc index a9476e8bb..82c004cd7 100644 --- a/htroot/Settings_ServerAccess.inc +++ b/htroot/Settings_ServerAccess.inc @@ -59,4 +59,28 @@ + +
Server Port Settings + + + + + + + + + + + + + + + + + + + +
Server port:This is the main port for all http communication. A change requires a restart.
Server ssl port:This is the port to connect via https. A change requires a restart.
Shutdown port:This is the local port on the loopback address (127.0.0.1 or :1) to listen for a shutdown signal to stop the YaCy server (-1 disables the shutdown port).A change requires a restart.
+
+ \ No newline at end of file diff --git a/htroot/Settings_p.java b/htroot/Settings_p.java index 39b05bc72..5630daa87 100644 --- a/htroot/Settings_p.java +++ b/htroot/Settings_p.java @@ -198,8 +198,9 @@ public final class Settings_p { prop.putHTML("crawler.file.maxFileSize",sb.getConfig("crawler.file.maxFileSize", "-1")); // http server info - prop.put("server.https",sb.getConfigBool("server.https", false)); - prop.put("server.https_port.ssl", sb.getConfig("port.ssl","8443")); + prop.put("server.https", sb.getConfigBool("server.https", false)); + prop.put("server.https_port.ssl", sb.getConfig(SwitchboardConstants.SERVER_SSLPORT,"8443")); + prop.put("port.shutdown", sb.getConfig(SwitchboardConstants.SERVER_SHUTDOWNPORT, "-1")); // debug/analysis prop.put("solrBinaryResponseChecked", env.getConfigBool(SwitchboardConstants.REMOTE_SOLR_BINARY_RESPONSE_ENABLED, diff --git a/source/net/yacy/search/Switchboard.java b/source/net/yacy/search/Switchboard.java index 13fedf146..a5ad92f2b 100644 --- a/source/net/yacy/search/Switchboard.java +++ b/source/net/yacy/search/Switchboard.java @@ -47,9 +47,13 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; +import java.net.InetAddress; import java.net.MalformedURLException; +import java.net.ServerSocket; +import java.net.Socket; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; @@ -208,6 +212,7 @@ import net.yacy.search.ranking.RankingProfile; import net.yacy.search.schema.CollectionConfiguration; import net.yacy.search.schema.CollectionSchema; import net.yacy.search.schema.WebgraphConfiguration; +import net.yacy.server.serverCore; import net.yacy.server.serverSwitch; import net.yacy.server.http.RobotsTxtConfig; import net.yacy.utils.CryptoLib; @@ -4036,7 +4041,71 @@ public final class Switchboard extends serverSwitch { return this.terminate; } + /** + * Wait until the shutdown semaphore is released. + * Optionally if config defines a shutdown port a thread is initalized, to + * listen on a defined shutdown port on the local loopback address. If a + * connection is made to the shutdown port an a text containig "shutdown" + * command, a shutdown is initiated. + * @return + * @throws InterruptedException + */ public boolean waitForShutdown() throws InterruptedException { + final int shutdownPort; + if ((shutdownPort = this.getConfigInt(SwitchboardConstants.SERVER_SHUTDOWNPORT, 0)) > 0) { + // init thread to listen to a shutdown port - to receive a shutdown signal + Thread shutdownThread = new Thread() { + @Override + public void run() { + ServerSocket ss = null; + try { + + shutdownloop: while (true) { + ss = new ServerSocket(shutdownPort, 0, InetAddress.getLoopbackAddress()); + Socket shSocket = ss.accept(); + + InputStream in = shSocket.getInputStream(); + BufferedReader inreader = new BufferedReader(new InputStreamReader(in)); + String cmd = inreader.readLine(); // read a input line to check for command shutdown + + // check for shutdown command, accept e.g. http://localhost:8009/shutdown connect with input line "GET /shutdown HTTP/1.1" + if (cmd != null && !cmd.isEmpty()) { + if (cmd.contains("shutdown")) { + if (cmd.contains("HTTP")) { // write a min. http response + OutputStream out = shSocket.getOutputStream(); + out.write(UTF8.getBytes("HTTP/1.1 200 OK")); + out.write(serverCore.CRLF); + out.close(); + } + ss.close(); + terminate("shutdown signal received on shutdown port"); + } else if (cmd.contains("restart")) { + if (cmd.contains("HTTP")) { // write a min. http response + OutputStream out = shSocket.getOutputStream(); + out.write(UTF8.getBytes("HTTP/1.1 200 OK")); + out.write(serverCore.CRLF); + out.close(); + } + ss.close(); + yacyRelease.restart(); + } + break shutdownloop; // important to get out of the loop + } + ss.close(); // we don't want to accept any additional input (abort/disconnect if not expected input) + } + } catch (IOException ex) { + } finally { + if (ss != null) { + try { + ss.close(); + } catch (IOException ex) { } + } + } + } + }; + shutdownThread.start(); + } + this.shutdownSync.acquire(); return this.terminate; } diff --git a/source/net/yacy/search/SwitchboardConstants.java b/source/net/yacy/search/SwitchboardConstants.java index 8e1892006..3df5c1a55 100644 --- a/source/net/yacy/search/SwitchboardConstants.java +++ b/source/net/yacy/search/SwitchboardConstants.java @@ -57,6 +57,7 @@ public final class SwitchboardConstants { // server settings public static final String SERVER_PORT = "port"; // port for the http server public static final String SERVER_SSLPORT = "port.ssl"; // port for https + public static final String SERVER_SHUTDOWNPORT = "port.shutdown"; // local port to listen for a shutdown signal (0 <= disabled) public static final String SERVER_STATICIP = "staticIP"; // static IP of http server public static final String PUBLIC_SEARCHPAGE = "publicSearchpage"; diff --git a/source/net/yacy/server/serverSwitch.java b/source/net/yacy/server/serverSwitch.java index fbcc982e5..83e158d1f 100644 --- a/source/net/yacy/server/serverSwitch.java +++ b/source/net/yacy/server/serverSwitch.java @@ -157,7 +157,7 @@ public class serverSwitch { @Deprecated public String myPublicIP() { // if a static IP was configured, we have to return it here ... - final String staticIP = getConfig("staticIP", ""); + final String staticIP = getConfig(SwitchboardConstants.SERVER_STATICIP, ""); if (staticIP.length() > 0) return staticIP; @@ -176,7 +176,7 @@ public class serverSwitch { */ public Set myPublicIPs() { // if a static IP was configured, we have to return it here ... - final String staticIP = getConfig("staticIP", ""); + final String staticIP = getConfig(SwitchboardConstants.SERVER_STATICIP, ""); if (staticIP.length() > 0) { HashSet h = new HashSet<>(); h.add(staticIP); @@ -254,7 +254,7 @@ public class serverSwitch { if(localPort != null) { return localPort; } - return getConfigInt("port", 8090); + return getConfigInt(SwitchboardConstants.SERVER_PORT, 8090); } // a logger for this switchboard