📄 serve.java
字号:
if (argn != argc)
usage();
// log and error stream manipulation
// TODO add log rotation feature, it can be done as plug-in
PrintStream printstream = System.err;
if (arguments.get(ARG_OUT) != null)
printstream = (PrintStream) arguments.get(ARG_OUT);
else {
String logEncoding = System.getProperty(DEF_LOGENCODING);
try {
File logFile = new File(workPath, "AWS-" + System.currentTimeMillis() + ".log");
if (logEncoding != null)
printstream = new PrintStream(new FileOutputStream(logFile), true, logEncoding); /* 1.4 */
else
printstream = new PrintStream(new FileOutputStream(logFile), true);
} catch (IOException e) {
System.err.println("I/O problem at setting a log stream " + e);
}
}
if (arguments.get(ARG_ERR) != null) {
System.setErr((PrintStream) arguments.get(ARG_ERR));
} else {
System.setErr(printstream);
}
if (messages != null)
System.err.println(messages);
/**
* format path mapping from=givenpath;dir=realpath
*/
PathTreeDictionary mappingtable = new PathTreeDictionary();
if (arguments.get(ARG_ALIASES) != null) {
File file = new File((String) arguments.get(ARG_ALIASES));
if (file.isAbsolute() == false)
file = new File(workPath, file.getPath());
if (file.exists() && file.canRead()) {
try {
// DataInputStream in = new DataInputStream(
// new FileInputStream(file));
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
do {
String mappingstr = in.readLine(); // no arguments in non ASCII encoding allowed
if (mappingstr == null)
break;
StringTokenizer maptokenzr = new StringTokenizer(mappingstr, "=;");
if (maptokenzr.hasMoreTokens()) {
if (maptokenzr.nextToken("=").equalsIgnoreCase("from")) {
if (maptokenzr.hasMoreTokens()) {
String srcpath = maptokenzr.nextToken("=;");
if (maptokenzr.hasMoreTokens()
&& maptokenzr.nextToken(";=").equalsIgnoreCase("dir"))
try {
if (maptokenzr.hasMoreTokens()) {
File mapFile = new File(maptokenzr.nextToken());
if (mapFile.isAbsolute() == false)
mapFile = new File(workPath, mapFile.getPath());
mappingtable.put(srcpath, mapFile);
}
} catch (NullPointerException e) {
}
}
}
}
} while (true);
} catch (IOException e) {
System.err.println("Problem reading aliases file: " + arguments.get(ARG_ALIASES) + "/" + e);
}
} else
System.err.println("File " + file + " (" + arguments.get(ARG_ALIASES)
+ ") doesn't exist or not readable.");
}
// format realmname=path,user:password,,,,
// TODO consider to add a role, like realmname=path,user:password[:role]
PathTreeDictionary realms = new PathTreeDictionary();
if (arguments.get(ARG_REALMS) != null) {
try {
File file = new File((String) arguments.get(ARG_REALMS));
if (file.isAbsolute() == false)
file = new File(workPath, file.getPath());
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
do {
String realmstr = in.readLine();
if (realmstr == null)
break;
StringTokenizer rt = new StringTokenizer(realmstr, "=,:");
if (rt.hasMoreTokens()) {
String realmname = null;
realmname = rt.nextToken();
if (rt.hasMoreTokens()) {
String realmPath = null;
realmPath = rt.nextToken();
if (rt.hasMoreTokens()) {
String user = rt.nextToken();
if (rt.hasMoreTokens()) {
String password = rt.nextToken();
BasicAuthRealm realm = null;
Object o[] = realms.get(realmPath);
if (o != null && o[0] != null)
realm = (BasicAuthRealm) o[0];
else {
realm = new BasicAuthRealm(realmname);
realms.put(realmPath, realm);
}
realm.put(user, password);
}
}
}
}
} while (true);
} catch (IOException ioe) {
System.err.println("I/O problem in reading realms file " + arguments.get(ARG_REALMS) + ": " + ioe);
}
}
// Create the server.
serve = new Serve(arguments, printstream);
// can use log(.. after this point
File tempFile = arguments.get(ARG_SERVLETS) == null ? null : new File((String) arguments.get(ARG_SERVLETS));
if (tempFile != null && tempFile.isAbsolute() == false)
tempFile = new File(workPath, tempFile.getPath());
final File servFile = tempFile;
serve.setMappingTable(mappingtable);
serve.setRealms(realms);
new Thread(new Runnable() {
public void run() {
serve.readServlets(servFile);
}
}).start();
// And add the standard Servlets.
String throttles = (String) arguments.get(ARG_THROTTLES);
if (throttles == null)
serve.addDefaultServlets((String) arguments.get(ARG_CGI_PATH));
else
try {
serve.addDefaultServlets((String) arguments.get(ARG_CGI_PATH), throttles);
} catch (IOException e) {
serve.log("Problem reading throttles file: " + e, e);
System.exit(1);
}
serve.addWarDeployer((String) arguments.get(ARG_WAR), throttles);
// And run.
int code = serve.serve();
try {
Runtime.getRuntime().removeShutdownHook(sdHook);
serve.destroyAllServlets();
} catch (IllegalStateException ise) {
}
serve.killAliveThreads();
System.exit(code);
}
private static void usage() {
System.out.println(Identification.serverName + " " + Identification.serverVersion + "\n" + "Usage: "
+ progName + " [-p port] [-s servletpropertiesfile] [-a aliasmappingfile]\n"
+ " [-b bind address] [-k backlog] [-l[a][r][f access_log_fmt]]\n"
+ " [-c cgi-bin-dir] [-m max_active_session]\n"
+ " [-sp] [-j jsp_servlet_class] [-w war_deployment_module_class]\n"
+ " [-nka] [-kat timeout_in_secs] [-mka max_times_connection_use]\n"
+ " [-e [-]duration_in_minutes] [-nohup] [-z max_threadpool_size]\n"
+ " [-err [class_name?PrintStream]] [-out [class_name?PrintStream]]\n"
+ " [-socketFactory class name with following optional socket parameters}\n" + " Legend:\n"
+ " -sp session persistence\n" + " -l access log a - with user agent, and r - referer\n"
+ " -nka no keep alive for connection");
System.exit(1);
}
private void readServlets(File servFile) {
/**
* servlet.properties file format servlet. <servletname>.code= <servletclass>servlet. <servletname>.initArgs= <name=value>, <name=value>
*/
Hashtable servletstbl, parameterstbl;
servletstbl = new Hashtable();
parameterstbl = new Hashtable();
if (servFile != null && servFile.exists() && servFile.canRead()) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(servFile)));
/**
* format of servlet.cfg file servlet_name;servlet_class;init_parameter1=value1;init_parameter2=value2...
*/
do {
String servletdsc = in.readLine();
if (servletdsc == null)
break;
StringTokenizer dsctokenzr = new StringTokenizer(servletdsc, ".=,", false);
if (dsctokenzr.hasMoreTokens()) {
if (!dsctokenzr.nextToken().equalsIgnoreCase("servlet")) {
log("No leading 'servlet' keyword, the sentence is skipped");
break;
}
if (dsctokenzr.hasMoreTokens()) {
String servletname = dsctokenzr.nextToken();
if (dsctokenzr.hasMoreTokens()) {
String lt = dsctokenzr.nextToken();
if (lt.equalsIgnoreCase("code")) {
if (dsctokenzr.hasMoreTokens())
servletstbl.put(servletname, dsctokenzr.nextToken("="));
} else if (lt.equalsIgnoreCase("initArgs")) {
Hashtable initparams = new Hashtable();
while (dsctokenzr.hasMoreTokens()) {
String key = dsctokenzr.nextToken("=,");
if (dsctokenzr.hasMoreTokens())
initparams.put(key, dsctokenzr.nextToken(",="));
}
parameterstbl.put(servletname, initparams);
} else
log("Unrecognized token " + lt + " in " + servletdsc + ", the line's skipped");
}
}
}
} while (true);
} catch (IOException e) {
log("Problem reading cfg file: " + e);
}
Enumeration se = servletstbl.keys();
String servletname;
while (se.hasMoreElements()) {
servletname = (String) se.nextElement();
addServlet(servletname, (String) servletstbl.get(servletname), (Hashtable) parameterstbl
.get(servletname));
}
}
}
String hostName;
private transient PrintStream logStream;
private boolean useAccLog;
private boolean keepAlive;
private int timeoutKeepAlive;
private int maxAliveConnUse;
private boolean showUserAgent;
private boolean showReferer;
protected String keepAliveHdrParams;
protected transient PathTreeDictionary registry;
protected transient PathTreeDictionary realms;
protected transient PathTreeDictionary mappingtable;
private Hashtable attributes;
protected transient KeepAliveCleaner keepAliveCleaner;
protected transient ThreadGroup serverThreads;
protected transient Utils.ThreadPool threadPool;
protected static Thread sdHook;
// for sessions
private int uniqer;
protected HttpSessionContextImpl sessions;
static int expiredIn;
public Map arguments;
protected static Serve serve;
protected static String workPath;
// / Constructor.
public Serve(Map arguments, PrintStream logStream) {
this.arguments = arguments;
this.logStream = logStream;
registry = new PathTreeDictionary();
realms = new PathTreeDictionary();
attributes = new Hashtable();
serverThreads = new ThreadGroup("TJWS threads");
Properties props = new Properties();
props.putAll(arguments);
threadPool = new Utils.ThreadPool(props, new Utils.ThreadFactory() {
public Thread create(Runnable runnable) {
Thread result = new Thread(serverThreads, runnable);
result.setDaemon(true);
return result;
}
});
setAccessLogged();
keepAlive = arguments.get(ARG_KEEPALIVE) == null || ((Boolean) arguments.get(ARG_KEEPALIVE)).booleanValue();
int timeoutKeepAliveSec;
try {
timeoutKeepAliveSec = Integer.parseInt((String) arguments.get(ARG_KEEPALIVE_TIMEOUT));
} catch (Exception ex) {
timeoutKeepAliveSec = 30;
}
timeoutKeepAlive = timeoutKeepAliveSec * 1000;
try {
maxAliveConnUse = Integer.parseInt((String) arguments.get(ARG_MAX_CONN_USE));
} catch (Exception ex) {
maxAliveConnUse = DEF_MAX_CONN_USE;
}
keepAliveHdrParams = "timeout=" + timeoutKeepAliveSec + ", max=" + maxAliveConnUse;
expiredIn = arguments.get(ARG_SESSION_TIMEOUT) != null ? ((Integer) arguments.get(ARG_SESSION_TIMEOUT))
.intValue() : DEF_SESSION_TIMEOUT;
Runtime.getRuntime().addShutdownHook(sdHook = new Thread(new Runnable() {
synchronized public void run() {
destroyAllServlets();
}
}, "ShutDownHook"));
}
public Serve() {
this(new HashMap(), System.err);
}
void setAccessLogged() {
String logflags = (String) arguments.get(ARG_LOG_OPTIONS);
if (logflags != null) {
useAccLog = true;
showUserAgent = logflags.indexOf('A') >= 0;
showReferer = logflags.indexOf('R') >= 0;
}
}
boolean isAccessLogged() {
return useAccLog;
}
boolean isShowReferer() {
return showReferer;
}
boolean isShowUserAgent() {
return showUserAgent;
}
boolean isKeepAlive() {
return keepAlive;
}
int getKeepAliveDuration() {
return timeoutKeepAlive;
}
String getKeepAliveParamStr() {
return keepAliveHdrParams;
}
int getMaxTimesConnectionUse() {
return maxAliveConnUse;
}
// / Register a Servlet by class name. Registration consists of a URL
// pattern, which can contain wildcards, and the class name of the Servlet
// to launch when a matching URL comes in. Patterns are checked for
// matches in the order they were added, and only the first match is run.
public void addServlet(String urlPat, String className) {
addServlet(urlPat, className, (Hashtable) null);
}
public void addServlet(String urlPat, String className, Hashtable initParams) {
// Check if we're allowed to make one of these.
SecurityManager security = System.getSecurityManager();
if (security != null) {
int i = className.lastIndexOf('.');
if (i > 0) {
security.checkPackageAccess(className.substring(0, i));
security.checkPackageDefinition(className.substring(0, i));
}
}
// Make a new one.
try {
addServlet(urlPat, (Servlet) Class.forName(className).newInstance(), initParams);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -