📄 main.java
字号:
/*
* SSL-Explorer
*
* Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package com.sslexplorer.server;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Authenticator;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.net.ssl.TrustManager;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mortbay.http.HttpContext;
import org.mortbay.http.NCSARequestLog;
import org.mortbay.http.ResourceCache;
import org.mortbay.http.SocketListener;
import org.mortbay.http.handler.MsieSslHandler;
import org.mortbay.jetty.Server;
import org.mortbay.util.Password;
import org.tanukisoftware.wrapper.WrapperListener;
import org.tanukisoftware.wrapper.WrapperManager;
import com.sslexplorer.boot.BrowserLauncher;
import com.sslexplorer.boot.Context;
import com.sslexplorer.boot.ContextHolder;
import com.sslexplorer.boot.ContextListener;
import com.sslexplorer.boot.KeyStoreManager;
import com.sslexplorer.boot.PropertyDefinition;
import com.sslexplorer.boot.PropertyList;
import com.sslexplorer.boot.PropertyPreferences;
import com.sslexplorer.boot.RequestHandler;
import com.sslexplorer.boot.Util;
import com.sslexplorer.boot.VersionInfo;
import com.sslexplorer.boot.XMLPropertyDefinitionList;
import com.sslexplorer.boot.VersionInfo.Version;
import com.sslexplorer.server.jetty.CustomHttpContext;
import com.sslexplorer.server.jetty.CustomJsseListener;
import com.sslexplorer.server.jetty.CustomWebApplicationContext;
import com.sslexplorer.server.jetty.SecureHandler;
/**
* <p>
* Provides an entry point and a default environment for starting the
* SSL-Explorer service.
*
* <p>
* SSL-Explorer is primarily a standard Java web application. However, it
* requires a few additional services from the container that it is running in.
* This environment is called the {@link com.sslexplorer.boot.Context} (see this
* interfaces Javadoc for more information about this environment) and this
* class implements that interface.
*
* <p>
* This class currently provides an implementation that uses Jetty for the
* servlet / JSP container.
*
* <p>
* The <i>Context Properties</b> are stored using the Java Preferences API so
* will likely end up in the Windows register on Win32 platforms or XML files
* everywhere else.
*
* @see com.sslexplorer.boot.Context
* @author Brett Smith <brett@3sp.com>
*/
public class Main implements WrapperListener, Context {
// Private statics
private static File DB_DIR = new File("db");
private static File CONF_DIR = new File("conf");
private static File TMP_DIR = new File("tmp");
private static File LOG_DIR = new File("logs");
private static File appDir = new File("webapp/WEB-INF/applications");
static Log log;
static Preferences PREF;
// Private instance variables
private Server server;
private long startupStarted;
private HashMap resourceCaches;
private String hostAddress;
private static boolean useWrapper = false;
private boolean install;
private boolean gui;
private Throwable startupException;
private List listeners;
private CustomWebApplicationContext webappContext;
private CustomHttpContext httpContext;
private String jettyLog;
private int defaultPort;
private int actualPort;
private boolean useDevConfig;
private String hostname;
private ServerLock serverLock;
private Thread mainThread;
private Thread insecureThread;
private ThreadGroup threadGroup;
private XMLPropertyDefinitionList contextPropertyDefinitions;
private static Properties contextProperties = new Properties();
private List contextListeners;
private boolean shuttingDown;
/**
* Entry point
*
* @param args
* @throws Throwable
*/
public static void main(String[] args) throws Throwable {
// This is a hack to allow the Install4J installer to get the java
// runtime that will be used
if (args.length > 0 && args[0].equals("--jvmdir")) {
System.out.println(System.getProperty("java.home"));
System.exit(0);
}
useWrapper = System.getProperty("wrapper.key") != null;
final Main main = new Main();
ContextHolder.setContext(main);
if (useWrapper) {
WrapperManager.start(main, args);
} else {
Integer returnCode = main.start(args);
if (returnCode != null) {
if (main.gui) {
if (main.startupException == null) {
main.startupException = new Exception("An exit code of " + returnCode + " was returned.");
}
try {
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
} catch (Exception e) {
}
String mesg = main.startupException.getMessage() == null ? "No message supplied." : main.startupException
.getMessage();
StringBuffer buf = new StringBuffer();
int l = 0;
char ch = ' ';
for (int i = 0; i < mesg.length(); i++) {
ch = mesg.charAt(i);
if (l > 50 && ch == ' ') {
buf.append("\n");
l = 0;
} else {
if (ch == '\n') {
l = 0;
} else {
l++;
}
buf.append(ch);
}
}
mesg = buf.toString();
final String fMesg = mesg;
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(null, fMesg, "SSL-Explorer Startup Error", JOptionPane.ERROR_MESSAGE);
}
});
}
System.exit(returnCode.intValue());
} else {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
if (!main.shuttingDown) {
main.stop(0);
}
}
});
}
}
}
/*
* (non-Javadoc)
*
* @see org.tanukisoftware.wrapper.WrapperListener#start(java.lang.String[])
*/
public Integer start(String[] args) {
startupStarted = System.currentTimeMillis();
// Inform the wrapper the startup process may take a while
if (useWrapper) {
WrapperManager.signalStarting(60000);
}
// Parse the command line
Integer returnCode = parseCommandLine(args);
if (returnCode != null) {
if (returnCode.intValue() == 999) {
return null;
}
return returnCode;
}
//
resourceCaches = new HashMap();
contextListeners = new ArrayList();
loadSystemProperties();
initialiseLogging();
/*
* Migrate preferences.
*/
File newPrefDir = new File(ContextHolder.getContext().getConfDirectory(), "prefs");
PREF = PropertyPreferences.SYSTEM_ROOT;
try {
if (!newPrefDir.exists() && Preferences.systemRoot().node("/com").nodeExists("sslexplorer")) {
Preferences from = Preferences.systemRoot().node("/com/sslexplorer");
log.warn("Migrating preferences");
try {
copyNode(from.node("core") , PREF.node("core"));
from.node("core").removeNode();
copyNode(from.node("plugin") , PREF.node("plugin"));
from.node("plugin").removeNode();
copyNode(from.node("extensions") , PREF.node("extensions"));
from.node("extensions").removeNode();
copyNode(from.node("dbupgrader") , PREF.node("dbupgrader"));
from.node("dbupgrader").removeNode();
} catch (Exception e) {
log.error("Failed to migrate preferences.", e);
}
try {
from.flush();
} catch (BackingStoreException bse) {
log.error("Failed to flush old preferences");
}
try {
PREF.flush();
} catch (BackingStoreException bse) {
log.error("Failed to flush new preferences");
}
if (log.isInfoEnabled()) {
log.info("Flushing preferences");
}
}
} catch (BackingStoreException bse) {
log.error("Failed to migrate preferences.", bse);
}
//
try {
clearTemp();
try {
hostname = Inet4Address.getLocalHost().getCanonicalHostName();
hostAddress = Inet4Address.getLocalHost().getHostAddress();
} catch (Exception ex) {
// This should be fatal, we now rely on the hostname being
// available
throw new Exception("The host name or address on which this service is running could not "
+ "be determined. Check you network configuration. One possible cause is "
+ "a misconfigured 'hosts' file (e.g. on UNIX-like systems this would be "
+ "/etc/hosts, on Windows XP it would be " + "C:\\Windows\\System32\\Drivers\\Etc\\Hosts).");
}
File contextFile = new File(getConfDirectory(), "webserver.properties");
if (contextFile.exists()) {
contextProperties.load(new FileInputStream(contextFile));
}
// Display some information about the system we are running on
displaySystemInfo();
// Load the context property definitions
URL u = getClass().getResource("context-properties.xml");
if (u == null) {
throw new Exception("Could not find resource context-properties.xml");
}
contextPropertyDefinitions = new XMLPropertyDefinitionList(u);
// Configure any HTTP / HTTPS / SOCKS proxy servers
configureProxyServers();
String bind = getContextProperty("webServer.bindAddress");
PropertyList l = new PropertyList(bind.equals("") ? "0.0.0.0" : bind);
serverLock = new ServerLock((String) l.get(0));
if (serverLock.isLocked()) {
if (!isSetupMode()) {
if (serverLock.isSetup()) {
throw new Exception("The SSL-Explorer installation wizard is currently running. "
+ "Please shut this down by pointing your browser " + "to http://" + getHostname() + ":"
+ serverLock.getPort() + "/showShutdown.do before attempting to start the server again.");
} else {
throw new Exception("SSL-Explorer is already running.");
}
} else {
if (!serverLock.isSetup()) {
throw new Exception("SSL-Explorer is currently already running. "
+ "Please shut this down by pointing your browser " + "to https://" + getHostname() + ":"
+ serverLock.getPort() + "/showShutdown.do before attempting to start the server again.");
} else {
throw new Exception("The SSL-Explorer installation wizard is running..");
}
}
}
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
serverLock.stop();
}
});
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -