/*
 * Copyright 2005 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.
 */

/**
   Provides a simple high-level Http server API, which can be used to build
   embedded HTTP servers. Both "http" and "https" are supported. The API provides
   a partial implementation of RFC <a href="http://www.ietf.org/rfc/rfc2616.txt">2616</a> (HTTP 1.1)
   and RFC <a href="http://www.ietf.org/rfc/rfc2818.txt">2818</a> (HTTP over TLS).
   Any HTTP functionality not provided by this API can be implemented by application code
   using the API.
   <p>
   Programmers must implement the {@link com.sun.net.httpserver.HttpHandler} interface. This interface
   provides a callback which is invoked to handle incoming requests from clients.
   A HTTP request and its response is known as an exchange. HTTP exchanges are
   represented by the {@link com.sun.net.httpserver.HttpExchange} class.
   The {@link com.sun.net.httpserver.HttpServer} class is used to listen for incoming TCP connections
   and it dispatches requests on these connections to handlers which have been
   registered with the server.
   <p>
   A minimal Http server example is shown below:
   <blockquote><pre>
   class MyHandler implements HttpHandler {
       public void handle(HttpExchange t) throws IOException {
           InputStream is = t.getRequestBody();
           read(is); // .. read the request body
           String response = "This is the response";
           t.sendResponseHeaders(200, response.length());
           OutputStream os = t.getResponseBody();
           os.write(response.getBytes());
           os.close();
       }
   }
   ...

   HttpServer server = HttpServer.create(new InetSocketAddress(8000));
   server.createContext("/applications/myapp", new MyHandler());
   server.setExecutor(null); // creates a default executor
   server.start();
   </blockquote></pre>
   <p>The example above creates a simple HttpServer which uses the calling
   application thread to invoke the handle() method for incoming http
   requests directed to port 8000, and to the path /applications/myapp/.
   <p>
   The {@link com.sun.net.httpserver.HttpExchange} class encapsulates everything an application needs to
   process incoming requests and to generate appropriate responses.
   <p>
   Registering a handler with a HttpServer creates a {@link com.sun.net.httpserver.HttpContext} object and
   {@link com.sun.net.httpserver.Filter}
   objects can be added to the returned context. Filters are used to perform automatic pre- and
   post-processing of exchanges before they are passed to the exchange handler.
   <p>
   For sensitive information, a {@link com.sun.net.httpserver.HttpsServer} can
   be used to process "https" requests secured by the SSL or TLS protocols.
   A HttpsServer must be provided with a
   {@link com.sun.net.httpserver.HttpsConfigurator} object, which contains an
   initialized {@link javax.net.ssl.SSLContext}.
   HttpsConfigurator can be used to configure the
   cipher suites and other SSL operating parameters.
   A simple example SSLContext could be created as follows:
   <blockquote><pre>
   char[] passphrase = "passphrase".toCharArray();
   KeyStore ks = KeyStore.getInstance("JKS");
   ks.load(new FileInputStream("testkeys"), passphrase);

   KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
   kmf.init(ks, passphrase);

   TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
   tmf.init(ks);

   SSLContext ssl = SSLContext.getInstance("TLS");
   ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
   </blockquote></pre>
   <p>
   In the example above, a keystore file called "testkeys", created with the keytool utility
   is used as a certificate store for client and server certificates.
   The following code shows how the SSLContext is then used in a HttpsConfigurator
   and how the SSLContext and HttpsConfigurator are linked to the HttpsServer.
   <blockquote><pre>
    server.setHttpsConfigurator (new HttpsConfigurator(sslContext) {
        public void configure (HttpsParameters params) {

        // get the remote address if needed
        InetSocketAddress remote = params.getClientAddress();

        SSLContext c = getSSLContext();

        // get the default parameters
        SSLParameters sslparams = c.getDefaultSSLParameters();
        if (remote.equals (...) ) {
            // modify the default set for client x
        }

        params.setSSLParameters(sslparams);
        // statement above could throw IAE if any params invalid.
        // eg. if app has a UI and parameters supplied by a user.

        }
    });
   </blockquote></pre>
   <p>
   @since 1.6
 */
package com.sun.net.httpserver;
