📄 pseudoserver.java
字号:
package com.meterware.pseudoserver;/********************************************************************************************************************* $Id: PseudoServer.java,v 1.16 2004/04/20 16:35:21 russgold Exp $** Copyright (c) 2000-2003, Russell Gold** Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated* documentation files (the "Software"), to deal in the Software without restriction, including without limitation* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and* to permit persons to whom the Software is furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in all copies or substantial portions* of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER* DEALINGS IN THE SOFTWARE.********************************************************************************************************************/import java.io.*;import java.net.HttpURLConnection;import java.net.ServerSocket;import java.net.Socket;import java.util.*;/** * A basic simulated web-server for testing user agents without a web server. **/public class PseudoServer { private static final int DEFAULT_SOCKET_TIMEOUT = 1000; private static final int INPUT_POLL_INTERVAL = 10; /** Time in msec to wait for an outstanding server socket to be released before creating a new one. **/ private static int _socketReleaseWaitTime = 50; /** Number of outstanding server sockets that must be present before trying to wait for one to be released. **/ private static int _waitThreshhold = 10; private static int _numServers = 0; private int _serverNum = 0; private int _connectionNum = 0; private ArrayList _classpathDirs = new ArrayList(); private String _maxProtocolLevel = "1.1"; private final int _socketTimeout; /** * Returns the amount of time the pseudo server will wait for a server socket to be released (in msec) * before allocating a new one. See also {@link #getWaitThreshhold getWaitThreshhold}. */ public static int getSocketReleaseWaitTime() { return _socketReleaseWaitTime; } /** * Returns the amount of time the pseudo server will wait for a server socket to be released (in msec) * before allocating a new one. See also {@link #getWaitThreshhold getWaitThreshhold}. */ public static void setSocketReleaseWaitTime( int socketReleaseWaitTime ) { _socketReleaseWaitTime = socketReleaseWaitTime; } /** * Returns the number of server sockets that must have been allocated and not returned before waiting for one * to be returned. */ public static int getWaitThreshhold() { return _waitThreshhold; } /** * Specifies the number of server sockets that must have been allocated and not returned before waiting for one * to be returned. */ public static void setWaitThreshhold( int waitThreshhold ) { _waitThreshhold = waitThreshhold; } public PseudoServer() { this( DEFAULT_SOCKET_TIMEOUT ); } public PseudoServer( int socketTimeout ) { _socketTimeout = socketTimeout; _serverNum = ++_numServers; Thread t = new Thread( "PseudoServer " + _serverNum ) { public void run() { while (_active) { try { handleNewConnection( getServerSocket().accept() ); Thread.sleep( 20 ); } catch (InterruptedIOException e) { } catch (IOException e) { System.out.println( "Error in pseudo server: " + e ); e.printStackTrace(); } catch (InterruptedException e) { System.out.println( "Interrupted. Shutting down" ); _active = false; } } try { if (_serverSocket != null) ServerSocketFactory.release( _serverSocket ); _serverSocket = null; } catch (IOException e) { } } }; t.start(); } public void shutDown() { if (_debug) System.out.println( "** Requested shutdown of pseudoserver: " + hashCode() ); _active = false; } public void setMaxProtocolLevel( int majorLevel, int minorLevel ) { _maxProtocolLevel = majorLevel + "." + minorLevel; } /** * Returns the port on which this server is listening. **/ public int getConnectedPort() throws IOException { return getServerSocket().getLocalPort(); } /** * Defines the contents of an expected resource. **/ public void setResource( String name, String value ) { setResource( name, value, "text/html" ); } /** * Defines the contents of an expected resource. **/ public void setResource( String name, PseudoServlet servlet ) { _resources.put( asResourceName( name ), servlet ); } /** * Defines the contents of an expected resource. **/ public void setResource( String name, String value, String contentType ) { _resources.put( asResourceName( name ), new WebResource( value, contentType ) ); } /** * Defines the contents of an expected resource. **/ public void setResource( String name, byte[] value, String contentType ) { _resources.put( asResourceName( name ), new WebResource( value, contentType ) ); } /** * Defines a resource which will result in an error message. **/ public void setErrorResource( String name, int errorCode, String errorMessage ) { _resources.put( asResourceName( name ), new WebResource( errorMessage, errorCode ) ); } /** * Enables the sending of the character set in the content-type header. **/ public void setSendCharacterSet( String name, boolean enabled ) { WebResource resource = (WebResource) _resources.get( asResourceName( name ) ); if (resource == null) throw new IllegalArgumentException( "No defined resource " + name ); resource.setSendCharacterSet( enabled ); } /** * Specifies the character set encoding for a resource. **/ public void setCharacterSet( String name, String characterSet ) { WebResource resource = (WebResource) _resources.get( asResourceName( name ) ); if (resource == null) { resource = new WebResource( "" ); _resources.put( asResourceName( name ), resource ); } resource.setCharacterSet( characterSet ); } /** * Adds a header to a defined resource. **/ public void addResourceHeader( String name, String header ) { WebResource resource = (WebResource) _resources.get( asResourceName( name ) ); if (resource == null) { resource = new WebResource( "" ); _resources.put( asResourceName( name ), resource ); } resource.addHeader( header ); } public void mapToClasspath( String directory ) { _classpathDirs.add( directory ); } public void setDebug( boolean debug ) { _debug = debug; }//------------------------------------- private members --------------------------------------- private Hashtable _resources = new Hashtable(); private boolean _active = true; private boolean _debug; private String asResourceName( String rawName ) { if (rawName.startsWith( "http:" ) || rawName.startsWith( "/" )) { return escape( rawName ); } else { return escape( "/" + rawName ); } } private static String escape( String urlString ) { if (urlString.indexOf( ' ' ) < 0) return urlString; StringBuffer sb = new StringBuffer(); int start = 0; do { int index = urlString.indexOf( ' ', start ); if (index < 0) { sb.append( urlString.substring( start ) ); break; } else { sb.append( urlString.substring( start, index ) ).append( "%20" ); start = index+1; } } while (true); return sb.toString(); } private void handleNewConnection( final Socket socket ) { Thread t = new Thread( "PseudoServer " + _serverNum + " connection " + (++_connectionNum) ) { public void run() { try { serveRequests( socket ); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use Options | File Templates. } } }; t.start(); } private void serveRequests( Socket socket ) throws IOException { socket.setSoTimeout( _socketTimeout ); socket.setTcpNoDelay( true ); if (_debug) System.out.println( "** Created server thread: " + hashCode() ); final BufferedInputStream inputStream = new BufferedInputStream( socket.getInputStream() ); final HttpResponseStream outputStream = new HttpResponseStream( socket.getOutputStream() ); while (_active) { HttpRequest request = new HttpRequest( inputStream ); boolean keepAlive = respondToRequest( request, outputStream ); if (!keepAlive) break; while (_active && 0 == inputStream.available()) { try { Thread.sleep( INPUT_POLL_INTERVAL ); } catch (InterruptedException e) {} } } if (_debug) System.out.println( "** Closing server thread: " + hashCode() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -