/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.ajp.tomcat4;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.AccessControlException;
import java.util.Stack;
import java.util.Vector;

import org.apache.catalina.Connector;
import org.apache.catalina.Container;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Request;
import org.apache.catalina.Response;
import org.apache.catalina.Service;
import org.apache.catalina.net.DefaultServerSocketFactory;
import org.apache.catalina.net.ServerSocketFactory;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;

/**
 * Implementation of an Ajp13 connector.
 *
 * @author Kevin Seguin
 * @version $Revision$ $Date$
 */


public final class Ajp13Connector
    implements Connector, Lifecycle, Runnable {


    // ----------------------------------------------------- Instance Variables


    /**
     * The accept count for this Connector.
     */
    private int acceptCount = 10;


    /**
     * The IP address on which to bind, if any.  If <code>null</code>, all
     * addresses on the server will be bound.
     */
    private String address = null;


    /**
     * The input buffer size we should create on input streams.
     */
    private int bufferSize = 2048;


    /**
     * The Container used for processing requests received by this Connector.
     */
    protected Container container = null;


    /**
     * The set of processors that have ever been created.
     */
    private Vector created = new Vector();


    /**
     * The current number of processors that have been created.
     */
    private int curProcessors = 0;


    /**
     * The debugging detail level for this component.
     */
    private int debug = 0;


    /**
     * The server socket factory for this component.
     */
    private ServerSocketFactory factory = null;


    /**
     * Descriptive information about this Connector implementation.
     */
    private static final String info =
        "org.apache.catalina.connector.ajp.Ajp13Connector/1.0";


    /**
     * redirect port.
     */
    private int redirectPort = -1;

    /**
     * enable DNS lookups.
     */
    private boolean enableLookups = false;

    /**
     * The lifecycle event support for this component.
     */
    protected LifecycleSupport lifecycle = new LifecycleSupport(this);


    /**
     * The minimum number of processors to start at initialization time.
     */
    protected int minProcessors = 5;


    /**
     * The maximum number of processors allowed, or <0 for unlimited.
     */
    private int maxProcessors = 20;


    /**
     * Timeout value on the incoming connection.
     * Note : a value of 0 means no timeout.
     */
    private int connectionTimeout = -1;


    /**
     * Linger value to be used on socket close.
     * Note : a value of -1 means no linger used on close.
     */
    private int connectionLinger = -1;


    /**
     * The port number on which we listen for ajp13 requests.
     */
    private int port = 8009;


    /**
     * The set of processors that have been created but are not currently
     * being used to process a request.
     */
    private Stack processors = new Stack();


    /**
     * The request scheme that will be set on all requests received
     * through this connector.
     */
    private String scheme = "http";


    /**
     * The secure connection flag that will be set on all requests received
     * through this connector.
     */
    private boolean secure = false;


    /**
     * The server socket through which we listen for incoming TCP connections.
     */
    private ServerSocket serverSocket = null;


    /**
     * The string manager for this package.
     */
    private StringManager sm =
	StringManager.getManager(Constants.PACKAGE);


    /**
     * Has this component been started yet?
     */
    private boolean started = false;


    /**
     * The shutdown signal to our background thread
     */
    private boolean stopped = false;


    /**
     * The background thread.
     */
    private Thread thread = null;


    /**
     * This connector's thread group.
     */
    private ThreadGroup threadGroup = null;


    /**
     * The name to register for the background thread.
     */
    private String threadName = null;


    /**
     * A thread that periodically logs debug info if debug > 0.
     */
    private DebugThread debugThread = null;


    /**
     * The thread synchronization object.
     */
    private Object threadSync = new Object();

    private Ajp13Logger logger = new Ajp13Logger();

    /**
     * The service which which the connector is associated
     */
    private Service service = null;

    private String secret = null;


    /**
     * Tomcat authentication flag. If true, the authnetication is done by
     * Tomcat, otherwise, it is done by the native webserver.
     */
    private boolean tomcatAuthentication = true;


    // ------------------------------------------------------------- Properties


    /**
     * Return the connection timeout for this Connector.
     */
    public int getConnectionTimeout() {

	return (connectionTimeout);

    }


    /**
     * Set the connection timeout for this Connector.
     *
     * @param connectionTimeout The new connection timeout
     */
    public void setConnectionTimeout(int connectionTimeout) {

	this.connectionTimeout = connectionTimeout;

    }

    /**
     * Return the connection linger settings for this Connector.
     */
    public int getConnectionLinger() {

	return (connectionLinger);

    }


    /**
     * Set the connection linger for this Connector.
     *
     * @param connectionLinger The new connection linger
     */
    public void setConnectionLinger(int connectionLinger) {

	this.connectionLinger = connectionLinger;

    }

    public void setSecret( String s ) {
        secret=s;
    }

    public String getSecret() {
        return secret;
    }
    

    /**
     * Return the accept count for this Connector.
     */
    public int getAcceptCount() {

	return (acceptCount);

    }


    /**
     * Set the accept count for this Connector.
     *
     * @param count The new accept count
     */
    public void setAcceptCount(int count) {

	this.acceptCount = count;

    }



    /**
     * Return the bind IP address for this Connector.
     */
    public String getAddress() {

	return (this.address);

    }


    /**
     * Set the bind IP address for this Connector.
     *
     * @param address The bind IP address
     */
    public void setAddress(String address) {

	this.address = address;

    }


    /**
     * Is this connector available for processing requests?
     */
    public boolean isAvailable() {

	return (started);

    }


    /**
     * Return the input buffer size for this Connector.
     */
    public int getBufferSize() {

	return (this.bufferSize);

    }


    /**
     * Set the input buffer size for this Connector.
     *
     * @param bufferSize The new input buffer size.
     */
    public void setBufferSize(int bufferSize) {

	this.bufferSize = bufferSize;

    }


    /**
     * Return the Container used for processing requests received by this
     * Connector.
     */
    public Container getContainer() {

	return (container);

    }


    /**
     * Set the Container used for processing requests received by this
     * Connector.
     *
     * @param container The new Container to use
     */
    public void setContainer(Container container) {

	this.container = container;

    }


    /**
     * Return the current number of processors that have been created.
     */
    public int getCurProcessors() {

	return (curProcessors);

    }


    /**
     * Return the debugging detail level for this component.
     */
    public int getDebug() {

        return (debug);

    }


    /**
     * Set the debugging detail level for this component.
     *
     * @param debug The new debugging detail level
     */
    public void setDebug(int debug) {

        this.debug = debug;

    }

    /**
     * Return the "enable DNS lookups" flag.
     */
    public boolean getEnableLookups() {
        return this.enableLookups;
    }

    /**
     * Set the "enable DNS lookups" flag.
     *
     * @param enableLookups The new "enable DNS lookups" flag value
     */
    public void setEnableLookups(boolean enableLookups) {
        this.enableLookups = enableLookups;
    }

    /**
     * Return the port number to which a request should be redirected if
     * it comes in on a non-SSL port and is subject to a security constraint
     * with a transport guarantee that requires SSL.
     */
    public int getRedirectPort() {
        return this.redirectPort;
    }


    /**
     * Set the redirect port number.
     *
     * @param redirectPort The redirect port number (non-SSL to SSL)
     */
    public void setRedirectPort(int redirectPort) {
        this.redirectPort = redirectPort;
    }

    /**
     * Return the server socket factory used by this Container.
     */
    public ServerSocketFactory getFactory() {

        if (this.factory == null) {
            synchronized (this) {
                this.factory = new DefaultServerSocketFactory();
            }
        }
        return (this.factory);

    }


    /**
     * Set the server socket factory used by this Container.
     *
     * @param factory The new server socket factory
     */
    public void setFactory(ServerSocketFactory factory) {

        this.factory = factory;

    }


    /**
     * Return descriptive information about this Connector implementation.
     */
    public String getInfo() {

	return (info);

    }


    /**
     * Return the minimum number of processors to start at initialization.
     */
    public int getMinProcessors() {

	return (minProcessors);

    }


    /**
     * Set the minimum number of processors to start at initialization.
     *
     * @param minProcessors The new minimum processors
     */
    public void setMinProcessors(int minProcessors) {

	this.minProcessors = minProcessors;

    }


    /**
     * Return the maximum number of processors allowed, or <0 for unlimited.
     */
    public int getMaxProcessors() {

	return (maxProcessors);

    }


    /**
     * Set the maximum number of processors allowed, or <0 for unlimited.
     *
     * @param maxProcessors The new maximum processors
     */
    public void setMaxProcessors(int maxProcessors) {

	this.maxProcessors = maxProcessors;

    }


    /**
     * Return the port number on which we listen for AJP13 requests.
     */
    public int getPort() {

	return (this.port);

    }


    /**
     * Set the port number on which we listen for AJP13 requests.
     *
     * @param port The new port number
     */
    public void setPort(int port) {

	this.port = port;

    }


    /**
     * Return the scheme that will be assigned to requests received
     * through this connector.  Default value is "http".
     */
    public String getScheme() {

	return (this.scheme);

    }


    /**
     * Set the scheme that will be assigned to requests received through
     * this connector.
     *
     * @param scheme The new scheme
     */
    public void setScheme(String scheme) {

	this.scheme = scheme;

    }


    /**
     * Return the secure connection flag that will be assigned to requests
     * received through this connector.  Default value is "false".
     */
    public boolean getSecure() {

	return (this.secure);

    }


    /**
     * Set the secure connection flag that will be assigned to requests
     * received through this connector.
     *
     * @param secure The new secure connection flag
     */
    public void setSecure(boolean secure) {

	this.secure = secure;

    }


    /**
     * Returns the <code>Service</code> with which we are associated.
     */
    public Service getService() {
	return service;
    }


    /**
     * Set the <code>Service</code> with which we are associated.
     */
    public void setService(Service service) {
	this.service = service;
    }


    /**
     * Get the value of the tomcatAuthentication flag.
     */
    public boolean getTomcatAuthentication() {
        return tomcatAuthentication;
    }


    /**
     * Set the value of the tomcatAuthentication flag.
     */
    public void setTomcatAuthentication(boolean tomcatAuthentication) {
        this.tomcatAuthentication = tomcatAuthentication;
    }


    // --------------------------------------------------------- Public Methods


    /**
     * Create (or allocate) and return a Request object suitable for
     * specifying the contents of a Request to the responsible Container.
     */
    public Request createRequest() {

	Ajp13Request request = new Ajp13Request(this);
	request.setConnector(this);
	return (request);

    }


    /**
     * Create (or allocate) and return a Response object suitable for
     * receiving the contents of a Response from the responsible Container.
     */
    public Response createResponse() {

	Ajp13Response response = new Ajp13Response();
	response.setConnector(this);
	return (response);

    }

    /**
     * Invoke a pre-startup initialization. This is used to allow connectors
     * to bind to restricted ports under Unix operating environments.
     * ServerSocket (we start as root and change user? or I miss something?).
     */
    public void initialize() throws LifecycleException {
    }


    // -------------------------------------------------------- Package Methods


    /**
     * Recycle the specified Processor so that it can be used again.
     *
     * @param processor The processor to be recycled
     */
    void recycle(Ajp13Processor processor) {

        synchronized(processors) {
            if (debug > 0) {
                logger.log("added processor to available processors, available="
                           + processors.size());
            }
            processors.push(processor);
        }

    }


    // -------------------------------------------------------- Private Methods


    /**
     * Create (or allocate) and return an available processor for use in
     * processing a specific AJP13 request, if possible.  If the maximum
     * allowed processors have already been created and are in use, return
     * <code>null</code> instead.
     */
    private Ajp13Processor createProcessor() {

	synchronized (processors) {
	    if (processors.size() > 0)
		return ((Ajp13Processor) processors.pop());
	    if ((maxProcessors > 0) && (curProcessors < maxProcessors))
	        return (newProcessor());
	    else
	        return (null);
	}

    }


    /**
     * Create and return a new processor suitable for processing AJP13
     * requests and returning the corresponding responses.
     */
    private Ajp13Processor newProcessor() {

        Ajp13Processor processor = new Ajp13Processor(this, curProcessors++, threadGroup);
	if (processor instanceof Lifecycle) {
	    try {
	        ((Lifecycle) processor).start();
	    } catch (LifecycleException e) {
	        logger.log("newProcessor", e);
                curProcessors--;
	        return (null);
	    }
	}
	created.addElement(processor);
	return (processor);

    }


    /**
     * Open and return the server socket for this Connector.  If an IP
     * address has been specified, the socket will be opened only on that
     * address; otherwise it will be opened on all addresses.
     *
     * @exception IOException if an input/output error occurs
     */
    private ServerSocket open() throws IOException {

        // Acquire the server socket factory for this Connector
        ServerSocketFactory factory = getFactory();

	// If no address is specified, open a connection on all addresses
        if (address == null) {
	    logger.log(sm.getString("ajp13Connector.allAddresses"));
            try {
		return (factory.createSocket(port, acceptCount));
	    } catch(Exception ex ) {
		ex.printStackTrace();
		return null;
	    }
	}

	// Open a server socket on the specified address
        try {
            InetAddress is = InetAddress.getByName(address);
	    logger.log(sm.getString("ajp13Connector.anAddress", address));
            return (factory.createSocket(port, acceptCount, is));
	} catch (Exception e) {
	    try {
		logger.log(sm.getString("ajp13Connector.noAddress", address));
		return (factory.createSocket(port, acceptCount));
	    } catch( Exception e1 ) {
		e1.printStackTrace();
		return null;
	    }
	}

    }


    // ---------------------------------------------- Background Thread Methods


    /**
     * The background thread that listens for incoming TCP/IP connections and
     * hands them off to an appropriate processor.
     */
    public void run() {

        // Loop until we receive a shutdown command
	while (!stopped) {

	    // Accept the next incoming connection from the server socket
	    Socket socket = null;
	    try {
                if (debug > 0) {
                    logger.log("accepting socket...");
                }
                
		socket = serverSocket.accept();

                if (debug > 0) {
                    logger.log("accepted socket, assigning to processor.");
                }
                
                /* Warning :
                 * 
                 * To be able to close more quickly a connection, it's recommanded
                 * to set linger to a small value.
                 * 
                 * AJP13 connection SHOULD be closed under webserver responsability and 
                 * in such case it's safe to close socket on Tomcat side without delay,
                 * which may be also the case for HTTP connectors.
                 * 
                 * I (henri) recommand to set Linger to 0, making socket closed immediatly
                 * so the OS will free faster the underlying io descriptor and resources.
                 * It's very important under heavy load !
                 */
                
                if (connectionLinger < 0)
                	socket.setSoLinger(false, 0);
                else	
                	socket.setSoLinger(true, connectionLinger);
                	
                /* We don't need it since it's the native side which 
                 * will set the connection with keep alive
                 * if specified in workers.properties.
                 * 
                 * socket.setKeepAlive(true); 
                 */
                
                /* Warning :
                 * 
                 * AJP13 shouldn't use socket timeout on tomcat site since
                 * when Tomcat close a connection after a timeout is reached
                 * the socket stay in half-closed state until the webserver
                 * try to send a request to tomcat and detect the socket close
                 * when it will try to read the reply.
                 * 
                 * On many Unix platforms the write() call didn't told
                 * webserver that the socket is closed.
                 */
                 
                if (connectionTimeout >= 0) {
                    socket.setSoTimeout(connectionTimeout);
                }
            } catch (AccessControlException ace) {
                logger.log("socket accept security exception: "
                           + ace.getMessage());
                continue;
	    } catch (IOException e) {
		if (started && !stopped)
		    logger.log("accept: ", e);
		try {
                    if (serverSocket != null) {
                        serverSocket.close();
                    }
                    if (stopped) {
                        if (debug > 0) {
                            logger.log("run():  stopped, so breaking");
                        }
                        break;
                    } else {
                        if (debug > 0) {
                            logger.log("run():  not stopped, " +
                                       "so reopening server socket");
                        }
                        serverSocket = open();
                    }
                } catch (IOException ex) {
                    // If reopening fails, exit
                    logger.log("socket reopen: ", ex);
                    break;
                }
                continue;
	    }

	    // Hand this socket off to an appropriate processor
            if (debug > 0) {
                synchronized(processors) {
                    logger.log("about to create a processor, available="
                               + processors.size() + ", created=" + created.size()
                               + ", maxProcessors=" + maxProcessors);
                }
            }
	    Ajp13Processor processor = createProcessor();
	    if (processor == null) {
		try {
		    logger.log(sm.getString("ajp13Connector.noProcessor"));
		    socket.close();
		} catch (IOException e) {
		    ;
		}
		continue;
	    }
	    processor.assign(socket);

	    // The processor will recycle itself when it finishes

	}

	// Notify the threadStop() method that we have shut ourselves down
	synchronized (threadSync) {
	    threadSync.notifyAll();
	}

    }


    /**
     * Start the background processing thread.
     */
    private void threadStart() {

	logger.log(sm.getString("ajp13Connector.starting"));

	thread = new Thread(threadGroup, this, threadName);
	thread.setDaemon(true);
	thread.start();

    }


    /**
     * Stop the background processing thread.
     */
    private void threadStop() {

	logger.log(sm.getString("ajp13Connector.stopping"));

	stopped = true;
	synchronized (threadSync) {
	    try {
		threadSync.wait(5000);
	    } catch (InterruptedException e) {
		;
	    }
	}
	thread = null;

    }


    // ------------------------------------------------------ Lifecycle Methods


    /**
     * Add a lifecycle event listener to this component.
     *
     * @param listener The listener to add
     */
    public void addLifecycleListener(LifecycleListener listener) {

	lifecycle.addLifecycleListener(listener);

    }

    /**
     * Get the lifecycle listeners associated with this lifecycle. If this
     * Lifecycle has no listeners registered, a zero-length array is returned.
     */
    public LifecycleListener[] findLifecycleListeners() {
        return null; // FIXME: lifecycle.findLifecycleListeners();
    }


    /**
     * Remove a lifecycle event listener from this component.
     *
     * @param listener The listener to add
     */
    public void removeLifecycleListener(LifecycleListener listener) {

	lifecycle.removeLifecycleListener(listener);

    }


    /**
     * Begin processing requests via this Connector.
     *
     * @exception LifecycleException if a fatal startup error occurs
     */
    public void start() throws LifecycleException {

	// Validate and update our current state
	if (started)
	    throw new LifecycleException
		(sm.getString("ajp13Connector.alreadyStarted"));

        if (debug > 0) {
            debugThread = new DebugThread();
            debugThread.setDaemon(true);
            debugThread.start();
        }

        threadName = "Ajp13Connector[" + port + "]";
        threadGroup = new ThreadGroup(threadName);
        threadGroup.setDaemon(true);
        logger.setConnector(this);
        logger.setName(threadName);
	lifecycle.fireLifecycleEvent(START_EVENT, null);
	started = true;

	// Establish a server socket on the specified port
	try {
	    serverSocket = open();
	} catch (IOException e) {
	    throw new LifecycleException(threadName + ".open", e);
	}

	// Start our background thread
	threadStart();

	// Create the specified minimum number of processors
	while (curProcessors < minProcessors) {
	    if ((maxProcessors > 0) && (curProcessors >= maxProcessors))
		break;
	    Ajp13Processor processor = newProcessor();
	    recycle(processor);
	}

    }


    /**
     * Terminate processing requests via this Connector.
     *
     * @exception LifecycleException if a fatal shutdown error occurs
     */
    public void stop() throws LifecycleException {

	// Validate and update our current state
	if (!started)
	    throw new LifecycleException
		(sm.getString("ajp13Connector.notStarted"));
	lifecycle.fireLifecycleEvent(STOP_EVENT, null);
	started = false;

	// Gracefully shut down all processors we have created
	for (int i = created.size() - 1; i >= 0; i--) {
	    Ajp13Processor processor = (Ajp13Processor) created.elementAt(i);
	    if (processor instanceof Lifecycle) {
		try {
		    ((Lifecycle) processor).stop();
		} catch (LifecycleException e) {
		    logger.log("Ajp13Connector.stop", e);
		}
	    }
	}

	// Stop our background thread
	threadStop();

	// Close the server socket we were using
	if (serverSocket != null) {
	    try {
		serverSocket.close();
	    } catch (IOException e) {
		;
	    }
	    serverSocket = null;
	}

    }

    /**
     * Debugging thread used to debug thread activity in this
     * connector.
     */
    private class DebugThread extends Thread
    {
        public void run() {
            while (true) {
                try {
                    sleep(60 * 1000);
                } catch (InterruptedException e) {
                    break;
                }
                logger.log("active threads=" + threadGroup.activeCount());
                System.out.println("===================================");
                System.out.println("Ajp13Connector active threads="
                                   + threadGroup.activeCount());
                threadGroup.list();
                System.out.println("===================================");
            }
        }
    }

}
