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

📄 httprequest.java

📁 java写的一个很小但是实用的http server
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// HttpRequest.java - Class that represents HTTP requests.
//
// 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.BufferedReader;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;

import com.smartsc.util.Base64;
import com.smartsc.util.CaselessHashtable;
import com.smartsc.util.NVPairParser;

public class
HttpRequest
implements HttpStatusCodes, HttpReasonPhrases,
	HttpHeaders, HttpServletRequest
{
	protected
	HttpRequest( HttpServer server, Socket socket)
	throws IOException
	{
		this.server = server;
		this.socket = socket;

		is = new BufferedInputStream(
			socket.getInputStream(), server.getBufferSize() );
	}

	protected
	void
	parseRequest()
	throws HttpException
	{
		try
		{
			// Parse first line
			String s = readLine();
			StringTokenizer st = new StringTokenizer( s);

			method      = st.nextToken();
			verbatimRequestPath = st.nextToken();
			protocol    = st.nextToken();

			parseRequestPath( verbatimRequestPath );

			// Don't accept proxy requests (i.e. "GET http://host/uri ...")
			if( !requestPath.startsWith( "/" )
			||  st.hasMoreTokens() )
			{
				throw new HttpException( SC_BAD_REQUEST, RP_BAD_REQUEST);
			}

			// Parse headers
			s = readLine();
			while( !"".equals( s))
			{
				int idx = s.indexOf( ":");
				if( idx < 0)
				{
					server.log( "Bad Header: '" + s + "'");
					throw new HttpException( SC_BAD_REQUEST, RP_BAD_REQUEST);
				}
				String name  = s.substring( 0, idx);
				String value = "";
				if( idx < s.length()-1)
				{
					value = s.substring( idx+1).trim();
				}
				setHeader( name, value);

				s = readLine();
			}

			// Look for authorization
			String auth = getHeader( AUTHORIZATION);
			if( auth != null)
			{
				st = new StringTokenizer( auth);
				if( st.hasMoreTokens())
					authType = st.nextToken();
				if( st.hasMoreTokens())
				{
					String credentials = Base64.decode( st.nextToken());
					int colon = credentials.indexOf( ':');
					if( colon != -1)
						remoteUser = credentials.substring( 0, colon);
				}
			}

			// Look for session
			sessionName = server.getSessionName();
			Cookie sessionCookie = getCookie( sessionName);
			if( sessionCookie != null)
			{
				reqSessionId = sessionCookie.getValue();
				if( reqSessionId != null)
				{
					reqSessionIdFromCookie = true;
				}
			}
			else
			{
				// Can't call getParameter( sessionName ) because
				// that would/could cause POST data to be parsed!
				Vector v = (Vector)parameters.get( sessionName);
				if( v != null)
				{
					reqSessionId = (String)v.firstElement();
					if( reqSessionId != null)
					{
						reqSessionIdFromURL = true;
					}
				}
			}

			// Specific SessionId requested
			if( reqSessionId != null)
			{
				// Look for session, but don't create
				session = getSession( reqSessionId);
				// If found
				if( session != null)
				{
					session.setLastAccessedTime();
					// Requested sessionId valid
					reqSessionIdValid = true;
				}
			}
		}
		catch( HttpException he)
		{
			throw he;
		}
		catch( InterruptedIOException iioe)
		{
			throw new HttpException( SC_REQUEST_TIMEOUT, RP_REQUEST_TIMEOUT);
		}
		catch( Exception e)
		{
			server.log( "Exception parsing request: ", e );
			throw new HttpException( SC_BAD_REQUEST, RP_BAD_REQUEST);
		}
	}

	protected void parsePostData()
	throws IOException
	{
		if( !postDataParsed && HttpMethods.POST.equals( getMethod() ))
		{
			postDataParsed = true;

			// Get content type and length
			String contentType = getHeader( CONTENT_TYPE);
			int contentLength = getIntHeader( CONTENT_LENGTH);
			if( FORM_URLENCODED.equalsIgnoreCase( contentType)
			&&  contentLength > 0 )
			// TODO Limit max length?
			{
				// Get form data
				byte[] content = new byte[contentLength];
				int totalBytesRead = 0;
				while( totalBytesRead < contentLength )
				{
					int bytesRead = is.read( content,
						totalBytesRead, contentLength - totalBytesRead);
					if( bytesRead == -1 ) throw new IOException( "Short read" );
					totalBytesRead += bytesRead;
				}
				String s = new String( content);
				StringBuffer sb = new StringBuffer( s);
				// Change '+' to ' '
				for( int i = 0; i < sb.length(); ++i)
				{
					if( sb.charAt( i) == '+')
						sb.setCharAt( i, ' ');
				}
				s = sb.toString();
				new NVPairParser( s, "&", "=")
				{
					public void forEachNVPair( String name, String value)
					{
						setParameter(
							httpDecode( name), httpDecode( value) );
					}
				}.parse();
			}
		}
	}

	protected final String readLine()
	throws IOException
	{
		StringBuffer sb = new StringBuffer();

		int ch = is.read();

		while( ch != '\r' && ch != '\n' && ch != -1)
		{
			sb.append( (char)ch);
			ch = is.read();
		}

		// If CR, handle CRLF
		if( ch == '\r')
		{
			is.mark( 1);
			ch = is.read();
			if( ch != '\n')
			{
				// put it back
				is.reset();
			}
		}

		return sb.toString();
	}

	protected
	void
	setHeader( String name, String value)
	{
		headers.put( name, value);
		// If cookies
		if( name.equalsIgnoreCase( "Cookie"))
		{
			setCookies( value);
		}
	}

	public
	Cookie
	getCookie( String name)
	{
		return (Cookie)cookies.get( httpDecode( name));
	}

	protected
	void
	setCookies( String cookieString)
	{
		new NVPairParser( cookieString, ";", "=")
		{
			public void forEachNVPair( String name, String value)
			{
				setCookie( name, value);
			}
		}.parse();
	}

	protected
	void
	setCookie( String name, String value)
	{
		cookies.put( httpDecode( name),
			new Cookie( httpDecode(name), httpDecode(value)) );
	}

	protected
	void
	pushParameter( String name, String value)
	{
		setParameter( name, value, true );
	}

	protected
	void
	popParameter( String name )
	{
		Vector v = (Vector)parameters.get( name);
		if( v != null )
		{
			v.removeElementAt( 0 );
			if( v.size() == 0 )
			{
				parameters.remove( name );
			}
		}
	}

	protected
	void
	setParameter( String name, String value)
	{
		setParameter( name, value, false );
	}

	protected
	void
	setParameter( String name, String value, boolean putInFront )
	{
		Vector v = (Vector)parameters.get( name);
		if( v == null)
		{
			v = new Vector();
			parameters.put( name, v);
		}
		if( putInFront )
		{
			v.insertElementAt( value, 0 );
		}
		else
		{
			v.addElement( value);
		}
	}

	protected
	void
	createSession()
	{
		session =
			new com.smartsc.http.HttpSession( server.getSessionTimeout());
		sessions.put( session.getId(), session);
	}

	protected
	com.smartsc.http.HttpSession
	getSession( String sessionId)
	{
		return (com.smartsc.http.HttpSession)sessions.get( sessionId);
	}

	protected
	void
	close()
	throws IOException
	{
		if( ir != null)
		{
			ir.close();
		}
		is.close();
	}

	protected static
	void
	removeSession( String id)
	{
		sessions.remove( id);
	}

	public static
	String
	httpDecode( String encoded)
	{
		if( encoded == null)
			return null;

		StringBuffer decoded = new StringBuffer();
		StringTokenizer st = new StringTokenizer( encoded, "%+", true);

		while( st.hasMoreTokens())
		{
			String token =  st.nextToken();
			if( "%".equals( token) && st.hasMoreTokens())
			{
				String nextChunk = st.nextToken();

				// If Unicode encoding
				if( nextChunk.charAt( 0 ) == 'u' )
				{
					// Find first non-digit in the next four characters
					int nonDigitIdx = 5;
					int max = Math.min( 5, nextChunk.length() );
					for( int i = 1; i < max; ++i )
					{
						char ch = nextChunk.charAt( i );

						if( (ch < '0' || '9' < ch)
						&&  (ch < 'a' || 'f' < ch)
						&&  (ch < 'A' || 'F' < ch) )
						{
							nonDigitIdx = i;
							break;
						}
					}
					// Make sure we have at least one digit
					if( nonDigitIdx == 1 )
					{
						throw new NumberFormatException(
							"Bad Unicode encoding: %" + nextChunk );
					}

					decoded.append( (char)
						Integer.parseInt( nextChunk.substring( 1, nonDigitIdx), 16));
					decoded.append( nextChunk.substring( nonDigitIdx));
				}
				else
				{
					decoded.append( (char)
						Integer.parseInt( nextChunk.substring( 0, 2), 16));
					decoded.append( nextChunk.substring( 2));
				}
			}
			else if( "+".equals( token))
			{
				decoded.append( " ");
			}
			else
			{
				decoded.append( token);
			}

⌨️ 快捷键说明

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