/*
 * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.net.httpserver;

import java.net.*;
import java.io.*;
import java.nio.*;
import java.security.*;
import java.nio.channels.*;
import java.util.*;
import java.util.concurrent.*;
import javax.net.ssl.*;
import com.sun.net.httpserver.spi.HttpServerProvider;

/**
 * This class implements a simple HTTP server. A HttpServer is bound to an IP address
 * and port number and listens for incoming TCP connections from clients on this address.
 * The sub-class {@link HttpsServer} implements a server which handles HTTPS requests.
 * <p>
 * One or more {@link HttpHandler} objects must be associated with a server
 * in order to process requests. Each such HttpHandler is registered
 * with a root URI path which represents the
 * location of the application or service on this server. The mapping of a handler
 * to a HttpServer is encapsulated by a {@link HttpContext} object. HttpContexts
 * are created by calling {@link #createContext(String,HttpHandler)}.
 * Any request for which no handler can be found is rejected with a 404 response.
 * Management of threads can be done external to this object by providing a
 * {@link java.util.concurrent.Executor} object. If none is provided a default
 * implementation is used.
 * <p>
 * <a name="mapping_description"></a>
 * <b>Mapping request URIs to HttpContext paths</b><p>
 * When a HTTP request is received,
 * the appropriate HttpContext (and handler) is located by finding the context
 * whose path is the longest matching prefix of the request URI's path.
 * Paths are matched literally, which means that the strings are compared
 * case sensitively, and with no conversion to or from any encoded forms.
 * For example. Given a HttpServer with the following HttpContexts configured.<p>
 * <table >
 * <tr><td><i>Context</i></td><td><i>Context path</i></td></tr>
 * <tr><td>ctx1</td><td>"/"</td></tr>
 * <tr><td>ctx2</td><td>"/apps/"</td></tr>
 * <tr><td>ctx3</td><td>"/apps/foo/"</td></tr>
 * </table>
 * <p>
 * the following table shows some request URIs and which, if any context they would
 * match with.<p>
 * <table>
 * <tr><td><i>Request URI</i></td><td><i>Matches context</i></td></tr>
 * <tr><td>"http://foo.com/apps/foo/bar"</td><td>ctx3</td></tr>
 * <tr><td>"http://foo.com/apps/Foo/bar"</td><td>no match, wrong case</td></tr>
 * <tr><td>"http://foo.com/apps/app1"</td><td>ctx2</td></tr>
 * <tr><td>"http://foo.com/foo"</td><td>ctx1</td></tr>
 * </table>
 * <p>
 * <b>Note about socket backlogs</b><p>
 * When binding to an address and port number, the application can also specify an integer
 * <i>backlog</i> parameter. This represents the maximum number of incoming TCP connections
 * which the system will queue internally. Connections are queued while they are waiting to
 * be accepted by the HttpServer. When the limit is reached, further connections may be
 * rejected (or possibly ignored) by the underlying TCP implementation. Setting the right
 * backlog value is a compromise between efficient resource usage in the TCP layer (not setting
 * it too high) and allowing adequate throughput of incoming requests (not setting it too low).
 * @since 1.6
 */

public abstract class HttpServer {

    /**
     */
    protected HttpServer () {
    }

    /**
     * creates a HttpServer instance which is initially not bound to any local address/port.
     * The HttpServer is acquired from the currently installed {@link HttpServerProvider}
     * The server must be bound using {@link #bind(InetSocketAddress,int)} before it can be used.
     * @throws IOException
     */
    public static HttpServer create () throws IOException {
        return create (null, 0);
    }

    /**
     * Create a <code>HttpServer</code> instance which will bind to the
     * specified {@link java.net.InetSocketAddress} (IP address and port number)
     *
     * A maximum backlog can also be specified. This is the maximum number of
     * queued incoming connections to allow on the listening socket.
     * Queued TCP connections exceeding this limit may be rejected by the TCP implementation.
     * The HttpServer is acquired from the currently installed {@link HttpServerProvider}
     *
     * @param addr the address to listen on, if <code>null</code> then bind() must be called
     *  to set the address
     * @param backlog the socket backlog. If this value is less than or equal to zero,
     *          then a system default value is used.
     * @throws BindException if the server cannot bind to the requested address,
     *          or if the server is already bound.
     * @throws IOException
     */

    public static HttpServer create (
        InetSocketAddress addr, int backlog
    ) throws IOException {
        HttpServerProvider provider = HttpServerProvider.provider();
        return provider.createHttpServer (addr, backlog);
    }

    /**
     * Binds a currently unbound HttpServer to the given address and port number.
     * A maximum backlog can also be specified. This is the maximum number of
     * queued incoming connections to allow on the listening socket.
     * Queued TCP connections exceeding this limit may be rejected by the TCP implementation.
     * @param addr the address to listen on
     * @param backlog the socket backlog. If this value is less than or equal to zero,
     *          then a system default value is used.
     * @throws BindException if the server cannot bind to the requested address or if the server
     *          is already bound.
     * @throws NullPointerException if addr is <code>null</code>
     */
    public abstract void bind (InetSocketAddress addr, int backlog) throws IOException;

    /**
     * Starts this server in a new background thread. The background thread
     * inherits the priority, thread group and context class loader
     * of the caller.
     */
    public abstract void start () ;

    /**
     * sets this server's {@link java.util.concurrent.Executor} object. An
     * Executor must be established before {@link #start()} is called.
     * All HTTP requests are handled in tasks given to the executor.
     * If this method is not called (before start()) or if it is
     * called with a <code>null</code> Executor, then
     * a default implementation is used, which uses the thread
     * which was created by the {@link #start()} method.
     * @param executor the Executor to set, or <code>null</code> for  default
     *          implementation
     * @throws IllegalStateException if the server is already started
     */
    public abstract void setExecutor (Executor executor);


    /**
     * returns this server's Executor object if one was specified with
     * {@link #setExecutor(Executor)}, or <code>null</code> if none was
     * specified.
     * @return the Executor established for this server or <code>null</code> if not set.
     */
    public abstract Executor getExecutor () ;

    /**
     * stops this server by closing the listening socket and disallowing
     * any new exchanges from being processed. The method will then block
     * until all current exchange handlers have completed or else when
     * approximately <i>delay</i> seconds have elapsed (whichever happens
     * sooner). Then, all open TCP connections are closed, the background
     * thread created by start() exits, and the method returns.
     * Once stopped, a HttpServer cannot be re-used. <p>
     *
     * @param delay the maximum time in seconds to wait until exchanges have finished.
     * @throws IllegalArgumentException if delay is less than zero.
     */
    public abstract void stop (int delay);

    /**
     * Creates a HttpContext. A HttpContext represents a mapping from a
     * URI path to a exchange handler on this HttpServer. Once created, all requests
     * received by the server for the path will be handled by calling
     * the given handler object. The context is identified by the path, and
     * can later be removed from the server using this with the {@link #removeContext(String)} method.
     * <p>
     * The path specifies the root URI path for this context. The first character of path must be
     * '/'. <p>
     * The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a>
     * to HttpContext instances.
     * @param path the root URI path to associate the context with
     * @param handler the handler to invoke for incoming requests.
     * @throws IllegalArgumentException if path is invalid, or if a context
     *          already exists for this path
     * @throws NullPointerException if either path, or handler are <code>null</code>
     */
    public abstract HttpContext createContext (String path, HttpHandler handler) ;

    /**
     * Creates a HttpContext without initially specifying a handler. The handler must later be specified using
     * {@link HttpContext#setHandler(HttpHandler)}.  A HttpContext represents a mapping from a
     * URI path to an exchange handler on this HttpServer. Once created, and when
     * the handler has been set, all requests
     * received by the server for the path will be handled by calling
     * the handler object. The context is identified by the path, and
     * can later be removed from the server using this with the {@link #removeContext(String)} method.
     * <p>
     * The path specifies the root URI path for this context. The first character of path must be
     * '/'. <p>
     * The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a>
     * to HttpContext instances.
     * @param path the root URI path to associate the context with
     * @throws IllegalArgumentException if path is invalid, or if a context
     *          already exists for this path
     * @throws NullPointerException if path is <code>null</code>
     */
    public abstract HttpContext createContext (String path) ;

    /**
     * Removes the context identified by the given path from the server.
     * Removing a context does not affect exchanges currently being processed
     * but prevents new ones from being accepted.
     * @param path the path of the handler to remove
     * @throws IllegalArgumentException if no handler corresponding to this
     *          path exists.
     * @throws NullPointerException if path is <code>null</code>
     */
    public abstract void removeContext (String path) throws IllegalArgumentException ;

    /**
     * Removes the given context from the server.
     * Removing a context does not affect exchanges currently being processed
     * but prevents new ones from being accepted.
     * @param context the context to remove
     * @throws NullPointerException if context is <code>null</code>
     */
    public abstract void removeContext (HttpContext context) ;

    /**
     * returns the address this server is listening on
     * @return the address/port number the server is listening on
     */
    public abstract InetSocketAddress getAddress() ;
}
