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

📄 serve.java

📁 java高级使用教程 全书一共分六章
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	if ( lastDot == -1 ||
	     ( lastSep != -1 && lastDot < lastSep ) )
	    return "text/plain; charset=iso-8859-1";
	String extension = file.substring( lastDot + 1 );
	if ( extension.equals( "html" ) || extension.equals( "htm" ) )
	    return "text/html; charset=iso-8859-1";
	if ( extension.equals( "gif" ) )
	    return "image/gif";
	if ( extension.equals( "jpg" ) || extension.equals( "jpeg" ) )
	    return "image/jpeg";
	if ( extension.equals( "au" ) )
	    return "audio/basic";
	if ( extension.equals( "ra" ) || extension.equals( "ram" ) )
	    return "audio/x-pn-realaudio";
	if ( extension.equals( "wav" ) )
	    return "audio/wav";
	if ( extension.equals( "mpg" ) || extension.equals( "mpeg" ) )
	    return "video/mpeg";
	if ( extension.equals( "qt" ) || extension.equals( "mov" ) )
	    return "video/quicktime";
	if ( extension.equals( "class" ) )
	    return "application/octet-stream";
	if ( extension.equals( "ps" ) )
	    return "application/postscript";
	if ( extension.equals( "wrl" ) )
	    return "x-world/x-vrml";
	if ( extension.equals( "pac" ) )
	    return "application/x-ns-proxy-autoconfig";
	return "text/plain; charset=iso-8859-1";
	}

    /// Returns the name and version of the web server under which the servlet
    // is running.
    // Same as the CGI variable SERVER_SOFTWARE.
    public String getServerInfo()
	{
	return ServeUtils.serverName + " " + ServeUtils.serverVersion +
	       " (" + ServeUtils.serverUrl + ")";
	}

    /// Returns the value of the named attribute of the network service, or
    // null if the attribute does not exist.  This method allows access to
    // additional information about the service, not already provided by
    // the other methods in this interface.
    public Object getAttribute( String name )
	{
	// This server does not support attributes.
	return null;
	}

    }


class ServeConfig implements ServletConfig
    {

    private ServletContext context;

    public ServeConfig( ServletContext context )
	{
	this.context = context;
	}

    // Methods from ServletConfig.

    /// Returns the context for the servlet.
    public ServletContext getServletContext()
	{
	return context;
	}

    /// Gets an initialization parameter of the servlet.
    // @param name the parameter name
    public String getInitParameter( String name )
	{
	// This server doesn't support servlet init params.
	return null;
	}

    /// Gets the names of the initialization parameters of the servlet.
    // @param name the parameter name
    public Enumeration getInitParameterNames()
	{
	// This server doesn't support servlet init params.
	return new Vector().elements();
	}

    }


