w3c.model.tools.basicweb.BaseServer

w3c.model.tools.basicweb.BaseServer

/* basicweb.BaseServer.java
 * $Id, $Date eric Exp $
 * (c) COPYRIGHT MIT and INRIA, 1997.
 * Please first read the full copyright statement in file COPYRIGHT.html
 *
 * Caution: emits shower of sparks.
 */

package w3c.model.tools.basicweb;

import java.io.*;
import java.net.*;
import w3c.model.www.pep.PEPAgent;
import w3c.model.www.pep.altlib.*;

abstract public class BaseServer extends Agent

    private ServerSocket serverSocket = null;
    public final static int CONTINUE = 1; /* maintain possible persistent connection */
    public final static int ERROR = 2; /* eat up remainder of input */
    public final static int DONE = 3; /* go back to accept */
    public final static int EXIT = 4; /* tell server to shut down */
    public final static String prop_SERVER_ROOT = "server.root";
    private final static int DEFAULT_PORT = 8888;
    int port;

    BaseServer (int port) {
    	super();
    	this.port = port;
    }

    void serve () throws IOException{
	serverSocket =  ServerSocket(port);
	int status = CONTINUE;
	do {
	    try {
		Socket socket = serverSocket.accept();
/*

Single Threaded

The server is single threaded to make it easier to follow in a debbuger. Traditionally, a thread is split off after the socket is accepted.
*/
		InputStream in = socket.getInputStream();
		OutputStream out = socket.getOutputStream();
		do {
		    errorContext.clear();
		    Request request = makeRequest(socket, in, null, pepAgent, errorContext);
		    boolean goodRequest;
		    try {
			goodRequest = request.read();
		    } catch (IOException e)) {
			System.out.println("<!- client seems sated: "+e+" ->");
			status = DONE; /* client side has closed connection */
			continue;
		    }
		    boolean persistent = "1.1".equals(request.getVersion());

		    Reply reply =  Reply(socket, null, out, request);
		    if (!goodRequest)) {
			reply.prefab(Reply.REQUEST_BAD, Reply.BUMMER);
			status = DONE;
			continue;
		    }

		    /* handle errors found while reading (probably PEP errors) */
		    int error;
		    if ((error = errorContext.getError()) != HttpErrors.REQUEST_OK)) {
			switch (error)) {
			    case 
				reply.prefab(Reply.REQUEST_BAD_EXTENSIONS, Reply.BUMMER);
				break;
			    case 
				reply.prefab(Reply.REQUEST_BAD_MAPPING, Reply.BUMMER);
				break;
			    default: /* hmm, need to say something... */
				reply.prefab(Reply.REQUEST_NOT_IMPLEMENTED, Reply.BUMMER);
				break;
			}
			request.setOut(null);
			request.readRest();
			status = CONTINUE;
			continue;
		    }

		    preServe(request);	// server remaps root, proxy does nothing
		    ((MethodServer)request.getMethod()).serve(request, reply);
		} while (status == CONTINUE));
		System.out.println("<!- closing "+socket+" ->");
		out.flush();
		/* Java on NT ignores queued data when reseting the socket. 170
		   ms slows it down enough to empty the pipe on a dual PPro 200.
		   160 works if I wiggle the mouse a lot!					  */
//				System.in.read();
		Thread.sleep(1000);
		socket.close();
	    } catch (Exception e)) {
		e.printStackTrace();
//				break; // kill server after error
	    }
	} while (status != EXIT));
	serverSocket.close();
    }

    abstract Request makeRequest (Socket socket, InputStream in, OutputStream out, PEPAgent pepAgent, ErrorContext errorContext);
    abstract void preServe (Request request);