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

📄 httpserver.java

📁 java写的一个很小但是实用的http server
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
// HttpServer.java - A multithreaded HTTP server.
//
// Copyright (C) 1999-2002  Smart Software Consulting
//
// 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// Smart Software Consulting
// 1688 Silverwood Court
// Danville, CA  94526-3079
// USA
//
// http://www.smartsc.com
//

package com.smartsc.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintWriter;

import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;

import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.StringTokenizer;

import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;

import com.smartsc.util.AbsoluteFile;
import com.smartsc.util.Mailer;
import com.smartsc.util.NVPairParser;
import com.smartsc.util.Properties;

public class
HttpServer
implements ServletContext, HttpStatusCodes, HttpReasonPhrases, Runnable
{
	public
	HttpServer( Properties props)
	throws IOException
	{
		this.props = props;

		// Get verbosity from properties
		boolean verbose = props.getBooleanProperty( PROP_VERBOSE);

		openLog( true );
		openTransferLog( true );

		// Log startup message
		banner( verbose);

		// Setup handler counter
		maxHandlers = props.getIntProperty(
			PROP_MAX_HANDLERS, DEFAULT_MAX_HANDLERS);
		handlerCount = 0;

		int backlog = props.getIntProperty( PROP_BACKLOG, -1);
		int port = props.getIntProperty( PROP_PORT, DEFAULT_PORT);
		if( port == 0)
			port = DEFAULT_PORT;

		if( backlog > 0)
		{
			serverSocket = new ServerSocket( port, backlog);
		}
		else
		{
			serverSocket = new ServerSocket( port);
		}

		StringBuffer sb = new StringBuffer(
			InetAddress.getLocalHost().getHostName());
		sb.append( ":");
		sb.append( port);
		serverName = sb.toString();

		// Parse servlet context init params
		String initParams = 	props.getProperty( PROP_INIT_PARAMS);
		if( initParams != null)
		{
			new NVPairParser( initParams, ",", "=")
			{
				public void forEachNVPair( String name, String value)
				{
					servletContextInitParams.put( name.trim(), value);
				}
			}.parse();
		}

		// Load servlets properties file
		String servletPropFile = props.getProperty(
			PROP_SERVLET_PROPS, DEFAULT_SERVLET_PROPS);
		try
		{
			File f = AbsoluteFile.create( servletPropFile);
			servletProperties.load( new FileInputStream( f));
		}
		// Ignore exceptions
		catch( IOException ie) {}

		// Process servlet properties (i.e. .startup and .mappings)
		processServletProperties();
	}

	public
	void
	run()
	{
		Socket clientSocket;

		while( true)
		{
			try
			{
				// If we have max number of handlers
				if( handlerCount >= maxHandlers)
				{
					// Wail until some finish
					synchronized( this)
					{
						while( handlerCount >= maxHandlers)
						{
							try
							{
								wait();
								/* TINI Omit
								// (wait is only a stub in TINI Beta 2.1)
								Thread.sleep( 100);
								//*/
							}
							catch( InterruptedException ie) {}
						}
					}
				}

				clientSocket = serverSocket.accept();
				clientSocket.setSoTimeout(
					1000 * props.getIntProperty( PROP_REQUEST_TIMEOUT));
			}
			catch( IOException ioe)
			{
				log( "Exception in accept()", ioe);
				continue;
			}

			try
			{
				HttpServerHandler handler = createHandler( this, clientSocket);
				new Thread( handler).start();
			}
			catch( HttpException he)
			{
				log( he);
				try
				{
					HttpResponse.sendError(
						clientSocket.getOutputStream(),
						he.getStatusCode(),
						he.getReasonPhrase());
				}
				catch( IOException ioe) {}
			}
			catch( Throwable t)
			{
				log( t);
				try
				{
					HttpResponse.sendError(
						clientSocket.getOutputStream(),
						SC_INTERNAL_SERVER_ERROR,
						RP_INTERNAL_SERVER_ERROR);
				}
				catch( IOException ioe) {}
			}
		}
	}

	protected
	void
	openLog( boolean append )
	{
		String logFileName = props.getProperty( PROP_LOG_FILE);

		if( logFileName != null)
		{
			try
			{
				logFile = AbsoluteFile.create( logFileName);
				logFileName = logFile.getAbsolutePath();
				logWriter = new PrintWriter(
					new FileOutputStream( logFileName, append ), true );
			}
			catch( IOException ioe)
			{
				System.err.println(
					"Could not open log file '" +
					logFileName + "' for writing.");
				logWriter = new PrintWriter( System.out, true);
				logFile = null;
			}
		}
		else
		{
			logWriter = new PrintWriter( System.out, true);
			logFile = null;
		}
	}

	protected
	void
	openTransferLog( boolean append )
	{
		String logFileName = null;
		if( logFile != null)
		{
			logFileName = logFile.getAbsolutePath();
		}

		String transferLogName = props.getProperty( PROP_TRANSFER_LOG);
		if( transferLogName != null)
		{
			transferLogFile = AbsoluteFile.create( transferLogName);
			transferLogName = transferLogFile.getAbsolutePath();
		}

		// Set transferLogWriter = logWriter if any one of these three
		// conditions is true...
		// 1) server.transferLog is not defined
		// 2) server.transferLog is the same as server.logFile
		// 3) server.transferLog is "-" and logFile is not defined
		if( transferLogName == null	|| transferLogName.equals( logFileName)
		||( transferLogName.equals( "-") && transferLogName == null) )
		{
			transferLogWriter = logWriter;
			transferLogFile = logFile;
		}
		else if( transferLogName.equals( "-"))
		{
			transferLogWriter = new PrintWriter( System.out, true);
			transferLogFile = null;
		}
		else
		{
			try
			{
				transferLogWriter = new PrintWriter(
					new FileOutputStream( transferLogName, append ), true);
			}
			catch( IOException ioe)
			{
				System.err.println(
					"Could not open transfer log file '" +
					transferLogName + "' for writing.");
				transferLogWriter = logWriter;
				transferLogFile = logFile;
			}
		}
	}

	public
	void
	logTransfer( String msg)
	{
		if( transferLogWriter != null)
		{
			synchronized( transferLogWriter)
			{
				transferLogWriter.println( msg);
			}
		}
	}

	protected
	HttpServerHandler
	createHandler( HttpServer server, Socket clientSocket)
	throws HttpException
	{
		return new HttpServerHandler( server, clientSocket);
	}

	protected synchronized
	void
	addHandler()
	{
		++handlerCount;
	}

	protected synchronized
	void
	removeHandler()
	{
		--handlerCount;
		if( (handlerCount == 0 && getTimeSinceLastGC() > MIN_GC_TIME))
		{
			gc();
		}
		notifyAll();
	}

	protected synchronized
	long
	getTimeSinceLastGC()
	{
		return System.currentTimeMillis() - lastGCTime;
	}

	protected synchronized
	void
	gc()
	{
		// Check log file sizes
		if( logFile != null)
		{
			synchronized( logWriter)
			{
				if( isLogOversized( logFile))
				{
					logWriter.close();
					try
					{
						if( isMailingOversizedLogs() )
						{
							mailLog( logFile);
						}
						openLog( false );
					}
					catch( IOException ioe)
					{
						// Truncate log file then log exception
						openLog( false );
						log( ioe );
					}
				}
			}
		}

		if( transferLogFile != null && transferLogFile != logFile)
		{
			synchronized( transferLogWriter)
			{
				if( isLogOversized( transferLogFile))
				{
					transferLogWriter.close();
					if( isMailingOversizedLogs() )
					{
						try
						{
							mailLog( transferLogFile);
						}
						catch( IOException ioe)
						{
							log( ioe );
						}
					}
					openTransferLog( false );
				}
			}
		}

		System.gc();
		lastGCTime = System.currentTimeMillis();
	}

	protected void processServletProperties()
	{
		Enumeration e = servletProperties.keys();
		while( e.hasMoreElements())
		{
			String propName = (String)e.nextElement();
			String propValue = getServletProperty( propName );
			if( propValue == null )
			{
				continue;
			}

			if( propName.endsWith( PRELOAD))
			{
				boolean preload = Boolean.valueOf( propValue).booleanValue();
				if( preload)
				{
					String servletName = propName.substring( 0,
						propName.length() - PRELOAD.length());

					getNamedDispatcher( servletName);
				}
			}
			else if( propName.endsWith( MAPPING))
			{
				String servletName = propName.substring( 0,
					propName.length() - MAPPING.length());

				// If prefix mapping
				if( propValue.startsWith( "/" ) && propValue.endsWith( "/*" ))

⌨️ 快捷键说明

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