Milán Major

netscape-revival

1 branch
Code

sun-java/classsrc/netscape/server/applet/ServerApplet.java

/*
 * @(#)ServerApplet.java	1.4 95/07/31
 * 
 * Copyright (c) 1995 Netscape Communications Corporation. All Rights Reserved.
 * 
 */

package netscape.server.applet;

import netscape.net.*;
import java.net.*;
import java.io.*;

/**
 * ServerApplet.
 *
 * @version 	1.0, 15 Jan 1996
 * @author 	Warren Harris
 */
abstract public class ServerApplet {
    protected String name;
    protected Socket socket;
    protected boolean responseStarted = false;
    int Cargs;
    int Csession;
    int Crequest;

    ////////////////////////////////////////////////////////////////////////////
    // Running
    ////////////////////////////////////////////////////////////////////////////

    /**
     * This method is overridden by the individual server applets.
     */
    public void run() throws Exception {
	warn("no 'run' method defined for " + name);
    }

    /**
     * Constant return code: NSAPI function was successful and performed an
     * action.
     */
    public static final int PROCEED = 0;

    /**
     * Constant return code: NSAPI function encountered an error and the 
     * request cannot proceed.
     */
    public static final int ABORTED = -1;

    /**
     * Constant return code: NSAPI function determined that it could not
     * do anything for the request.
     */
    public static final int NOACTION = -2;

    /**
     * Constant return code: Service function found that the client is 
     * unreachable, stop processing the request but do not report an error.
     */
    public static final int EXIT = -3;

    /**
     * Called by the system. 
     */
    protected int handleRequest(int rq) {
	Crequest = rq;
 	try {
	    run();
	    return PROCEED;
	}
	catch (Warning e) {
	    warn(e.getMessage());
	}
	catch (Misconfiguration e) {
	    reportMisconfiguration(e.toString());
	}
	catch (SecurityException e) {
	    reportSecurity(e.toString());
	}
	catch (Catastrophe e) {
	    reportCatastrophe(e.toString());
	}
	catch (Throwable e) {
	    reportFailure(e.toString());
	}

	if (responseStarted)
	    return EXIT;
	else
	    return ABORTED;
    }
    
    ////////////////////////////////////////////////////////////////////////////
    // Accessors
    ////////////////////////////////////////////////////////////////////////////

    static Server server = new Server();

    public static Server getServer() {
	return server;
    }

    /**
     * Returns the socket which connects the ServerApplet to the client.
     * The IP address of the client can be obtained by calling getAddress
     * on the socket returned.
     */
    public Socket getClientSocket() {
	return socket;
    }

    InputStream instr;
    PrintStream outstr;

    /**
     * This convenience routine returns an InputStream to be used for
     * reading input. 
     */
    public InputStream getInputStream() throws IOException {
	if (instr == null)
	    instr = socket.getInputStream();
	return instr;
    }

    /**
     * This convenience routine returns a PrintStream to be used for
     * writing text output. 
     */
    public PrintStream getOutputStream() throws IOException {
	if (outstr == null)
	    outstr = new PrintStream(socket.getOutputStream());
	return outstr;
    }

    /**
     * Retrieves things from the client pblock of the Session struct.
     */
    public native String getClientProperty(String name);

    /**
     * Retrieves things from the vars pblock of the Request struct.
     */
    public native String getServerProperty(String name);

    /**
     * Retrieves things from the args pblock associated with the request.
     * This is used to retrieve properties set up in the obj.conf file.
     */
    public native String getConfigProperty(String name);

    /**
     * Retrieves things from the headers pblock of the Request struct.
     * HTTP requests have attached RFC822 headers, which are actually
     * name=value pairs. Convert the header name you want to access to
     * lower case and this function will return its value if the client
     * sent it. Example:<p>
     * Client sends: <code>User-agent: Mozilla/1.1N</code><br>
     * Then: <code>getHeader("user-agent") == "Mozilla/1.1N"</code>
     */
    public native String getHeader(String name);
    
    /**
     * Retrieves things from the reqpb pblock of the Request struct.
     * Gets an aspect of the request. For HTTP, the request consists of:<p>
     * <pre>
     * Name               Value
     * ------------------------------------------------------------------------
     * method             HTTP method used in the request, usually GET or POST.
     * uri                The URI originally requested
     * protocol           The protocol identifier sent by the client
     * query              Any query string (data following a ?) sent in the URI
     * </pre>
     */
    public native String getRequestProperty(String name);
    
    /**
     * Sets response properties into the srvhdrs pblock of the Request 
     * struct.
     */
    public native void setResponseProperty(String name, String value);

    /**
     * Gets response properties from the srvhdrs pblock of the Request 
     * struct. This is handy if you want to see what responses are
     * going to be sent.
     */
    public native String getResponseProperty(String name);

    ////////////////////////////////////////////////////////////////////////////
    // Error Logging
    ////////////////////////////////////////////////////////////////////////////

    public static final int WARN = 0;
    public static final int MISCONFIG = 1;
    public static final int SECURITY = 2;
    public static final int FAILURE = 3;
    public static final int CATASTROPHE = 4;
    public static final int INFORM = 5;

    native void report(int degree, String name, String error);

    /**
    * Record a warning. name identifies your function to the administrator,
    * sn and rq are the Session and Request generating the error (these
    * can be null), and error is a string describing what went wrong.
     */
    public void warn(String error) { 
        report(WARN, name, error);
    }

    /**
     * Record a misconfiguration, or a missing or illegal parameter. name
     * identifies your function to the administrator,
     * sn and rq are the Session and Request generating the error (these
     * can be null), and error is a string describing what went wrong.
     */
    public void reportMisconfiguration(String error) { 
	report(MISCONFIG, name, error);
    }

    /**
     * Record a security violation, or someone trying to access a resource
     * they shouldn't. name identifies your function to the
     * administrator, sn and rq are the Session and Request generating the 
     * error (these can be null), and error is a string describing what went
     * wrong.
     */
    public void reportSecurity(String error) { 
        report(SECURITY, name, error);
    }

    /**
     * Record a general failure. name identifies your function to the
     * administrator, sn and rq are the Session and Request generating the 
     * error (these can be null), and error is a string describing what went
     * wrong.
     */
    public void reportFailure(String error) { 
       report(FAILURE, name, error);
    }

    /**
     * Record a catastrophic failure. name identifies your function to the
     * administrator, sn and rq are the Session and Request generating the 
     * error (these can be null), and error is a string describing what went
     * wrong.
     */
    public void reportCatastrophe(String error) { 
        report(CATASTROPHE, name, error);
    }

    /**
     * Record an informational message. name identifies your function to the
     * administrator, sn and rq are the Session and Request generating the 
     * error (these can be null), and error is a string describing what went
     * wrong.
     */
    public void inform(String error) { 
        report(INFORM, name, error);
    }

    ////////////////////////////////////////////////////////////////////////////
    // Static Initialization
    ////////////////////////////////////////////////////////////////////////////

    static {
	try {
	    Socket.setSocketImplFactory(new NSAPISocketImplFactory());
	} catch (IOException e) {
	    System.err.println("Failed to set SocketImplFactory");
	}
    }
}