org.apache.commons.httpclient.server.SimpleHttpServer.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.commons.httpclient.server.SimpleHttpServer.java

Source

/*
 * $Header: /home/data/cvs/rt/org.eclipse.ecf/tests/bundles/org.eclipse.ecf.tests.apache.httpclient.server/src/org/apache/commons/httpclient/server/SimpleHttpServer.java,v 1.2 2009/02/17 21:58:54 slewis Exp $
 * $Revision: 1.2 $
 * $Date: 2009/02/17 21:58:54 $
 *
 * ====================================================================
 *
 *  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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.commons.httpclient.server;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * A simple, but extensible HTTP server, mostly for testing purposes.
 * 
 * @author Christian Kohlschuetter
 * @author Oleg Kalnichevski
 */
public class SimpleHttpServer implements Runnable {
    private static final Log LOG = LogFactory.getLog(SimpleHttpServer.class);

    private String testname = "Simple test";
    private long count = 0;
    private ServerSocket listener = null;
    private Thread t;
    private ThreadGroup tg;
    private boolean stopped = false;

    private SimpleConnSet connections = new SimpleConnSet();

    private HttpRequestHandler requestHandler = null;

    /**
     * Creates a new HTTP server instance, using an arbitrary free TCP port
     * 
     * @throws IOException  if anything goes wrong during initialization
     */
    public SimpleHttpServer() throws IOException {
        this("");
    }

    public SimpleHttpServer(String serverThreadName) throws IOException {
        this(serverThreadName, null, 0);
    }

    /**
     * Creates a new HTTP server instance, using the specified socket
     * factory and the TCP port
     * 
     * @param   port    Desired TCP port
     * @throws IOException 
     * @throws IOException  if anything goes wrong during initialization
     */
    public SimpleHttpServer(SimpleSocketFactory socketfactory, int port) throws IOException {
        this("", socketfactory, port);
    }

    public SimpleHttpServer(String serverThreadName, SimpleSocketFactory socketfactory, int port)
            throws IOException {
        if (socketfactory == null) {
            socketfactory = new SimplePlainSocketFactory();
        }
        listener = socketfactory.createServerSocket(port);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Starting test HTTP server on port " + getLocalPort());
        }
        tg = new ThreadGroup("SimpleHttpServer thread group");
        t = new Thread(tg, this,
                serverThreadName + "(SimpleHttpServer listener at port " + listener.getLocalPort() + ")");
        t.setDaemon(true);
        t.start();
    }

    /**
     * Creates a new HTTP server instance, using the specified TCP port
     * 
     * @param   port    Desired TCP port
     * @throws IOException  if anything goes wrong during initialization
     */
    public SimpleHttpServer(int port) throws IOException {
        this("", null, port);
    }

    public SimpleHttpServer(String serverThreadName, int port) throws IOException {
        this(serverThreadName, null, port);
    }

    public String getTestname() {
        return this.testname;
    }

    public void setTestname(final String testname) {
        this.testname = testname;
    }

    /**
     * Returns the TCP port that this HTTP server instance is bound to.
     *
     * @return  TCP port, or -1 if not running
     */
    public int getLocalPort() {
        return listener.getLocalPort();
    }

    /**
     * Returns the IP address that this HTTP server instance is bound to.
     * @return String representation of the IP address or <code>null</code> if not running
     */
    public String getLocalAddress() {
        InetAddress address = listener.getInetAddress();
        // Ugly work-around for older JDKs
        byte[] octets = address.getAddress();
        if ((octets[0] == 0) && (octets[1] == 0) && (octets[2] == 0) && (octets[3] == 0)) {
            return "localhost";
        } else {
            return address.getHostAddress();
        }
    }

    /**
     * Checks if this HTTP server instance is running.
     * 
     * @return  true/false
     */
    public boolean isRunning() {
        if (t == null) {
            return false;
        }
        return t.isAlive();
    }

    /**
     * Stops this HTTP server instance.
     */
    public synchronized void destroy() {
        if (stopped) {
            return;
        }

        this.stopped = true;
        if (LOG.isDebugEnabled()) {
            LOG.debug("Stopping test HTTP server on port " + getLocalPort());
        }
        tg.interrupt();

        if (listener != null) {
            try {
                listener.close();
            } catch (IOException e) {

            }
        }
        this.connections.shutdown();
    }

    /**
     * Returns the currently used HttpRequestHandler by this SimpleHttpServer
     * 
     * @return The used HttpRequestHandler, or null.
     */
    public HttpRequestHandler getRequestHandler() {
        return requestHandler;
    }

    /**
     * Sets the HttpRequestHandler to be used for this SimpleHttpServer.
     * 
     * @param rh    Request handler to be used, or null to disable.
     */
    public void setRequestHandler(HttpRequestHandler rh) {
        this.requestHandler = rh;
    }

    public void setHttpService(HttpService service) {
        setRequestHandler(new HttpServiceHandler(service));
    }

    public void run() {
        try {
            while (!this.stopped && !Thread.interrupted()) {
                Socket socket = listener.accept();
                try {
                    if (this.requestHandler == null) {
                        socket.close();
                        break;
                    }

                    SimpleHttpServerConnection conn = new SimpleHttpServerConnection(socket);
                    this.connections.addConnection(conn);

                    Thread t = new SimpleConnectionThread(tg, this.testname + " thread " + this.count, conn,
                            this.connections, this.requestHandler);
                    t.setDaemon(true);
                    t.start();
                } catch (IOException e) {
                    LOG.error("I/O error: " + e.getMessage());
                }
                this.count++;
                Thread.sleep(100);
            }
        } catch (InterruptedException accept) {
        } catch (IOException e) {
            if (!stopped) {
                LOG.error("I/O error: " + e.getMessage());
            }
        } finally {
            destroy();
        }
    }
}