/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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("===================================");
            }
        }
    }

}
