use of org.eclipse.jetty.server.NCSARequestLog in project jetty.project by eclipse.
the class Runner method configure.
/**
* Configure a jetty instance and deploy the webapps presented as args
*
* @param args the command line arguments
* @throws Exception if unable to configure
*/
public void configure(String[] args) throws Exception {
// handle classpath bits first so we can initialize the log mechanism.
for (int i = 0; i < args.length; i++) {
if ("--lib".equals(args[i])) {
try (Resource lib = Resource.newResource(args[++i])) {
if (!lib.exists() || !lib.isDirectory())
usage("No such lib directory " + lib);
_classpath.addJars(lib);
}
} else if ("--jar".equals(args[i])) {
try (Resource jar = Resource.newResource(args[++i])) {
if (!jar.exists() || jar.isDirectory())
usage("No such jar " + jar);
_classpath.addPath(jar);
}
} else if ("--classes".equals(args[i])) {
try (Resource classes = Resource.newResource(args[++i])) {
if (!classes.exists() || !classes.isDirectory())
usage("No such classes directory " + classes);
_classpath.addPath(classes);
}
} else if (args[i].startsWith("--"))
i++;
}
initClassLoader();
LOG.info("Runner");
LOG.debug("Runner classpath {}", _classpath);
String contextPath = __defaultContextPath;
boolean contextPathSet = false;
int port = __defaultPort;
String host = null;
int stopPort = 0;
String stopKey = null;
boolean runnerServerInitialized = false;
for (int i = 0; i < args.length; i++) {
switch(args[i]) {
case "--port":
port = Integer.parseInt(args[++i]);
break;
case "--host":
host = args[++i];
break;
case "--stop-port":
stopPort = Integer.parseInt(args[++i]);
break;
case "--stop-key":
stopKey = args[++i];
break;
case "--log":
_logFile = args[++i];
break;
case "--out":
String outFile = args[++i];
PrintStream out = new PrintStream(new RolloverFileOutputStream(outFile, true, -1));
LOG.info("Redirecting stderr/stdout to " + outFile);
System.setErr(out);
System.setOut(out);
break;
case "--path":
contextPath = args[++i];
contextPathSet = true;
break;
case "--config":
if (_configFiles == null)
_configFiles = new ArrayList<>();
_configFiles.add(args[++i]);
break;
case "--lib":
//skip
++i;
break;
case "--jar":
//skip
++i;
break;
case "--classes":
//skip
++i;
break;
case "--stats":
_enableStats = true;
_statsPropFile = args[++i];
_statsPropFile = ("unsecure".equalsIgnoreCase(_statsPropFile) ? null : _statsPropFile);
break;
default:
if (// log handlers not registered, server maybe not created, etc
!runnerServerInitialized) {
if (// server not initialized yet
_server == null) {
// build the server
_server = new Server();
}
//apply jetty config files if there are any
if (_configFiles != null) {
for (String cfg : _configFiles) {
try (Resource resource = Resource.newResource(cfg)) {
XmlConfiguration xmlConfiguration = new XmlConfiguration(resource.getURL());
xmlConfiguration.configure(_server);
}
}
}
//check that everything got configured, and if not, make the handlers
HandlerCollection handlers = (HandlerCollection) _server.getChildHandlerByClass(HandlerCollection.class);
if (handlers == null) {
handlers = new HandlerCollection();
_server.setHandler(handlers);
}
//check if contexts already configured
_contexts = (ContextHandlerCollection) handlers.getChildHandlerByClass(ContextHandlerCollection.class);
if (_contexts == null) {
_contexts = new ContextHandlerCollection();
prependHandler(_contexts, handlers);
}
if (_enableStats) {
//if no stats handler already configured
if (handlers.getChildHandlerByClass(StatisticsHandler.class) == null) {
StatisticsHandler statsHandler = new StatisticsHandler();
Handler oldHandler = _server.getHandler();
statsHandler.setHandler(oldHandler);
_server.setHandler(statsHandler);
ServletContextHandler statsContext = new ServletContextHandler(_contexts, "/stats");
statsContext.addServlet(new ServletHolder(new StatisticsServlet()), "/");
statsContext.setSessionHandler(new SessionHandler());
if (_statsPropFile != null) {
HashLoginService loginService = new HashLoginService("StatsRealm", _statsPropFile);
Constraint constraint = new Constraint();
constraint.setName("Admin Only");
constraint.setRoles(new String[] { "admin" });
constraint.setAuthenticate(true);
ConstraintMapping cm = new ConstraintMapping();
cm.setConstraint(constraint);
cm.setPathSpec("/*");
ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
securityHandler.setLoginService(loginService);
securityHandler.setConstraintMappings(Collections.singletonList(cm));
securityHandler.setAuthenticator(new BasicAuthenticator());
statsContext.setSecurityHandler(securityHandler);
}
}
}
//ensure a DefaultHandler is present
if (handlers.getChildHandlerByClass(DefaultHandler.class) == null) {
handlers.addHandler(new DefaultHandler());
}
//ensure a log handler is present
_logHandler = (RequestLogHandler) handlers.getChildHandlerByClass(RequestLogHandler.class);
if (_logHandler == null) {
_logHandler = new RequestLogHandler();
handlers.addHandler(_logHandler);
}
//check a connector is configured to listen on
Connector[] connectors = _server.getConnectors();
if (connectors == null || connectors.length == 0) {
ServerConnector connector = new ServerConnector(_server);
connector.setPort(port);
if (host != null)
connector.setHost(host);
_server.addConnector(connector);
if (_enableStats)
connector.addBean(new ConnectionStatistics());
} else {
if (_enableStats) {
for (Connector connector : connectors) {
((AbstractConnector) connector).addBean(new ConnectionStatistics());
}
}
}
runnerServerInitialized = true;
}
// Create a context
try (Resource ctx = Resource.newResource(args[i])) {
if (!ctx.exists())
usage("Context '" + ctx + "' does not exist");
if (contextPathSet && !(contextPath.startsWith("/")))
contextPath = "/" + contextPath;
// Configure the context
if (!ctx.isDirectory() && ctx.toString().toLowerCase(Locale.ENGLISH).endsWith(".xml")) {
// It is a context config file
XmlConfiguration xmlConfiguration = new XmlConfiguration(ctx.getURL());
xmlConfiguration.getIdMap().put("Server", _server);
ContextHandler handler = (ContextHandler) xmlConfiguration.configure();
if (contextPathSet)
handler.setContextPath(contextPath);
_contexts.addHandler(handler);
String containerIncludeJarPattern = (String) handler.getAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN);
if (containerIncludeJarPattern == null)
containerIncludeJarPattern = __containerIncludeJarPattern;
else {
if (!containerIncludeJarPattern.contains(__containerIncludeJarPattern)) {
containerIncludeJarPattern = containerIncludeJarPattern + (StringUtil.isBlank(containerIncludeJarPattern) ? "" : "|") + __containerIncludeJarPattern;
}
}
handler.setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, containerIncludeJarPattern);
//check the configurations, if not explicitly set up, then configure all of them
if (handler instanceof WebAppContext) {
WebAppContext wac = (WebAppContext) handler;
if (wac.getConfigurationClasses() == null || wac.getConfigurationClasses().length == 0)
wac.setConfigurationClasses(__plusConfigurationClasses);
}
} else {
// assume it is a WAR file
WebAppContext webapp = new WebAppContext(_contexts, ctx.toString(), contextPath);
webapp.setConfigurationClasses(__plusConfigurationClasses);
webapp.setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, __containerIncludeJarPattern);
}
}
//reset
contextPathSet = false;
contextPath = __defaultContextPath;
break;
}
}
if (_server == null)
usage("No Contexts defined");
_server.setStopAtShutdown(true);
switch((stopPort > 0 ? 1 : 0) + (stopKey != null ? 2 : 0)) {
case 1:
usage("Must specify --stop-key when --stop-port is specified");
break;
case 2:
usage("Must specify --stop-port when --stop-key is specified");
break;
case 3:
ShutdownMonitor monitor = ShutdownMonitor.getInstance();
monitor.setPort(stopPort);
monitor.setKey(stopKey);
monitor.setExitVm(true);
break;
}
if (_logFile != null) {
NCSARequestLog requestLog = new NCSARequestLog(_logFile);
requestLog.setExtended(false);
_logHandler.setRequestLog(requestLog);
}
}
use of org.eclipse.jetty.server.NCSARequestLog in project jetty.project by eclipse.
the class ManyHandlers method main.
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
// create the handlers
Handler param = new ParamHandler();
HandlerWrapper wrapper = new WelcomeWrapHandler();
Handler hello = new HelloHandler();
Handler dft = new DefaultHandler();
RequestLogHandler requestLog = new RequestLogHandler();
// configure request logging
File requestLogFile = File.createTempFile("demo", "log");
NCSARequestLog ncsaLog = new NCSARequestLog(requestLogFile.getAbsolutePath());
requestLog.setRequestLog(ncsaLog);
// create the handler collections
HandlerCollection handlers = new HandlerCollection();
HandlerList list = new HandlerList();
// link them all together
wrapper.setHandler(hello);
list.setHandlers(new Handler[] { param, new GzipHandler(), dft });
handlers.setHandlers(new Handler[] { list, requestLog });
// Handler tree looks like the following
// <pre>
// Server
// + HandlerCollection
// . + HandlerList
// . | + param (ParamHandler)
// . | + wrapper (WelcomeWrapHandler)
// . | | \ hello (HelloHandler)
// . | \ dft (DefaultHandler)
// . \ requestLog (RequestLogHandler)
// </pre>
server.setHandler(handlers);
server.start();
server.join();
}
use of org.eclipse.jetty.server.NCSARequestLog in project hadoop by apache.
the class HttpRequestLog method getRequestLog.
public static RequestLog getRequestLog(String name) {
String lookup = serverToComponent.get(name);
if (lookup != null) {
name = lookup;
}
String loggerName = "http.requests." + name;
String appenderName = name + "requestlog";
Log logger = LogFactory.getLog(loggerName);
boolean isLog4JLogger;
;
try {
isLog4JLogger = logger instanceof Log4JLogger;
} catch (NoClassDefFoundError err) {
// In some dependent projects, log4j may not even be on the classpath at
// runtime, in which case the above instanceof check will throw
// NoClassDefFoundError.
LOG.debug("Could not load Log4JLogger class", err);
isLog4JLogger = false;
}
if (isLog4JLogger) {
Log4JLogger httpLog4JLog = (Log4JLogger) logger;
Logger httpLogger = httpLog4JLog.getLogger();
Appender appender = null;
try {
appender = httpLogger.getAppender(appenderName);
} catch (LogConfigurationException e) {
LOG.warn("Http request log for " + loggerName + " could not be created");
throw e;
}
if (appender == null) {
LOG.info("Http request log for " + loggerName + " is not defined");
return null;
}
if (appender instanceof HttpRequestLogAppender) {
HttpRequestLogAppender requestLogAppender = (HttpRequestLogAppender) appender;
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(requestLogAppender.getFilename());
requestLog.setRetainDays(requestLogAppender.getRetainDays());
return requestLog;
} else {
LOG.warn("Jetty request log for " + loggerName + " was of the wrong class");
return null;
}
} else {
LOG.warn("Jetty request log can only be enabled using Log4j");
return null;
}
}
use of org.eclipse.jetty.server.NCSARequestLog in project spark by perwendel.
the class EmbeddedServersTest method testAdd_whenConfigureRoutes_createsCustomServer.
@Test
public void testAdd_whenConfigureRoutes_createsCustomServer() throws Exception {
File requestLogDir = temporaryFolder.newFolder();
File requestLogFile = new File(requestLogDir, "request.log");
// Register custom server
EmbeddedServers.add(EmbeddedServers.Identifiers.JETTY, new EmbeddedJettyFactory(new JettyServerFactory() {
@Override
public Server create(int maxThreads, int minThreads, int threadTimeoutMillis) {
Server server = new Server();
server.setRequestLog(new NCSARequestLog(requestLogFile.getAbsolutePath()));
return server;
}
@Override
public Server create(ThreadPool threadPool) {
return null;
}
}));
Spark.get("/", (request, response) -> "OK");
Spark.awaitInitialization();
assertTrue(requestLogFile.exists());
}
use of org.eclipse.jetty.server.NCSARequestLog in project i2p.i2p by i2p.
the class RouterConsoleRunner method startConsole.
/**
* http://irc.codehaus.org/display/JETTY/Porting+to+jetty6
*
*<pre>
* Server
* HandlerCollection
* HostCheckHandler (extends GzipHandler)
* ContextHandlerCollection
* LocaleWebAppHandler (routerconsole)
* SessionHandler
* SecurityHandler
* ServletHandler
* servlets...
* WebAppContext (i2psnark)
* WebAppContext (i2ptunnel)
* WebAppContext (imagegen)
* WebAppContext (susidns)
* WebAppContext (susimail)
* WebAppContext (for each plugin with a .war)
* DefaultHandler
* RequestLogHandler (opt)
*</pre>
*
* Porting to Jetty 9:
*
* http://dev.eclipse.org/mhonarc/lists/jetty-dev/msg01952.html
* You are missing a few facts about Jetty 9.1 ...
* First, there are no longer any blocking connectors.
* Its all async / nio connectors now. (mainly because that's the direction that the servlet api 3.1 is taking)
*
* Next, there is only 1 connector. The ServerConnector.
* However, it takes 1 or more ConnectionFactory implementations to know how to handle the incoming connection.
* We have factories for HTTP (0.9 thru 1.1), SPDY, SSL-http, and SSL-npn so far.
* This list of factories will expand as the future of connectivity to web servers is ever growing (think HTTP/2)
*
* Use the embedded examples for help understanding this.
* http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java?id=jetty-9.1.0.RC0
*/
public void startConsole() {
File workDir = new SecureDirectory(_context.getTempDir(), "jetty-work");
boolean workDirRemoved = FileUtil.rmdir(workDir, false);
if (!workDirRemoved)
System.err.println("ERROR: Unable to remove Jetty temporary work directory");
boolean workDirCreated = workDir.mkdirs();
if (!workDirCreated)
System.err.println("ERROR: Unable to create Jetty temporary work directory");
// so Jetty can find WebAppConfiguration
System.setProperty("jetty.class.path", _context.getBaseDir() + "/lib/routerconsole.jar");
// FIXME
// http://dev.eclipse.org/mhonarc/lists/jetty-users/msg03487.html
// _server.setGracefulShutdown(1000);
// In Jetty 6, QTP was not concurrent, so we switched to
// ThreadPoolExecutor with a fixed-size queue, a set maxThreads,
// and a RejectedExecutionPolicy of CallerRuns.
// Unfortunately, CallerRuns causes lockups in Jetty NIO (ticket #1395)
// In addition, no flavor of TPE gives us what QTP does:
// - TPE direct handoff (which we were using) never queues.
// This doesn't provide any burst management when maxThreads is reached.
// CallerRuns was an attempt to work around that.
// - TPE unbounded queue does not adjust the number of threads.
// This doesn't provide automatic resource management.
// - TPE bounded queue does not add threads until the queue is full.
// This doesn't provide good responsiveness to even small bursts.
// QTP adds threads as soon as the queue is non-empty.
// QTP as of Jetty 7 uses concurrent.
// QTP unbounded queue is the default in Jetty.
// So switch back to QTP with a bounded queue.
//
// ref:
// http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
// https://wiki.eclipse.org/Jetty/Howto/High_Load
//
// try {
// ThreadPool ctp = new CustomThreadPoolExecutor();
// // Gone in Jetty 7
// //ctp.prestartAllCoreThreads();
// _server.setThreadPool(ctp);
// } catch (Throwable t) {
// class not found...
// System.out.println("INFO: Jetty concurrent ThreadPool unavailable, using QueuedThreadPool");
LinkedBlockingQueue<Runnable> lbq = new LinkedBlockingQueue<Runnable>(4 * MAX_THREADS);
// min and max threads will be reset below
QueuedThreadPool qtp = new QueuedThreadPool(MAX_THREADS, MIN_THREADS, MAX_IDLE_TIME, lbq);
qtp.setName(THREAD_NAME);
qtp.setDaemon(true);
_server = new Server(qtp);
// }
HandlerCollection hColl = new HandlerCollection();
ContextHandlerCollection chColl = new ContextHandlerCollection();
HostCheckHandler chCollWrapper = new HostCheckHandler(_context);
chCollWrapper.setHandler(chColl);
// gone in Jetty 7
// _server.addHandler(hColl);
_server.setHandler(hColl);
hColl.addHandler(chCollWrapper);
hColl.addHandler(new DefaultHandler());
String log = _context.getProperty("routerconsole.log");
if (log != null) {
File logFile = new File(log);
if (!logFile.isAbsolute())
logFile = new File(_context.getLogDir(), "logs/" + log);
try {
RequestLogHandler rhl = new RequestLogHandler();
rhl.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
hColl.addHandler(rhl);
} catch (Exception ioe) {
System.err.println("ERROR: Unable to create Jetty log: " + ioe);
}
}
boolean rewrite = false;
Properties props = webAppProperties();
if (props.isEmpty()) {
props.setProperty(PREFIX + ROUTERCONSOLE + ENABLED, "true");
rewrite = true;
}
// Get an absolute path with a trailing slash for the webapps dir
// We assume relative to the base install dir for backward compatibility
File app = new File(_webAppsDir);
if (!app.isAbsolute()) {
app = new File(_context.getBaseDir(), _webAppsDir);
try {
_webAppsDir = app.getCanonicalPath();
} catch (IOException ioe) {
}
}
if (!_webAppsDir.endsWith("/"))
_webAppsDir += '/';
Set<String> listenHosts = new HashSet<String>(8);
HandlerWrapper rootWebApp = null;
ServletHandler rootServletHandler = null;
List<Connector> connectors = new ArrayList<Connector>(4);
try {
int boundAddresses = 0;
SortedSet<String> addresses = Addresses.getAllAddresses();
boolean hasIPV4 = addresses.contains("0.0.0.0");
boolean hasIPV6 = addresses.contains("0:0:0:0:0:0:0:0");
// add standard listeners
int lport = 0;
if (_listenPort != null) {
try {
lport = Integer.parseInt(_listenPort);
} catch (NumberFormatException nfe) {
}
if (lport <= 0)
System.err.println("Bad routerconsole port " + _listenPort);
}
if (lport > 0) {
List<String> hosts = new ArrayList<String>(2);
StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
while (tok.hasMoreTokens()) {
String host = tok.nextToken().trim();
try {
// connectors are bad
if ((!hasIPV6) && Addresses.isIPv6Address(host))
throw new IOException("IPv6 addresses unsupported");
if ((!hasIPV4) && Addresses.isIPv4Address(host))
throw new IOException("IPv4 addresses unsupported");
ServerSocket testSock = null;
try {
// On Windows, this was passing and Jetty was still failing,
// possibly due to %scope_id ???
// https://issues.apache.org/jira/browse/ZOOKEEPER-667
// so do exactly what Jetty does in SelectChannelConnector.open()
testSock = new ServerSocket();
InetSocketAddress isa = new InetSocketAddress(host, 0);
testSock.bind(isa);
} finally {
if (testSock != null)
try {
testSock.close();
} catch (IOException ioe) {
}
}
HttpConfiguration httpConfig = new HttpConfiguration();
// number of acceptors, (default) number of selectors
ServerConnector lsnr = new ServerConnector(_server, 1, 0, new HttpConnectionFactory(httpConfig));
// lsnr.setUseDirectBuffers(false); // default true seems to be leaky
lsnr.setHost(host);
lsnr.setPort(lport);
// default 10 sec
lsnr.setIdleTimeout(90 * 1000);
// all with same name will use the same thread pool
lsnr.setName("ConsoleSocket");
// _server.addConnector(lsnr);
connectors.add(lsnr);
boundAddresses++;
hosts.add(host);
} catch (Exception ioe) {
System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ": " + ioe);
System.err.println("You may ignore this warning if the console is still available at http://localhost:" + _listenPort);
}
}
if (hosts.isEmpty()) {
_context.portMapper().register(PortMapper.SVC_CONSOLE, lport);
} else {
// put IPv4 first
Collections.sort(hosts, new HostComparator());
_context.portMapper().register(PortMapper.SVC_CONSOLE, hosts.get(0), lport);
// note that we could still fail in connector.start() below
listenHosts.addAll(hosts);
}
}
// add SSL listeners
int sslPort = 0;
if (_sslListenPort != null) {
try {
sslPort = Integer.parseInt(_sslListenPort);
} catch (NumberFormatException nfe) {
}
if (sslPort <= 0)
System.err.println("Bad routerconsole SSL port " + _sslListenPort);
}
if (sslPort > 0) {
File keyStore = new File(_context.getConfigDir(), "keystore/console.ks");
// Put the list of hosts together early, so we can put it in the selfsigned cert.
StringTokenizer tok = new StringTokenizer(_sslListenHost, " ,");
Set<String> altNames = new HashSet<String>(4);
while (tok.hasMoreTokens()) {
String s = tok.nextToken().trim();
if (!s.equals("0.0.0.0") && !s.equals("::") && !s.equals("0:0:0:0:0:0:0:0"))
altNames.add(s);
}
String allowed = _context.getProperty(PROP_ALLOWED_HOSTS);
if (allowed != null) {
tok = new StringTokenizer(allowed, " ,");
while (tok.hasMoreTokens()) {
altNames.add(tok.nextToken().trim());
}
}
if (verifyKeyStore(keyStore, altNames)) {
// the keystore path and password
SslContextFactory sslFactory = new SslContextFactory(keyStore.getAbsolutePath());
sslFactory.setKeyStorePassword(_context.getProperty(PROP_KEYSTORE_PASSWORD, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD));
// the X.509 cert password (if not present, verifyKeyStore() returned false)
sslFactory.setKeyManagerPassword(_context.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
sslFactory.addExcludeProtocols(I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.toArray(new String[I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.size()]));
sslFactory.addExcludeCipherSuites(I2PSSLSocketFactory.EXCLUDE_CIPHERS.toArray(new String[I2PSSLSocketFactory.EXCLUDE_CIPHERS.size()]));
List<String> hosts = new ArrayList<String>(2);
tok = new StringTokenizer(_sslListenHost, " ,");
while (tok.hasMoreTokens()) {
String host = tok.nextToken().trim();
// doing it this way means we don't have to escape an IPv6 host with []
try {
// connectors are bad
if ((!hasIPV6) && Addresses.isIPv6Address(host))
throw new IOException("IPv6 addresses unsupported");
if ((!hasIPV4) && Addresses.isIPv4Address(host))
throw new IOException("IPv4 addresses unsupported");
ServerSocket testSock = null;
try {
// see comments above
testSock = new ServerSocket();
InetSocketAddress isa = new InetSocketAddress(host, 0);
testSock.bind(isa);
} finally {
if (testSock != null)
try {
testSock.close();
} catch (IOException ioe) {
}
}
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSecureScheme("https");
httpConfig.setSecurePort(sslPort);
httpConfig.addCustomizer(new SecureRequestCustomizer());
// number of acceptors, (default) number of selectors
ServerConnector ssll = new ServerConnector(_server, 1, 0, new SslConnectionFactory(sslFactory, "http/1.1"), new HttpConnectionFactory(httpConfig));
// sssll.setUseDirectBuffers(false); // default true seems to be leaky
ssll.setHost(host);
ssll.setPort(sslPort);
// default 10 sec
ssll.setIdleTimeout(90 * 1000);
// all with same name will use the same thread pool
ssll.setName("ConsoleSocket");
// _server.addConnector(ssll);
connectors.add(ssll);
boundAddresses++;
hosts.add(host);
} catch (Exception e) {
System.err.println("Unable to bind routerconsole to " + host + " port " + sslPort + " for SSL: " + e);
if (SystemVersion.isGNU())
System.err.println("Probably because GNU classpath does not support Sun keystores");
System.err.println("You may ignore this warning if the console is still available at https://localhost:" + sslPort);
}
}
if (hosts.isEmpty()) {
_context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE, sslPort);
} else {
// put IPv4 first
Collections.sort(hosts, new HostComparator());
_context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE, hosts.get(0), sslPort);
// note that we could still fail in connector.start() below
listenHosts.addAll(hosts);
}
} else {
System.err.println("Unable to create or access keystore for SSL: " + keyStore.getAbsolutePath());
}
}
if (boundAddresses <= 0) {
System.err.println("Unable to bind routerconsole to any address on port " + _listenPort + (sslPort > 0 ? (" or SSL port " + sslPort) : ""));
return;
}
// Each address spawns a Connector and an Acceptor thread
// If the min is less than this, we have no thread for the handlers or the expiration thread.
qtp.setMinThreads(MIN_THREADS + (2 * boundAddresses));
qtp.setMaxThreads(MAX_THREADS + (2 * boundAddresses));
File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" + (_listenPort != null ? _listenPort : _sslListenPort));
tmpdir.mkdir();
rootServletHandler = new ServletHandler();
rootWebApp = new LocaleWebAppHandler(_context, "/", _webAppsDir + ROUTERCONSOLE + ".war", tmpdir, rootServletHandler);
try {
// Not sure who is supposed to call this, but unless we do,
// all the jsps die NPE, because JspFactory.getDefaultContext() returns null.
// We probably have to do this because we don't bundle the Jetty annotations jar and scanner.
// This is only with Tomcat 8, not with the Jetty (Eclipse) jsp impl.
// Got a clue from this ancient post for Tomcat 6:
// https://bz.apache.org/bugzilla/show_bug.cgi?id=39804
// see also apps/jetty/build.xml
Class.forName("org.eclipse.jetty.apache.jsp.JettyJasperInitializer");
} catch (ClassNotFoundException cnfe) {
System.err.println("Warning: JettyJasperInitializer not found");
}
WebAppContext wac = (WebAppContext) (rootWebApp.getHandler());
initialize(_context, wac);
WebAppStarter.setWebAppConfiguration(wac);
chColl.addHandler(rootWebApp);
} catch (Exception ioe) {
ioe.printStackTrace();
}
// fix up the allowed hosts set (see HostCheckHandler)
if (listenHosts.contains("0.0.0.0") || listenHosts.contains("::") || listenHosts.contains("0:0:0:0:0:0:0:0")) {
// empty set says all are valid
listenHosts.clear();
} else {
listenHosts.add("localhost");
listenHosts.add("127.0.0.1");
listenHosts.add("::1");
listenHosts.add("0:0:0:0:0:0:0:1");
String allowed = _context.getProperty(PROP_ALLOWED_HOSTS);
if (allowed != null) {
StringTokenizer tok = new StringTokenizer(allowed, " ,");
while (tok.hasMoreTokens()) {
listenHosts.add(tok.nextToken());
}
}
}
chCollWrapper.setListenHosts(listenHosts);
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=364936
// WARN:oejw.WebAppContext:Failed startup of context o.e.j.w.WebAppContext{/,jar:file:/.../webapps/routerconsole.war!/},/.../webapps/routerconsole.war
// java.lang.IllegalStateException: zip file closed
Resource.setDefaultUseCaches(false);
try {
// start does a mapContexts()
_server.start();
} catch (Throwable me) {
// NoClassFoundDefError from a webapp is a throwable, not an exception
System.err.println("Error starting the Router Console server: " + me);
me.printStackTrace();
}
if (_server.isRunning()) {
// Add and start the connectors one-by-one
boolean error = false;
for (Connector conn : connectors) {
try {
_server.addConnector(conn);
// start after adding so it gets the right thread pool
conn.start();
} catch (Throwable me) {
try {
_server.removeConnector(conn);
} catch (Throwable t) {
t.printStackTrace();
}
System.err.println("WARNING: Error starting " + conn + ": " + me);
me.printStackTrace();
error = true;
}
}
if (error) {
String port = (_listenPort != null) ? _listenPort : ((_sslListenPort != null) ? _sslListenPort : Integer.toString(DEFAULT_LISTEN_PORT));
System.err.println("WARNING: Error starting one or more listeners of the Router Console server.\n" + "If your console is still accessible at http://127.0.0.1:" + port + "/,\n" + "this may be a problem only with binding to the IPV6 address ::1.\n" + "If so, you may ignore this error, or remove the\n" + "\"::1,\" in the \"clientApp.0.args\" line of the clients.config file.");
}
}
// Start all the other webapps after the server is up,
// so things start faster.
// Jetty 6 starts the connector before the router console is ready
// This also prevents one webapp from breaking the whole thing
List<String> notStarted = new ArrayList<String>();
if (_server.isRunning()) {
File dir = new File(_webAppsDir);
File[] files = dir.listFiles(WAR_FILTER);
if (files != null) {
for (int i = 0; i < files.length; i++) {
String appName = files[i].getName();
appName = appName.substring(0, appName.lastIndexOf(".war"));
String enabled = props.getProperty(PREFIX + appName + ENABLED);
if (appName.equals("addressbook")) {
// addressbook.war is now empty, thread is started by SusiDNS
if (enabled != null) {
props.remove(PREFIX + "addressbook" + ENABLED);
rewrite = true;
}
} else if (!"false".equals(enabled)) {
try {
String path = files[i].getCanonicalPath();
WebAppStarter.startWebApp(_context, chColl, appName, path);
if (enabled == null) {
// do this so configclients.jsp knows about all apps from reading the config
props.setProperty(PREFIX + appName + ENABLED, "true");
rewrite = true;
}
} catch (Throwable t) {
System.err.println("ERROR: Failed to start " + appName + ' ' + t);
t.printStackTrace();
notStarted.add(appName);
}
} else {
notStarted.add(appName);
}
}
changeState(RUNNING);
if (_mgr != null)
_mgr.register(this);
}
} else {
System.err.println("ERROR: Router console did not start, not starting webapps");
changeState(START_FAILED);
}
if (rewrite)
storeWebAppProperties(_context, props);
if (rootServletHandler != null && notStarted.size() > 0) {
// map each not-started webapp to the error page
ServletHolder noWebApp = rootServletHandler.getServlet("net.i2p.router.web.jsp.nowebapp_jsp");
for (int i = 0; i < notStarted.size(); i++) {
// we want a new handler for each one since if the webapp is started we remove the handler???
try {
if (noWebApp != null) {
String path = '/' + notStarted.get(i);
// LocaleWebAppsHandler adds a .jsp
rootServletHandler.addServletWithMapping(noWebApp, path + ".jsp");
rootServletHandler.addServletWithMapping(noWebApp, path + "/*");
} else {
System.err.println("Can't find nowebapp.jsp?");
}
} catch (Throwable me) {
System.err.println(me);
me.printStackTrace();
}
}
}
Thread t = new I2PAppThread(new StatSummarizer(), "StatSummarizer", true);
t.setPriority(Thread.NORM_PRIORITY - 1);
t.start();
ConsoleUpdateManager um = new ConsoleUpdateManager(_context, _mgr, null);
um.start();
NewsManager nm = new NewsManager(_context, _mgr, null);
nm.startup();
if (PluginStarter.pluginsEnabled(_context)) {
t = new I2PAppThread(new PluginStarter(_context), "PluginStarter", true);
t.setPriority(Thread.NORM_PRIORITY - 1);
t.start();
}
// RouterAppManager registers its own hook
if (_mgr == null)
_context.addShutdownTask(new ServerShutdown());
ConfigServiceHandler.registerSignalHandler(_context);
}
Aggregations