refactoring

pull/533/head
Michael Peter Christen 2 years ago
parent 23f1dc3741
commit d23dea2642

@ -39,7 +39,7 @@ import net.yacy.cora.util.ConcurrentLog;
import net.yacy.data.TransactionManager;
import net.yacy.data.UserDB;
import net.yacy.data.UserDB.AccessRight;
import net.yacy.http.Jetty9HttpServerImpl;
import net.yacy.http.YaCyHttpServer;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.server.serverObjects;
@ -80,7 +80,7 @@ public class ConfigAccounts_p {
env.setConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, sb.encodeDigestAuth(user, pw1));
env.setConfig(SwitchboardConstants.ADMIN_ACCOUNT_USER_NAME,user);
// make sure server accepts new credentials
Jetty9HttpServerImpl jhttpserver = (Jetty9HttpServerImpl)sb.getHttpServer();
YaCyHttpServer jhttpserver = (YaCyHttpServer)sb.getHttpServer();
if (!user.equals(oldusername)) jhttpserver.removeUser(oldusername);
jhttpserver.resetUser(user);
} else {

@ -25,7 +25,7 @@ import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.util.ConcurrentLog;
import net.yacy.data.UserDB;
import net.yacy.data.UserDB.AccessRight;
import net.yacy.http.Jetty9HttpServerImpl;
import net.yacy.http.YaCyHttpServer;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.server.serverObjects;
@ -151,7 +151,7 @@ public class ConfigUser_p {
} catch (final Exception e) {
ConcurrentLog.logException(e);
}
Jetty9HttpServerImpl jhttpserver = (Jetty9HttpServerImpl) sb.getHttpServer();
YaCyHttpServer jhttpserver = (YaCyHttpServer) sb.getHttpServer();
jhttpserver.resetUser(entry.getUserName());
} else {
prop.put("error", "1");
@ -162,7 +162,7 @@ public class ConfigUser_p {
prop.putHTML("username", username);
} else if (post.containsKey("delete")) {
sb.userDB.removeEntry(post.get("username"));
Jetty9HttpServerImpl jhttpserver = (Jetty9HttpServerImpl) sb.getHttpServer();
YaCyHttpServer jhttpserver = (YaCyHttpServer) sb.getHttpServer();
jhttpserver.removeUser(post.get("username"));
prop.put(serverObjects.ACTION_LOCATION, "ConfigAccountList_p.html"); // jump back to user list
}

@ -1,534 +0,0 @@
//
// Jetty9HttpServerImpl
// Copyright 2011 by Florian Richter
// First released 13.04.2011 at http://yacy.net
//
// $LastChangedDate$
// $LastChangedRevision$
// $LastChangedBy$
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program in the file lgpl21.txt
// If not, see <http://www.gnu.org/licenses/>.
//
package net.yacy.http;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.security.KeyStore;
import java.util.StringTokenizer;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.InetAccessHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.WebAppContext;
import net.yacy.cora.util.ConcurrentLog;
import net.yacy.http.servlets.YaCyDefaultServlet;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.utils.PKCS12Tool;
/**
* class to embedded Jetty 9 http server into YaCy
*/
public class Jetty9HttpServerImpl implements YaCyHttpServer {
private final Server server;
/**
* @param port TCP Port to listen for http requests
*/
public Jetty9HttpServerImpl(int port) {
Switchboard sb = Switchboard.getSwitchboard();
this.server = new Server();
int cores = ProcessorUtils.availableProcessors();
int acceptors = Math.max(1, Math.min(4, cores/2)); // original: Math.max(1, Math.min(4,cores/8));
HttpConnectionFactory hcf = new HttpConnectionFactory();
ServerConnector connector = new ServerConnector(this.server, null, null, null, acceptors, -1, hcf);
connector.setPort(port);
connector.setName("httpd:"+Integer.toString(port));
connector.setIdleTimeout(9000); // timout in ms when no bytes send / received
connector.setAcceptQueueSize(128);
this.server.addConnector(connector);
// add ssl/https connector
boolean useSSL = sb.getConfigBool("server.https", false);
if (useSSL) {
final SslContextFactory sslContextFactory = new SslContextFactory.Server();
final SSLContext sslContext = initSslContext(sb);
if (sslContext != null) {
int sslport = sb.getConfigInt(SwitchboardConstants.SERVER_SSLPORT, 8443);
sslContextFactory.setSslContext(sslContext);
// SSL HTTP Configuration
HttpConfiguration https_config = new HttpConfiguration();
https_config.addCustomizer(new SecureRequestCustomizer());
// SSL Connector
ServerConnector sslConnector = new ServerConnector(this.server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(https_config));
sslConnector.setPort(sslport);
sslConnector.setName("ssld:" + Integer.toString(sslport)); // name must start with ssl (for withSSL() to work correctly)
sslConnector.setIdleTimeout(9000); // timout in ms when no bytes send / received
this.server.addConnector(sslConnector);
ConcurrentLog.info("SERVER", "SSL support initialized successfully on port " + sslport);
}
}
YacyDomainHandler domainHandler = new YacyDomainHandler();
domainHandler.setAlternativeResolver(sb.peers);
// configure root context
WebAppContext htrootContext = new WebAppContext();
htrootContext.setContextPath("/");
String htrootpath = sb.appPath + "/" + sb.getConfig(SwitchboardConstants.HTROOT_PATH, SwitchboardConstants.HTROOT_PATH_DEFAULT);
ConcurrentLog.info("Jetty9HttpServerImpl", "htrootpath = " + htrootpath);
htrootContext.setErrorHandler(new YaCyErrorHandler()); // handler for custom error page
try {
htrootContext.setBaseResource(Resource.newResource(htrootpath));
// set web.xml to use
// make use of Jetty feature to define web.xml other as default WEB-INF/web.xml
// and to use a DefaultsDescriptor merged with a individual web.xml
// use defaults/web.xml as default and look in DATA/SETTINGS for local addition/changes
htrootContext.setDefaultsDescriptor(sb.appPath + "/defaults/web.xml");
Resource webxml = Resource.newResource(sb.dataPath + "/DATA/SETTINGS/web.xml");
if (webxml.exists()) {
htrootContext.setDescriptor(webxml.getName());
}
} catch (IOException ex) {
if (htrootContext.getBaseResource() == null) {
ConcurrentLog.severe("SERVER", "could not find directory: htroot ");
} else {
ConcurrentLog.warn("SERVER", "could not find: defaults/web.xml or DATA/SETTINGS/web.xml");
}
}
// as fundamental component leave this hardcoded, other servlets may be defined in web.xml only
ServletHolder sholder = new ServletHolder(YaCyDefaultServlet.class);
sholder.setInitParameter("resourceBase", htrootpath);
sholder.setAsyncSupported(true); // needed for YaCyQoSFilter
//sholder.setInitParameter("welcomeFile", "index.html"); // default is index.html, welcome.html
htrootContext.addServlet(sholder, "/*");
final GzipHandler gzipHandler = new GzipHandler();
/*
* Decompression of incoming requests body is required for index distribution
* APIs /yacy/transferRWI.html and /yacy/transferURL.html This was previously
* handled by a GZIPRequestWrapper in the YaCyDefaultServlet.
*/
gzipHandler.setInflateBufferSize(4096);
if (!sb.getConfigBool(SwitchboardConstants.SERVER_RESPONSE_COMPRESS_GZIP,
SwitchboardConstants.SERVER_RESPONSE_COMPRESS_GZIP_DEFAULT)) {
/* Gzip compression of responses can be disabled by user configuration */
gzipHandler.setExcludedMethods(HttpMethod.GET.asString(), HttpMethod.POST.asString());
}
htrootContext.setGzipHandler(gzipHandler);
// -----------------------------------------------------------------------------
// here we set and map the mandatory servlets, needed for typical YaCy operation
// to make sure they are available even if removed in individual web.xml
// additional, optional or individual servlets or servlet mappings can be set in web.xml
// in Jetty 9 servlet should be set only once
// therefore only the settings in web.xml is used
//add SolrSelectServlet
//htrootContext.addServlet(SolrSelectServlet.class, "/solr/select"); // uses the default core, collection1
//htrootContext.addServlet(SolrSelectServlet.class, "/solr/collection1/select"); // the same servlet, identifies the collection1 core using the path
//htrootContext.addServlet(SolrSelectServlet.class, "/solr/webgraph/select"); // the same servlet, identifies the webgraph core using the path
//htrootContext.addServlet(SolrServlet.class, "/solr/collection1/admin/luke");
//htrootContext.addServlet(SolrServlet.class, "/solr/webgraph/admin/luke");
// add proxy?url= servlet
//htrootContext.addServlet(YaCyProxyServlet.class,"/proxy.html");
// add GSA servlet
//htrootContext.addServlet(GSAsearchServlet.class,"/gsa/search");
// --- eof default servlet mappings --------------------------------------------
// define list of YaCy specific general handlers
HandlerList handlers = new HandlerList();
if (sb.getConfigBool(SwitchboardConstants.PROXY_TRANSPARENT_PROXY, false)) {
// Proxyhandlers are only needed if feature activated (save resources if not used)
ConcurrentLog.info("SERVER", "load Jetty handler for transparent proxy");
handlers.setHandlers(new Handler[]{new MonitorHandler(), domainHandler, new ProxyCacheHandler(), new ProxyHandler()});
} else {
handlers.setHandlers(new Handler[]{new MonitorHandler(), domainHandler});
}
// context handler for dispatcher and security (hint: dispatcher requires a context)
ContextHandler context = new ContextHandler();
context.setServer(this.server);
context.setContextPath("/");
context.setHandler(handlers);
context.setMaxFormContentSize(1024 * 1024 * 10); // allow 10MB, large forms may be required during crawl starts with long lists
org.eclipse.jetty.util.log.Logger log = Log.getRootLogger();
context.setLogger(log);
// make YaCy handlers (in context) and servlet context handlers available (both contain root context "/")
// logic: 1. YaCy handlers are called if request not handled (e.g. proxy) then servlets handle it
ContextHandlerCollection allrequesthandlers = new ContextHandlerCollection();
allrequesthandlers.setServer(this.server);
allrequesthandlers.addHandler(context);
allrequesthandlers.addHandler(htrootContext);
allrequesthandlers.addHandler(new DefaultHandler()); // if not handled by other handler
YaCyLoginService loginService = new YaCyLoginService();
// this is very important (as it is part of the user password hash)
// changes will ivalidate all current existing user-password-hashes (from userDB)
loginService.setName(sb.getConfig(SwitchboardConstants.ADMIN_REALM,"YaCy"));
Jetty9YaCySecurityHandler securityHandler = new Jetty9YaCySecurityHandler();
securityHandler.setLoginService(loginService);
htrootContext.setSecurityHandler(securityHandler);
// wrap all handlers
Handler crashHandler = new CrashProtectionHandler(this.server, allrequesthandlers);
// check server access restriction and add InetAccessHandler if restrictions are needed
// otherwise don't (to save performance)
final String white = sb.getConfig("serverClient", "*");
if (!white.equals("*")) { // full ip (allowed ranges 0-255 or prefix 10.0-255,0,0-100 or CIDR notation 192.168.1.0/24)
final StringTokenizer st = new StringTokenizer(white, ",");
final InetAccessHandler whiteListHandler;
if (white.contains("|")) {
/*
* At least one pattern includes a path definition : we must use the
* InetPathAccessHandler as InetAccessHandler doesn't support path patterns
*/
whiteListHandler = new InetPathAccessHandler();
} else {
whiteListHandler = new InetAccessHandler();
}
int i = 0;
while (st.hasMoreTokens()) {
final String pattern = st.nextToken();
try {
whiteListHandler.include(pattern);
} catch (final IllegalArgumentException nex) { // catch format exception on wrong ip address pattern
ConcurrentLog.severe("SERVER", "Server Access Settings - IP filter: " + nex.getMessage());
continue;
}
i++;
}
if (i > 0) {
final String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress();
whiteListHandler.include(loopbackAddress);
whiteListHandler.setHandler(crashHandler);
this.server.setHandler(whiteListHandler);
ConcurrentLog.info("SERVER","activated IP access restriction to: [" + loopbackAddress + "," + white +"]");
} else {
this.server.setHandler(crashHandler); // InetAccessHandler not needed
}
} else {
this.server.setHandler(crashHandler); // InetAccessHandler not needed
}
}
/**
* start http server
*/
@Override
public void startupServer() throws Exception {
// option to finish running requests on shutdown
// server.setGracefulShutdown(3000);
this.server.setStopAtShutdown(true);
this.server.start();
}
/**
* stop http server and wait for it
*/
@Override
public void stop() throws Exception {
this.server.stop();
this.server.join();
}
/**
* @return true if ssl/https connector is available
*/
@Override
public boolean withSSL() {
Connector[] clist = this.server.getConnectors();
for (Connector c:clist) {
if (c.getName().startsWith("ssl")) return true;
}
return false;
}
/**
* The port of actual running ssl connector
* @return the ssl/https port or -1 if not active
*/
@Override
public int getSslPort() {
Connector[] clist = this.server.getConnectors();
for (Connector c:clist) {
if (c.getName().startsWith("ssl")) {
int port =((ServerConnector)c).getLocalPort();
return port;
}
}
return -1;
}
/**
* reconnect with new port settings (after waiting milsec) - routine returns
* immediately
* checks http and ssl connector for new port settings
* @param milsec wait time
*/
@Override
public void reconnect(final int milsec) {
new Thread("Jetty8HttpServer.reconnect") {
@Override
public void run() {
if (milsec > 0) try {
Thread.sleep(milsec);
} catch (final InterruptedException e) {
ConcurrentLog.logException(e);
} catch (final Exception e) {
ConcurrentLog.logException(e);
}
try {
if (!Jetty9HttpServerImpl.this.server.isRunning() || Jetty9HttpServerImpl.this.server.isStopped()) {
Jetty9HttpServerImpl.this.server.start();
}
// reconnect with new settings (instead to stop/start server, just manipulate connectors
final Connector[] cons = Jetty9HttpServerImpl.this.server.getConnectors();
final int port = Switchboard.getSwitchboard().getLocalPort();
final int sslport = Switchboard.getSwitchboard().getConfigInt(SwitchboardConstants.SERVER_SSLPORT, 8443);
for (Connector con : cons) {
// check http connector
if (con.getName().startsWith("httpd") && ((ServerConnector)con).getPort() != port) {
((ServerConnector)con).close();
con.stop();
if (!con.isStopped()) {
ConcurrentLog.warn("SERVER", "Reconnect: Jetty Connector failed to stop");
}
((ServerConnector)con).setPort(port);
con.start();
ConcurrentLog.info("SERVER", "set new port for Jetty connector " + con.getName());
continue;
}
// check https connector
if (con.getName().startsWith("ssl") && ((ServerConnector)con).getPort() != sslport) {
((ServerConnector)con).close();
con.stop();
if (!con.isStopped()) {
ConcurrentLog.warn("SERVER", "Reconnect: Jetty Connector failed to stop");
}
((ServerConnector)con).setPort(sslport);
con.start();
ConcurrentLog.info("SERVER", "set new port for Jetty connector " + con.getName());
}
}
} catch (Exception ex) {
ConcurrentLog.logException(ex);
}
}
}.start();
}
/**
* forces loginservice to reload user credentials
* (used after setting new pwd in cfg file/db)
* @param username
*/
public void resetUser(String username) {
Jetty9YaCySecurityHandler hx = this.server.getChildHandlerByClass(Jetty9YaCySecurityHandler.class);
if (hx != null) {
YaCyLoginService loginservice = (YaCyLoginService) hx.getLoginService();
if (loginservice.removeUser(username)) { // remove old credential from cache
loginservice.loadUserInfo(username);
}
}
}
/**
* removes user from knowuser cache of loginservice
* @param username
*/
public void removeUser(String username) {
Jetty9YaCySecurityHandler hx = this.server.getChildHandlerByClass(Jetty9YaCySecurityHandler.class);
if (hx != null) {
YaCyLoginService loginservice = (YaCyLoginService) hx.getLoginService();
loginservice.removeUser(username);
}
}
/**
* get Jetty version
* @return version_string
*/
@Override
public String getVersion() {
return "Jetty " + Server.getVersion();
}
/**
* Init SSL Context from config settings
* @param sb Switchboard
* @return default or sslcontext according to config
*/
private SSLContext initSslContext(Switchboard sb) {
// getting the keystore file name
String keyStoreFileName = sb.getConfig("keyStore", "").trim();
// getting the keystore pwd
String keyStorePwd = sb.getConfig("keyStorePassword", "").trim();
// take a look if we have something to import
final String pkcs12ImportFile = sb.getConfig("pkcs12ImportFile", "").trim();
// if no keyStore and no import is defined, then set the default key
if (keyStoreFileName.isEmpty() && keyStorePwd.isEmpty() && pkcs12ImportFile.isEmpty()) {
keyStoreFileName = "defaults/freeworldKeystore";
keyStorePwd = "freeworld";
sb.setConfig("keyStore", keyStoreFileName);
sb.setConfig("keyStorePassword", keyStorePwd);
}
if (pkcs12ImportFile.length() > 0) {
ConcurrentLog.info("SERVER", "Import certificates from import file '" + pkcs12ImportFile + "'.");
try {
// getting the password
final String pkcs12ImportPwd = sb.getConfig("pkcs12ImportPwd", "").trim();
// creating tool to import cert
final PKCS12Tool pkcsTool = new PKCS12Tool(pkcs12ImportFile,pkcs12ImportPwd);
// creating a new keystore file
if (keyStoreFileName.isEmpty()) {
// using the default keystore name
keyStoreFileName = "DATA/SETTINGS/myPeerKeystore";
// creating an empty java keystore
final KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null,keyStorePwd.toCharArray());
try (
/* Automatically closed by this try-with-resources statement */
final FileOutputStream ksOut = new FileOutputStream(keyStoreFileName);
) {
ks.store(ksOut, keyStorePwd.toCharArray());
}
// storing path to keystore into config file
sb.setConfig("keyStore", keyStoreFileName);
}
// importing certificate
pkcsTool.importToJKS(keyStoreFileName, keyStorePwd);
// removing entries from config file
sb.setConfig("pkcs12ImportFile", "");
sb.setConfig("pkcs12ImportPwd", "");
// deleting original import file
// TODO: should we do this
} catch (final Exception e) {
ConcurrentLog.severe("SERVER", "Unable to import certificate from import file '" + pkcs12ImportFile + "'.",e);
}
} else if (keyStoreFileName.isEmpty()) return null;
// get the ssl context
try {
ConcurrentLog.info("SERVER","Initializing SSL support ...");
// creating a new keystore instance of type (java key store)
if (ConcurrentLog.isFine("SERVER")) ConcurrentLog.fine("SERVER", "Initializing keystore ...");
final KeyStore ks = KeyStore.getInstance("JKS");
// loading keystore data from file
if (ConcurrentLog.isFine("SERVER")) ConcurrentLog.fine("SERVER","Loading keystore file " + keyStoreFileName);
final FileInputStream stream = new FileInputStream(keyStoreFileName);
try {
ks.load(stream, keyStorePwd.toCharArray());
} finally {
try {
stream.close();
} catch(IOException ioe) {
ConcurrentLog.warn("SERVER", "Could not close input stream on file " + keyStoreFileName);
}
}
// creating a keystore factory
if (ConcurrentLog.isFine("SERVER")) ConcurrentLog.fine("SERVER","Initializing key manager factory ...");
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks,keyStorePwd.toCharArray());
// initializing the ssl context
if (ConcurrentLog.isFine("SERVER")) ConcurrentLog.fine("SERVER","Initializing SSL context ...");
final SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(kmf.getKeyManagers(), null, null);
return sslcontext;
} catch (final Exception e) {
final String errorMsg = "FATAL ERROR: Unable to initialize the SSL Socket factory. " + e.getMessage();
ConcurrentLog.severe("SERVER",errorMsg);
System.out.println(errorMsg);
return null;
}
}
@Override
public int getServerThreads() {
return this.server == null ? 0 : this.server.getThreadPool().getThreads() - this.server.getThreadPool().getIdleThreads();
}
@Override
public String toString() {
return this.server.dump() + "\n\n" + this.server.getState();
}
}

@ -1,22 +1,523 @@
package net.yacy.http;
/**
* Isolation of HttpServer
*
* Development Goal: allow for individual implementation of a HttpServer
* to provide the routines and entry points required by the
* YaCy servlets
*
* Implementation Jetty9HttpServerImpl.java
*/
public interface YaCyHttpServer {
abstract void startupServer() throws Exception;
abstract void stop() throws Exception;
abstract int getSslPort();
abstract boolean withSSL();
abstract void reconnect(int milsec);
abstract String getVersion();
abstract int getServerThreads();
}
//
// YaCyHttpServer
// Copyright 2011 by Florian Richter
// First released 13.04.2011 at http://yacy.net
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program in the file lgpl21.txt
// If not, see <http://www.gnu.org/licenses/>.
//
package net.yacy.http;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.security.KeyStore;
import java.util.StringTokenizer;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.InetAccessHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.WebAppContext;
import net.yacy.cora.util.ConcurrentLog;
import net.yacy.http.servlets.YaCyDefaultServlet;
import net.yacy.search.Switchboard;
import net.yacy.search.SwitchboardConstants;
import net.yacy.utils.PKCS12Tool;
/**
* class to embedded Jetty 9 http server into YaCy
*/
public class YaCyHttpServer {
private final Server server;
/**
* @param port TCP Port to listen for http requests
*/
public YaCyHttpServer(final int port) {
final Switchboard sb = Switchboard.getSwitchboard();
this.server = new Server();
final int cores = ProcessorUtils.availableProcessors();
final int acceptors = Math.max(1, Math.min(4, cores/2)); // original: Math.max(1, Math.min(4,cores/8));
final HttpConnectionFactory hcf = new HttpConnectionFactory();
final ServerConnector connector = new ServerConnector(this.server, null, null, null, acceptors, -1, hcf);
connector.setPort(port);
connector.setName("httpd:"+Integer.toString(port));
connector.setIdleTimeout(9000); // timout in ms when no bytes send / received
connector.setAcceptQueueSize(128);
this.server.addConnector(connector);
// add ssl/https connector
final boolean useSSL = sb.getConfigBool("server.https", false);
if (useSSL) {
final SslContextFactory sslContextFactory = new SslContextFactory.Server();
final SSLContext sslContext = initSslContext(sb);
if (sslContext != null) {
final int sslport = sb.getConfigInt(SwitchboardConstants.SERVER_SSLPORT, 8443);
sslContextFactory.setSslContext(sslContext);
// SSL HTTP Configuration
final HttpConfiguration https_config = new HttpConfiguration();
https_config.addCustomizer(new SecureRequestCustomizer());
// SSL Connector
final ServerConnector sslConnector = new ServerConnector(this.server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
new HttpConnectionFactory(https_config));
sslConnector.setPort(sslport);
sslConnector.setName("ssld:" + Integer.toString(sslport)); // name must start with ssl (for withSSL() to work correctly)
sslConnector.setIdleTimeout(9000); // timout in ms when no bytes send / received
this.server.addConnector(sslConnector);
ConcurrentLog.info("SERVER", "SSL support initialized successfully on port " + sslport);
}
}
final YacyDomainHandler domainHandler = new YacyDomainHandler();
domainHandler.setAlternativeResolver(sb.peers);
// configure root context
final WebAppContext htrootContext = new WebAppContext();
htrootContext.setContextPath("/");
final String htrootpath = sb.appPath + "/" + sb.getConfig(SwitchboardConstants.HTROOT_PATH, SwitchboardConstants.HTROOT_PATH_DEFAULT);
ConcurrentLog.info("Jetty9HttpServerImpl", "htrootpath = " + htrootpath);
htrootContext.setErrorHandler(new YaCyErrorHandler()); // handler for custom error page
try {
htrootContext.setBaseResource(Resource.newResource(htrootpath));
// set web.xml to use
// make use of Jetty feature to define web.xml other as default WEB-INF/web.xml
// and to use a DefaultsDescriptor merged with a individual web.xml
// use defaults/web.xml as default and look in DATA/SETTINGS for local addition/changes
htrootContext.setDefaultsDescriptor(sb.appPath + "/defaults/web.xml");
final Resource webxml = Resource.newResource(sb.dataPath + "/DATA/SETTINGS/web.xml");
if (webxml.exists()) {
htrootContext.setDescriptor(webxml.getName());
}
} catch (final IOException ex) {
if (htrootContext.getBaseResource() == null) {
ConcurrentLog.severe("SERVER", "could not find directory: htroot ");
} else {
ConcurrentLog.warn("SERVER", "could not find: defaults/web.xml or DATA/SETTINGS/web.xml");
}
}
// as fundamental component leave this hardcoded, other servlets may be defined in web.xml only
final ServletHolder sholder = new ServletHolder(YaCyDefaultServlet.class);
sholder.setInitParameter("resourceBase", htrootpath);
sholder.setAsyncSupported(true); // needed for YaCyQoSFilter
//sholder.setInitParameter("welcomeFile", "index.html"); // default is index.html, welcome.html
htrootContext.addServlet(sholder, "/*");
final GzipHandler gzipHandler = new GzipHandler();
/*
* Decompression of incoming requests body is required for index distribution
* APIs /yacy/transferRWI.html and /yacy/transferURL.html This was previously
* handled by a GZIPRequestWrapper in the YaCyDefaultServlet.
*/
gzipHandler.setInflateBufferSize(4096);
if (!sb.getConfigBool(SwitchboardConstants.SERVER_RESPONSE_COMPRESS_GZIP,
SwitchboardConstants.SERVER_RESPONSE_COMPRESS_GZIP_DEFAULT)) {
/* Gzip compression of responses can be disabled by user configuration */
gzipHandler.setExcludedMethods(HttpMethod.GET.asString(), HttpMethod.POST.asString());
}
htrootContext.setGzipHandler(gzipHandler);
// -----------------------------------------------------------------------------
// here we set and map the mandatory servlets, needed for typical YaCy operation
// to make sure they are available even if removed in individual web.xml
// additional, optional or individual servlets or servlet mappings can be set in web.xml
// in Jetty 9 servlet should be set only once
// therefore only the settings in web.xml is used
//add SolrSelectServlet
//htrootContext.addServlet(SolrSelectServlet.class, "/solr/select"); // uses the default core, collection1
//htrootContext.addServlet(SolrSelectServlet.class, "/solr/collection1/select"); // the same servlet, identifies the collection1 core using the path
//htrootContext.addServlet(SolrSelectServlet.class, "/solr/webgraph/select"); // the same servlet, identifies the webgraph core using the path
//htrootContext.addServlet(SolrServlet.class, "/solr/collection1/admin/luke");
//htrootContext.addServlet(SolrServlet.class, "/solr/webgraph/admin/luke");
// add proxy?url= servlet
//htrootContext.addServlet(YaCyProxyServlet.class,"/proxy.html");
// add GSA servlet
//htrootContext.addServlet(GSAsearchServlet.class,"/gsa/search");
// --- eof default servlet mappings --------------------------------------------
// define list of YaCy specific general handlers
final HandlerList handlers = new HandlerList();
if (sb.getConfigBool(SwitchboardConstants.PROXY_TRANSPARENT_PROXY, false)) {
// Proxyhandlers are only needed if feature activated (save resources if not used)
ConcurrentLog.info("SERVER", "load Jetty handler for transparent proxy");
handlers.setHandlers(new Handler[]{new MonitorHandler(), domainHandler, new ProxyCacheHandler(), new ProxyHandler()});
} else {
handlers.setHandlers(new Handler[]{new MonitorHandler(), domainHandler});
}
// context handler for dispatcher and security (hint: dispatcher requires a context)
final ContextHandler context = new ContextHandler();
context.setServer(this.server);
context.setContextPath("/");
context.setHandler(handlers);
context.setMaxFormContentSize(1024 * 1024 * 10); // allow 10MB, large forms may be required during crawl starts with long lists
final org.eclipse.jetty.util.log.Logger log = Log.getRootLogger();
context.setLogger(log);
// make YaCy handlers (in context) and servlet context handlers available (both contain root context "/")
// logic: 1. YaCy handlers are called if request not handled (e.g. proxy) then servlets handle it
final ContextHandlerCollection allrequesthandlers = new ContextHandlerCollection();
allrequesthandlers.setServer(this.server);
allrequesthandlers.addHandler(context);
allrequesthandlers.addHandler(htrootContext);
allrequesthandlers.addHandler(new DefaultHandler()); // if not handled by other handler
final YaCyLoginService loginService = new YaCyLoginService();
// this is very important (as it is part of the user password hash)
// changes will ivalidate all current existing user-password-hashes (from userDB)
loginService.setName(sb.getConfig(SwitchboardConstants.ADMIN_REALM,"YaCy"));
final YaCySecurityHandler securityHandler = new YaCySecurityHandler();
securityHandler.setLoginService(loginService);
htrootContext.setSecurityHandler(securityHandler);
// wrap all handlers
final Handler crashHandler = new CrashProtectionHandler(this.server, allrequesthandlers);
// check server access restriction and add InetAccessHandler if restrictions are needed
// otherwise don't (to save performance)
final String white = sb.getConfig("serverClient", "*");
if (!white.equals("*")) { // full ip (allowed ranges 0-255 or prefix 10.0-255,0,0-100 or CIDR notation 192.168.1.0/24)
final StringTokenizer st = new StringTokenizer(white, ",");
final InetAccessHandler whiteListHandler;
if (white.contains("|")) {
/*
* At least one pattern includes a path definition : we must use the
* InetPathAccessHandler as InetAccessHandler doesn't support path patterns
*/
whiteListHandler = new InetPathAccessHandler();
} else {
whiteListHandler = new InetAccessHandler();
}
int i = 0;
while (st.hasMoreTokens()) {
final String pattern = st.nextToken();
try {
whiteListHandler.include(pattern);
} catch (final IllegalArgumentException nex) { // catch format exception on wrong ip address pattern
ConcurrentLog.severe("SERVER", "Server Access Settings - IP filter: " + nex.getMessage());
continue;
}
i++;
}
if (i > 0) {
final String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress();
whiteListHandler.include(loopbackAddress);
whiteListHandler.setHandler(crashHandler);
this.server.setHandler(whiteListHandler);
ConcurrentLog.info("SERVER","activated IP access restriction to: [" + loopbackAddress + "," + white +"]");
} else {
this.server.setHandler(crashHandler); // InetAccessHandler not needed
}
} else {
this.server.setHandler(crashHandler); // InetAccessHandler not needed
}
}
/**
* start http server
*/
public void startupServer() throws Exception {
// option to finish running requests on shutdown
// server.setGracefulShutdown(3000);
this.server.setStopAtShutdown(true);
this.server.start();
}
/**
* stop http server and wait for it
*/
public void stop() throws Exception {
this.server.stop();
this.server.join();
}
/**
* @return true if ssl/https connector is available
*/
public boolean withSSL() {
final Connector[] clist = this.server.getConnectors();
for (final Connector c:clist) {
if (c.getName().startsWith("ssl")) return true;
}
return false;
}
/**
* The port of actual running ssl connector
* @return the ssl/https port or -1 if not active
*/
public int getSslPort() {
final Connector[] clist = this.server.getConnectors();
for (final Connector c:clist) {
if (c.getName().startsWith("ssl")) {
final int port =((ServerConnector)c).getLocalPort();
return port;
}
}
return -1;
}
/**
* reconnect with new port settings (after waiting milsec) - routine returns
* immediately
* checks http and ssl connector for new port settings
* @param milsec wait time
*/
public void reconnect(final int milsec) {
new Thread("Jetty8HttpServer.reconnect") {
@Override
public void run() {
if (milsec > 0) try {
Thread.sleep(milsec);
} catch (final InterruptedException e) {
ConcurrentLog.logException(e);
} catch (final Exception e) {
ConcurrentLog.logException(e);
}
try {
if (!YaCyHttpServer.this.server.isRunning() || YaCyHttpServer.this.server.isStopped()) {
YaCyHttpServer.this.server.start();
}
// reconnect with new settings (instead to stop/start server, just manipulate connectors
final Connector[] cons = YaCyHttpServer.this.server.getConnectors();
final int port = Switchboard.getSwitchboard().getLocalPort();
final int sslport = Switchboard.getSwitchboard().getConfigInt(SwitchboardConstants.SERVER_SSLPORT, 8443);
for (final Connector con : cons) {
// check http connector
if (con.getName().startsWith("httpd") && ((ServerConnector)con).getPort() != port) {
((ServerConnector)con).close();
con.stop();
if (!con.isStopped()) {
ConcurrentLog.warn("SERVER", "Reconnect: Jetty Connector failed to stop");
}
((ServerConnector)con).setPort(port);
con.start();
ConcurrentLog.info("SERVER", "set new port for Jetty connector " + con.getName());
continue;
}
// check https connector
if (con.getName().startsWith("ssl") && ((ServerConnector)con).getPort() != sslport) {
((ServerConnector)con).close();
con.stop();
if (!con.isStopped()) {
ConcurrentLog.warn("SERVER", "Reconnect: Jetty Connector failed to stop");
}
((ServerConnector)con).setPort(sslport);
con.start();
ConcurrentLog.info("SERVER", "set new port for Jetty connector " + con.getName());
}
}
} catch (final Exception ex) {
ConcurrentLog.logException(ex);
}
}
}.start();
}
/**
* forces loginservice to reload user credentials
* (used after setting new pwd in cfg file/db)
* @param username
*/
public void resetUser(final String username) {
final YaCySecurityHandler hx = this.server.getChildHandlerByClass(YaCySecurityHandler.class);
if (hx != null) {
final YaCyLoginService loginservice = (YaCyLoginService) hx.getLoginService();
if (loginservice.removeUser(username)) { // remove old credential from cache
loginservice.loadUserInfo(username);
}
}
}
/**
* removes user from knowuser cache of loginservice
* @param username
*/
public void removeUser(final String username) {
final YaCySecurityHandler hx = this.server.getChildHandlerByClass(YaCySecurityHandler.class);
if (hx != null) {
final YaCyLoginService loginservice = (YaCyLoginService) hx.getLoginService();
loginservice.removeUser(username);
}
}
/**
* get Jetty version
* @return version_string
*/
public String getVersion() {
return "Jetty " + Server.getVersion();
}
/**
* Init SSL Context from config settings
* @param sb Switchboard
* @return default or sslcontext according to config
*/
private SSLContext initSslContext(final Switchboard sb) {
// getting the keystore file name
String keyStoreFileName = sb.getConfig("keyStore", "").trim();
// getting the keystore pwd
String keyStorePwd = sb.getConfig("keyStorePassword", "").trim();
// take a look if we have something to import
final String pkcs12ImportFile = sb.getConfig("pkcs12ImportFile", "").trim();
// if no keyStore and no import is defined, then set the default key
if (keyStoreFileName.isEmpty() && keyStorePwd.isEmpty() && pkcs12ImportFile.isEmpty()) {
keyStoreFileName = "defaults/freeworldKeystore";
keyStorePwd = "freeworld";
sb.setConfig("keyStore", keyStoreFileName);
sb.setConfig("keyStorePassword", keyStorePwd);
}
if (pkcs12ImportFile.length() > 0) {
ConcurrentLog.info("SERVER", "Import certificates from import file '" + pkcs12ImportFile + "'.");
try {
// getting the password
final String pkcs12ImportPwd = sb.getConfig("pkcs12ImportPwd", "").trim();
// creating tool to import cert
final PKCS12Tool pkcsTool = new PKCS12Tool(pkcs12ImportFile,pkcs12ImportPwd);
// creating a new keystore file
if (keyStoreFileName.isEmpty()) {
// using the default keystore name
keyStoreFileName = "DATA/SETTINGS/myPeerKeystore";
// creating an empty java keystore
final KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null,keyStorePwd.toCharArray());
try (
/* Automatically closed by this try-with-resources statement */
final FileOutputStream ksOut = new FileOutputStream(keyStoreFileName);
) {
ks.store(ksOut, keyStorePwd.toCharArray());
}
// storing path to keystore into config file
sb.setConfig("keyStore", keyStoreFileName);
}
// importing certificate
pkcsTool.importToJKS(keyStoreFileName, keyStorePwd);
// removing entries from config file
sb.setConfig("pkcs12ImportFile", "");
sb.setConfig("pkcs12ImportPwd", "");
// deleting original import file
// TODO: should we do this
} catch (final Exception e) {
ConcurrentLog.severe("SERVER", "Unable to import certificate from import file '" + pkcs12ImportFile + "'.",e);
}
} else if (keyStoreFileName.isEmpty()) return null;
// get the ssl context
try {
ConcurrentLog.info("SERVER","Initializing SSL support ...");
// creating a new keystore instance of type (java key store)
if (ConcurrentLog.isFine("SERVER")) ConcurrentLog.fine("SERVER", "Initializing keystore ...");
final KeyStore ks = KeyStore.getInstance("JKS");
// loading keystore data from file
if (ConcurrentLog.isFine("SERVER")) ConcurrentLog.fine("SERVER","Loading keystore file " + keyStoreFileName);
final FileInputStream stream = new FileInputStream(keyStoreFileName);
try {
ks.load(stream, keyStorePwd.toCharArray());
} finally {
try {
stream.close();
} catch(final IOException ioe) {
ConcurrentLog.warn("SERVER", "Could not close input stream on file " + keyStoreFileName);
}
}
// creating a keystore factory
if (ConcurrentLog.isFine("SERVER")) ConcurrentLog.fine("SERVER","Initializing key manager factory ...");
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks,keyStorePwd.toCharArray());
// initializing the ssl context
if (ConcurrentLog.isFine("SERVER")) ConcurrentLog.fine("SERVER","Initializing SSL context ...");
final SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(kmf.getKeyManagers(), null, null);
return sslcontext;
} catch (final Exception e) {
final String errorMsg = "FATAL ERROR: Unable to initialize the SSL Socket factory. " + e.getMessage();
ConcurrentLog.severe("SERVER",errorMsg);
System.out.println(errorMsg);
return null;
}
}
public int getServerThreads() {
return this.server == null ? 0 : this.server.getThreadPool().getThreads() - this.server.getThreadPool().getIdleThreads();
}
@Override
public String toString() {
return this.server.dump() + "\n\n" + this.server.getState();
}
}

@ -44,7 +44,7 @@ import org.eclipse.jetty.server.Request;
* demands authentication for pages with _p. inside
* and updates AccessTracker
*/
public class Jetty9YaCySecurityHandler extends ConstraintSecurityHandler {
public class YaCySecurityHandler extends ConstraintSecurityHandler {
/**
* create the constraint for the given path

@ -71,7 +71,7 @@ public class serverSwitch {
private final ConcurrentMap<String, String> configRemoved;
private final NavigableMap<String, BusyThread> workerThreads;
private YaCyHttpServer httpserver; // implemented HttpServer
private ConcurrentMap<String, Integer> upnpPortMap = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Integer> upnpPortMap = new ConcurrentHashMap<>();
private boolean isConnectedViaUpnp;
public serverSwitch(final File dataPath, final File appPath, final String initPath, final String configPath) {
@ -105,9 +105,9 @@ public class serverSwitch {
}
// overwrite configs with values from environment variables that start with "yacy_"
Properties sysprops = System.getProperties();
final Properties sysprops = System.getProperties();
sysprops.forEach((key, value) -> {
String k = (String) key;
final String k = (String) key;
if (k.startsWith("yacy.")) {
this.configProps.put(k.substring(5), (String) value);
}
@ -115,7 +115,7 @@ public class serverSwitch {
// remove all values from config that do not appear in init
this.configRemoved = new ConcurrentHashMap<String, String>();
Iterator<String> i = this.configProps.keySet().iterator();
final Iterator<String> i = this.configProps.keySet().iterator();
String key;
while (i.hasNext()) {
key = i.next();
@ -133,15 +133,15 @@ public class serverSwitch {
// Read system properties and set all variables that have a prefix "yacy.".
// This will make it possible that settings can be overwritten with environment variables.
// Do this i.e. with "export YACY_PORT=8091 && ./startYACY.sh"
for (Map.Entry<Object, Object> entry: System.getProperties().entrySet()) {
String yacykey = (String) entry.getKey();
for (final Map.Entry<Object, Object> entry: System.getProperties().entrySet()) {
final String yacykey = (String) entry.getKey();
if (yacykey.startsWith("YACY_")) {
key = yacykey.substring(5).toLowerCase().replace('_', '.');
if (this.configProps.containsKey(key)) this.configProps.put(key, (String) entry.getValue());
}
}
for (Map.Entry<String, String> entry: System.getenv().entrySet()) {
String yacykey = entry.getKey();
for (final Map.Entry<String, String> entry: System.getenv().entrySet()) {
final String yacykey = entry.getKey();
if (yacykey.startsWith("YACY_")) {
key = yacykey.substring(5).toLowerCase().replace('_', '.');
if (this.configProps.containsKey(key)) this.configProps.put(key, entry.getValue());
@ -169,7 +169,7 @@ public class serverSwitch {
* get my public IP, either set statically or figure out dynamic This method
* is deprecated because there may be more than one public IPs of this peer,
* i.e. one IPv4 and one IPv6. Please use myPublicIPs() instead
*
*
* @return the public IP of this peer, if known
*/
public String myPublicIP() {
@ -188,26 +188,26 @@ public class serverSwitch {
/**
* Get all my public IPs. If there was a static IP assignment, only one,
* that IP is returned.
*
*
* @return a set of IPs which are supposed to be my own public IPs
*/
public Set<String> myPublicIPs() {
// if a static IP was configured, we have to return it here ...
final String staticIP = getConfig(SwitchboardConstants.SERVER_STATICIP, "");
if (staticIP.length() > 0) {
HashSet<String> h = new HashSet<>();
final HashSet<String> h = new HashSet<>();
h.add(staticIP);
return h;
}
Set<String> h = new LinkedHashSet<>();
for (InetAddress i : Domains.myPublicIPv6()) {
String s = i.getHostAddress();
final Set<String> h = new LinkedHashSet<>();
for (final InetAddress i : Domains.myPublicIPv6()) {
final String s = i.getHostAddress();
if (Seed.isProperIP(s))
h.add(Domains.chopZoneID(s));
}
for (InetAddress i : Domains.myPublicIPv4()) {
String s = i.getHostAddress();
for (final InetAddress i : Domains.myPublicIPv4()) {
final String s = i.getHostAddress();
if (Seed.isProperIP(s))
h.add(Domains.chopZoneID(s));
}
@ -218,19 +218,19 @@ public class serverSwitch {
* Gets public port. May differ from local port due to NATting. This method
* will eventually removed once nobody used IPv4 anymore, but until then we
* have to live with it.
*
*
* @param key
* original key from config (for example "port" or "port.ssl")
* @param dflt
* default value which will be used if no value is found
* @return the public port of this system on its IPv4 address
*
*
* @see #getLocalPort()
*/
public int getPublicPort(final String key, final int dflt) {
if (isConnectedViaUpnp && upnpPortMap.containsKey(key)) {
return upnpPortMap.get(key).intValue();
if (this.isConnectedViaUpnp && this.upnpPortMap.containsKey(key)) {
return this.upnpPortMap.get(key).intValue();
}
// TODO: add way of setting and retrieving port for manual NAT
@ -241,9 +241,9 @@ public class serverSwitch {
/**
* Wrapper for {@link #getConfigInt(String, int)} to have a more consistent
* API.
*
*
* Default value 8090 will be used if no value is found in configuration.
*
*
* @return the local http port of this system
* @see #getPublicPort(String, int)
*/
@ -262,7 +262,7 @@ public class serverSwitch {
/**
* add whole map of key-value pairs to config
*
*
* @param otherConfigs
*/
public void setConfig(final Map<String, String> otherConfigs) {
@ -300,25 +300,25 @@ public class serverSwitch {
}
public void setConfig(final String key, final String[] value) {
StringBuilder sb = new StringBuilder();
if (value != null) for (String s: value) sb.append(',').append(s);
final StringBuilder sb = new StringBuilder();
if (value != null) for (final String s: value) sb.append(',').append(s);
setConfig(key, sb.length() > 0 ? sb.substring(1) : "");
}
public void setConfig(final String key, Set<String> value) {
String[] a = new String[value.size()];
public void setConfig(final String key, final Set<String> value) {
final String[] a = new String[value.size()];
int c = 0;
for (String s: value) a[c++] = s;
for (final String s: value) a[c++] = s;
setConfig(key, a);
}
public void removeConfig(final String key) {
this.configProps.remove(key);
}
/**
* Gets a configuration parameter from the properties.
*
*
* @param key
* name of the configuration parameter
* @param dflt
@ -339,7 +339,7 @@ public class serverSwitch {
/**
* Gets a configuration parameter from the properties.
*
*
* @param key
* name of the configuration parameter
* @param dflt
@ -357,7 +357,7 @@ public class serverSwitch {
/**
* Gets a configuration parameter from the properties.
*
*
* @param key
* name of the configuration parameter
* @param dflt
@ -375,7 +375,7 @@ public class serverSwitch {
public boolean isConnectedViaUpnp() {
return isConnectedViaUpnp;
return this.isConnectedViaUpnp;
}
public void setConnectedViaUpnp(final boolean isConnectedViaUpnp) {
@ -383,22 +383,22 @@ public class serverSwitch {
this.isConnectedViaUpnp = isConnectedViaUpnp;
if (!isConnectedViaUpnp) {
upnpPortMap.clear();
this.upnpPortMap.clear();
}
}
public void setUpnpPorts(final String key, final int port) {
upnpPortMap.put(key, Integer.valueOf(port));
this.upnpPortMap.put(key, Integer.valueOf(port));
}
public void removeUpnpPort(final String key) {
upnpPortMap.remove(key);
this.upnpPortMap.remove(key);
}
/**
* Gets a configuration parameter from the properties.
*
*
* @param key
* name of the configuration parameter
* @param dflt
@ -418,7 +418,7 @@ public class serverSwitch {
/**
* Gets a configuration parameter from the properties.
*
*
* @param key
* name of the configuration parameter
* @param dflt
@ -438,7 +438,7 @@ public class serverSwitch {
*/
public String[] getConfigArray(final String key, final String dflt) {
return CommonPattern.COMMA.split(this.getConfig(key, dflt));
}
}
/**
* get a configuration parameter set
@ -446,14 +446,14 @@ public class serverSwitch {
* @return a set of strings which had been separated by comma in the setting
*/
public Set<String> getConfigSet(final String key) {
Set<String> h = new LinkedHashSet<>();
final Set<String> h = new LinkedHashSet<>();
for (String s: getConfigArray(key, "")) {s = s.trim(); if (s.length() > 0) h.add(s.trim());}
return h;
}
/**
* Create a File instance for a configuration setting specifying a path.
*
*
* @param key
* config key
* @param dflt
@ -470,7 +470,7 @@ public class serverSwitch {
/**
* return file at path from config entry "key", or fallback to default dflt
*
*
* @param key
* @param dflt
* @return
@ -479,7 +479,7 @@ public class serverSwitch {
return getFileByPath(key, dflt, this.appPath);
}
private File getFileByPath(String key, String dflt, File prefix) {
private File getFileByPath(final String key, final String dflt, final File prefix) {
final String path = getConfig(key, dflt).replace('\\', '/');
final File f = new File(path);
return (f.isAbsolute() ? new File(f.getAbsolutePath()) : new File(
@ -494,7 +494,7 @@ public class serverSwitch {
* write the changes to permanent storage (File)
*/
private void saveConfig() {
ConcurrentMap<String, String> configPropsCopy = new ConcurrentHashMap<String, String>();
final ConcurrentMap<String, String> configPropsCopy = new ConcurrentHashMap<String, String>();
configPropsCopy.putAll(this.configProps); // avoid concurrency problems
FileUtils.saveMap(this.configFile, configPropsCopy, this.configComment);
}
@ -502,13 +502,13 @@ public class serverSwitch {
/**
* Gets configuration parameters which have been removed during
* initialization.
*
*
* @return contains parameter name as key and parameter value as value
*/
public ConcurrentMap<String, String> getRemoved() {
return this.configRemoved;
}
/**
* @return the default configuration properties loaded form the
* defaults/yacy.init file. The properties are empty when the file can
@ -519,9 +519,9 @@ public class serverSwitch {
try (final FileInputStream fis = new FileInputStream(new File(this.appPath, "defaults/yacy.init"))) {
config.load(fis);
} catch (final FileNotFoundException e) {
log.severe("Could not find default configuration file defaults/yacy.init.");
this.log.severe("Could not find default configuration file defaults/yacy.init.");
} catch (final IOException | IllegalArgumentException e) {
log.severe("Could not read configuration file.");
this.log.severe("Could not read configuration file.");
}
return config;
}
@ -671,7 +671,7 @@ public class serverSwitch {
/**
* Retrieve text data (e. g. config file) from file file may be an url or a
* filename with path relative to rootPath parameter
*
*
* @param file
* url or filename
* @param rootPath
@ -690,7 +690,7 @@ public class serverSwitch {
final RequestHeader reqHeader = new RequestHeader();
reqHeader.put(HeaderFramework.USER_AGENT, ClientIdentification.yacyInternetCrawlerAgent.userAgent);
client.setHeader(reqHeader.entrySet());
byte[] data = client.GETbytes(uri,
final byte[] data = client.GETbytes(uri,
getConfig(SwitchboardConstants.ADMIN_ACCOUNT_USER_NAME, "admin"),
getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, ""), false);
if (data == null || data.length == 0) {
@ -724,10 +724,10 @@ public class serverSwitch {
/**
* set/remember jetty server
*
*
* @param jettyserver
*/
public void setHttpServer(YaCyHttpServer jettyserver) {
public void setHttpServer(final YaCyHttpServer jettyserver) {
this.httpserver = jettyserver;
}

@ -69,7 +69,6 @@ import net.yacy.data.TransactionManager;
import net.yacy.data.Translator;
import net.yacy.gui.YaCyApp;
import net.yacy.gui.framework.Browser;
import net.yacy.http.Jetty9HttpServerImpl;
import net.yacy.http.YaCyHttpServer;
import net.yacy.kelondro.util.FileUtils;
import net.yacy.kelondro.util.Formatter;
@ -293,7 +292,7 @@ public final class yacy {
try {
// start http server
YaCyHttpServer httpServer;
httpServer = new Jetty9HttpServerImpl(port);
httpServer = new YaCyHttpServer(port);
httpServer.startupServer();
sb.setHttpServer(httpServer);
// TODO: this has no effect on Jetty (but needed to reflect configured value and limit is still used)
@ -628,7 +627,7 @@ public final class yacy {
*
* @param dataHome data directory
*/
static private void preReadSavedConfigandInit(File dataHome) {
static private void preReadSavedConfigandInit(final File dataHome) {
final File lockFile = new File(dataHome, "DATA/yacy.running");
final String conf = "DATA/SETTINGS/yacy.conf";
@ -688,7 +687,7 @@ public final class yacy {
* @param args
* Given arguments from the command line.
*/
public static void main(String args[]) {
public static void main(final String args[]) {
try {
// check assertion status

Loading…
Cancel
Save