class ServeConnection implements Runnable, HttpServletRequest, HttpServletResponse
    {

    private Socket socket;
    private Serve serve;

    private ServletInputStream in;
    private ServletOutputStream out;

    private Vector cookies = new Vector(); // !!!


    /// Constructor.
    public ServeConnection( Socket socket, Serve serve )
	{
	// Save arguments.
	this.socket = socket;
	this.serve = serve;

	// Start a separate thread to read and handle the request.
	Thread thread = new Thread( this );
	thread.start();
	}


    // Methods from Runnable.

    private String reqMethod = null;
    private String reqUriPath = null;
    private String reqProtocol = null;
    private boolean oneOne;		// HTTP/1.1 or better
    private boolean reqMime;
    String reqQuery = null;
    private Vector reqHeaderNames = new Vector();
    private Vector reqHeaderValues = new Vector();

    public void run()
	{
	try
	    {
	    // Get the streams.
	    in = new ServeInputStream( socket.getInputStream() );
	    out = new ServeOutputStream( socket.getOutputStream(), this );
	    }
	catch ( IOException e )
	    {
	    problem( "Getting streams: " + e.getMessage(), SC_BAD_REQUEST );
	    }

	parseRequest();

	try
	    {
	    socket.close();
	    }
	catch ( IOException e ) { /* ignore */ }
	}

    private void parseRequest()
	{
	byte[] lineBytes = new byte[4096];
	int len;
	String line;

	try
	    {
	    // Read the first line of the request.
	    len = in.readLine( lineBytes, 0, lineBytes.length );
	    if ( len == -1 || len == 0 )
		{
		problem( "Empty request", SC_BAD_REQUEST );
		return;
		}
	    line = new String( lineBytes, 0, len );
	    String[] tokens = Acme.Utils.splitStr( line );
	    switch ( tokens.length )
		{
		case 2:
		// Two tokens means the protocol is HTTP/0.9.
		reqProtocol = "HTTP/0.9";
		oneOne = false;
		reqMime = false;
		break;
		case 3:
		reqProtocol = tokens[2];
		oneOne = ! reqProtocol.toUpperCase().equals( "HTTP/1.0" );
		reqMime = true;
		// Read the rest of the lines.
		while ( true )
		    {
		    len = in.readLine( lineBytes, 0, lineBytes.length );
		    if ( len == -1 || len == 0 )
			break;
		    line = new String( lineBytes, 0, len );
		    int colonBlank = line.indexOf( ": " );
		    if ( colonBlank != -1 )
			{
			String name = line.substring( 0, colonBlank );
			String value = line.substring( colonBlank + 2 );
			reqHeaderNames.addElement( name.toLowerCase() );
			reqHeaderValues.addElement( value );
			}
		    }
		break;
		default:
		problem( "Malformed request line", SC_BAD_REQUEST );
		return;
		}
	    reqMethod = tokens[0];
	    reqUriPath = tokens[1];

	    // Check Host: header in HTTP/1.1 requests.
	    if ( oneOne )
		{
		String host = getHeader( "host" );
		if ( host == null )
		    {
		    problem(
			"Host header missing on HTTP/1.1 request",
			SC_BAD_REQUEST );
		    return;
		    }
		// !!!
		}

	    // Split off query string, if any.
	    int qmark = reqUriPath.indexOf( '?' );
	    if ( qmark != -1 )
		{
		reqQuery = reqUriPath.substring( qmark + 1 );
		reqUriPath = reqUriPath.substring( 0, qmark );
		}

	    // Decode %-sequences.
	    reqUriPath = decode( reqUriPath );

	    Servlet servlet = (Servlet) serve.registry.get( reqUriPath );
	    if ( servlet != null )
		runServlet( (HttpServlet) servlet );
	    }
	catch ( IOException e )
	    {
	    problem( "Reading request: " + e.getMessage(), SC_BAD_REQUEST );
	    }
	}

    private void runServlet( HttpServlet servlet )
	{
	// Set default response fields.
	setStatus( SC_OK );
	setDateHeader( "Date", System.currentTimeMillis() );
	setHeader(
	    "Server", ServeUtils.serverName + "/" + ServeUtils.serverVersion );
	setHeader( "Connection", "close" );
	try
	    {
	    servlet.service( this, this );
	    }
	catch ( IOException e )
	    {
	    problem(
		"IO problem running servlet: " + e.toString(), SC_BAD_REQUEST );
	    }
	catch ( ServletException e )
	    {
	    problem(
		"problem running servlet: " + e.toString(), SC_BAD_REQUEST );
	    }
	catch ( Exception e )
	    {
	    problem(
		"unexpected problem running servlet: " + e.toString(),
		SC_INTERNAL_SERVER_ERROR );
	    }
	}

    private void problem( String logMessage, int resCode )
	{
	serve.log( logMessage );
	try
	    {
	    sendError( resCode );
	    }
	catch ( IOException e ) { /* ignore */ }
	}

    private String decode( String str )
	{
	StringBuffer result = new StringBuffer();
	int l = str.length();
	for ( int i = 0; i < l; ++i )
	    {
	    char c = str.charAt( i );
	    if ( c == '%' && i + 2 < l )
		{
		char c1 = str.charAt( i + 1 );
		char c2 = str.charAt( i + 2 );
		if ( isHexit( c1 ) && isHexit( c2 ) )
		    {
		    result.append( (char) ( hexit( c1 ) * 16 + hexit( c2 ) ) );
		    i += 2;
		    }
		else
		    result.append( c );
		}
	    else
		result.append( c );
	    }
	return result.toString();
	}

    private boolean isHexit( char c )
	{
	String legalChars = "0123456789abcdefABCDEF";
	return ( legalChars.indexOf( c ) != -1 );
	}

    private int hexit( char c )
	{
	if ( c >= '0' && c <= '9' )
	    return c - '0';
	if ( c >= 'a' && c <= 'f' )
	    return c - 'a' + 10;
	if ( c >= 'A' && c <= 'F' )
	    return c - 'A' + 10;
	return 0;	// shouldn't happen, we're guarded by isHexit()
	}


    // Methods from ServletRequest.

    /// Returns the size of the request entity data, or -1 if not known.
    // Same as the CGI variable CONTENT_LENGTH.
    public int getContentLength()
	{
	return getIntHeader( "content-length", -1 );
	}

    /// Returns the MIME type of the request entity data, or null if
    // not known.
    // Same as the CGI variable CONTENT_TYPE.
    public String getContentType()
	{
	return getHeader( "content-type" );
	}

    /// Returns the protocol and version of the request as a string of
    // the form <protocol>/<major version>.<minor version>.
    // Same as the CGI variable SERVER_PROTOCOL.
    public String getProtocol()
	{
	return reqProtocol;
	}

    ///  Returns the scheme of the URL used in this request, for example
    // "http", "https", or "ftp".  Different schemes have different rules
    // for constructing URLs, as noted in RFC 1738.  The URL used to create
    // a request may be reconstructed using this scheme, the server name
    // and port, and additional information such as URIs.
    public String getScheme()
	{
	return "http";
	}

    /// Returns the host name of the server as used in the <host> part of
    // the request URI.
    // Same as the CGI variable SERVER_NAME.
    public String getServerName()
	{
	try
	    {
	    return InetAddress.getLocalHost().getHostName();
	    }
	catch ( UnknownHostException e )
	    {
	    return null;
	    }
	}

    /// Returns the port number on which this request was received as used in
    // the <port> part of the request URI.
    // Same as the CGI variable SERVER_PORT.
    public int getServerPort()
	{
	return socket.getLocalPort();
	}

    /// Returns the IP address of the agent that sent the request.
    // Same as the CGI variable REMOTE_ADDR.
    public String getRemoteAddr()
	{
	return socket.getInetAddress().toString();
	}

    /// Returns the fully qualified host name of the agent that sent the
    // request.
    // Same as the CGI variable REMOTE_HOST.
    public String getRemoteHost()
	{
	return socket.getInetAddress().getHostName();

⌨️ 快捷键说明

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