⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serve.java

📁 用java开发的
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
// Serve - minimal Java servlet container class
//
// Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
//

// All enhancments Copyright (C)1998-2007 by Dmitriy Rogatkin
// This version is compatible with JSDK 2.5
// http://tjws.sourceforge.net
// $Id: Serve.java,v 1.112 2007/01/04 00:33:29 rogatkin Exp $

package Acme.Serve;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLDecoder;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.TreeSet;
import java.util.Vector;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionContext;
import javax.servlet.SingleThreadModel;

import Acme.Utils;

/// Minimal Java servlet container class.
// <P>
// This class implements a very small embeddable servlet container.
// It runs Servlets compatible with the API used by Sun's 
// <A HREF="http://docs.sun.com/app/docs/doc/819-3653">Java System Application </A> server.
// Servlet API can be found <A HREF="http://java.sun.com/products/servlet/">here</A>.
// It comes with default Servlets which provide the usual
// httpd services, returning files and directory listings.
// <P>
// This is not in any sense a competitor for Java System Application server.
// Java System Application server is a full-fledged HTTP server and more.
// Acme.Serve is tiny, about 5000 lines, and provides only the
// functionality necessary to deliver an Applet's .class files
// and then start up a Servlet talking to the Applet.
// They are both written in Java, they are both web servers, and
// they both implement the Servlet API; other than that they couldn't
// be more different.
// <P>
// This is actually the second HTTP server I've written.
// The other one is called
// <A HREF="http://www.acme.com/software/thttpd/">thttpd</A>,
// it's written in C, and is also pretty small although much more
// featureful than this.
// <P>
// Other Java HTTP servers:
// <UL>
// <LI> The above-mentioned <A
// HREF="http://docs.sun.com/app/docs/doc/819-3653">JavaServer</A>.
// <LI> W3C's <A HREF="http://www.w3.org/pub/WWW/Jigsaw/">Jigsaw</A>.
// <LI> David Wilkinson's <A
// HREF="http://www.netlink.co.uk/users/cascade/http/">Cascade</A>.
// <LI> Yahoo's <A
// HREF="http://www.yahoo.com/Computers_and_Internet/Software/Internet/World_Wide_Web/Servers/Java/">list
// of Java web servers</A>.
// </UL>
// <P>
// A <A HREF="http://www.byte.com/art/9706/sec8/art1.htm">June 1997 BYTE
// magazine article</A> mentioning this server.<BR>
// A <A HREF="http://www.byte.com/art/9712/sec6/art7.htm">December 1997 BYTE
// magazine article</A> giving it an Editor's Choice Award of Distinction.<BR>
// <A HREF="/resources/classes/Acme/Serve/Serve.java">Fetch the
// software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A>
// <P>
// @see Acme.Serve.servlet.http.HttpServlet
// @see FileServlet
// @see CgiServlet
// <h3>Post notes</h3>
// Currently the server 3 more times complex and can compete with
// most popular app and web servers used for deploying of web
// Java applications.

// Inheritance can extend usage of this server
public class Serve implements ServletContext, Serializable {

	private static final String progName = "Serve";

	public static final String ARG_PORT = "port";

	public static final String ARG_THROTTLES = "throttles";

	public static final String ARG_SERVLETS = "servlets";

	public static final String ARG_REALMS = "realms";

	public static final String ARG_ALIASES = "aliases";

	public static final String ARG_BINDADDRESS = "bind-address";

	public static final String ARG_BACKLOG = "backlog";

	public static final String ARG_CGI_PATH = "cgi-path";

	public static final String ARG_ERR = "error-stream";

	public static final String ARG_OUT = "out-stream";

	public static final String ARG_SESSION_TIMEOUT = "session-timeout";

	public static final String ARG_LOG_OPTIONS = "log-options";

	public static final String ARG_SOCKET_FACTORY = "socketFactory";

	public static final String ARG_NOHUP = "nohup";

	public static final String ARG_JSP = "JSP";

	public static final String ARG_WAR = "war-deployer";

	public static final String ARG_KEEPALIVE = "keep-alive";

	public static final String DEF_LOGENCODING = "tjws.serve.log.encoding";

	public static final String ARG_KEEPALIVE_TIMEOUT = "timeout-keep-alive";

	public static final String ARG_MAX_CONN_USE = "max-alive-conn-use";

	public static final String ARG_SESSION_PERSIST = "sssn-persistance";

	public static final String ARG_MAX_ACTIVE_SESSIONS = "max-active-sessions";

	public static final String ARG_ACCESS_LOG_FMT = "access-log-format";

	public static final String ARG_THREAD_POOL_SIZE = Utils.ThreadPool.MAXNOTHREAD;

	protected static final int DEF_SESSION_TIMEOUT = 30; // in minutes

	protected static final int DEF_MIN_ACT_SESS = 10;

	public static final int DEF_PORT = 8080;

	public static final String BGCOLOR = "BGCOLOR=\"#D1E9FE\"";

	/**
	 * max number of alive connections default value
	 */
	protected static final int DEF_MAX_CONN_USE = 100;

	protected static final String UTF8 = "UTF-8"; // default encoding

	// / Main routine, if you want to run this directly as an application.
	public static void main(String[] args) {
		Map arguments = new HashMap(20);
		StringBuffer messages = null;

		int argc = args.length;
		int argn;
		// Parse args.
		workPath = System.getProperty("user.dir", ".");
		if (argc == 0) { // a try to read from file for java -jar server.jar
			BufferedReader br = null;
			try {
				br = new BufferedReader(new FileReader(new File(workPath, "cmdparams")));
				args = Utils.splitStr(br.readLine(), "\"");
				argc = args.length;
			} catch (Exception e) { // many can happen
				if (messages == null)
					messages = new StringBuffer(100);
				messages.append("Can't read from CLA file ").append(e).append('\n');
			} finally {
				if (br != null)
					try {
						br.close();
					} catch (IOException ioe) {
					}
			}
		}
		// TODO: redesign process of parameters based on a map
		for (argn = 0; argn < argc && args[argn].length() > 0 && args[argn].charAt(0) == '-';) {
			if (args[argn].equals("-p") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_PORT, new Integer(args[argn]));
			} else if (args[argn].equals("-t") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_THROTTLES, args[argn]);
			} else if (args[argn].equals("-s") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_SERVLETS, args[argn]);
			} else if (args[argn].equals("-r") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_REALMS, args[argn]);
			} else if (args[argn].equals("-a") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_ALIASES, args[argn]);
			} else if (args[argn].equals("-b") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_BINDADDRESS, args[argn]);
			} else if (args[argn].equals("-k") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_BACKLOG, args[argn]);
			} else if (args[argn].equals("-j") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_JSP, args[argn]);
			} else if (args[argn].equals("-w") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_WAR, args[argn]);
			} else if (args[argn].equals("-c") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_CGI_PATH, args[argn]);
			} else if (args[argn].equals("-mka") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_MAX_CONN_USE, args[argn]);
				arguments.put(ARG_KEEPALIVE, Boolean.TRUE);
			} else if (args[argn].equals("-nka")) {
				arguments.put(ARG_KEEPALIVE, Boolean.FALSE);
			} else if (args[argn].equals("-sp")) {
				arguments.put(ARG_SESSION_PERSIST, Boolean.TRUE);
			} else if (args[argn].equals("-kat") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_KEEPALIVE_TIMEOUT, args[argn]);
				arguments.put(ARG_KEEPALIVE, Boolean.TRUE);
			} else if (args[argn].equals("-e") && argn + 1 < argc) {
				++argn;
				try {
					arguments.put(ARG_SESSION_TIMEOUT, new Integer(args[argn]));
				} catch (NumberFormatException nfe) {
				}
			} else if (args[argn].equals("-z") && argn + 1 < argc) {
				++argn;
				arguments.put(ARG_THREAD_POOL_SIZE, args[argn]);
				// backlog will be anyway upper limitation
			} else if (args[argn].startsWith("-l")) {
				arguments
						.put(ARG_ACCESS_LOG_FMT,
								"{0}:{9} {1} {2} [{3,date,dd/MMM/yyyy:HH:mm:ss Z}] \"{4} {5} {6}\" {7,number,#} {8,number} {10} {11}");
				if (args[argn].length() > 2) {
					arguments.put(ARG_LOG_OPTIONS, args[argn].substring(2).toUpperCase());
					if (args[argn].indexOf('f') >= 0) {
						++argn;
						arguments.put(ARG_ACCESS_LOG_FMT, args[argn]);
					}
				} else
					arguments.put(ARG_LOG_OPTIONS, "");
			} else if (args[argn].startsWith("-nohup")) {
				arguments.put(ARG_NOHUP, ARG_NOHUP);
			} else if (args[argn].equals("-m") && argn + 1 < argc) {
				++argn;
				try {
					arguments.put(ARG_MAX_ACTIVE_SESSIONS, new Integer(args[argn]));
					if (((Integer) arguments.get(ARG_MAX_ACTIVE_SESSIONS)).intValue() < DEF_MIN_ACT_SESS)
						arguments.put(ARG_MAX_ACTIVE_SESSIONS, new Integer(DEF_MIN_ACT_SESS));
				} catch (NumberFormatException nfe) {
					// ignored
				}
			} else if (args[argn].equals("-err")) {
				if (argn + 1 < argc && args[argn + 1].startsWith("-") == false) {
					++argn;
					try {
						arguments.put(ARG_ERR, (PrintStream) Class.forName(args[argn]).newInstance());
					} catch (Error er) {
						if (messages == null)
							messages = new StringBuffer(100);
						messages.append("Problem of processing class parameter of error redirection stream: ").append(
								er).append('\n');
					} catch (Exception ex) {
						if (messages == null)
							messages = new StringBuffer(100);
						messages.append("Exception in processing class parameter of error redirection stream: ")
								.append(ex).append('\n');
					}
				} else
					arguments.put(ARG_ERR, System.err);
			} else if (args[argn].equals("-out")) {
				if (argn + 1 < argc && args[argn + 1].startsWith("-") == false) {
					++argn;
					try {
						arguments.put(ARG_OUT, (PrintStream) Class.forName(args[argn]).newInstance());
					} catch (Error er) {
						if (messages == null)
							messages = new StringBuffer(100);
						messages.append("Problem of processing class parameter of out redirection stream: ").append(er)
								.append('\n');
					} catch (Exception ex) {
						if (messages == null)
							messages = new StringBuffer(100);
						messages.append("Exception in processing class parameter of out redirection stream: ").append(
								ex).append('\n');
					}
				}
			} else if (args[argn].startsWith("-")) { // free args, note it generate problem since free arguments can match internal arguments
				if (args[argn].length() > 1)
					arguments.put(args[argn].substring(1),// .toUpperCase(),
							argn < argc - 1 ? args[++argn] : "");
			} else
				usage();

			++argn;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -