Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  *   - Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  *
     11  *   - Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  *
     15  *   - Neither the name of Oracle nor the names of its
     16  *     contributors may be used to endorse or promote products derived
     17  *     from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * This source code is provided to illustrate the usage of a given feature
     34  * or technique and has been deliberately simplified. Additional steps
     35  * required for a production-quality application, such as security checks,
     36  * input validation and proper error handling, might not be present in
     37  * this sample code.
     38  */
     39 
     40 
     41 import java.io.*;
     42 import java.net.*;
     43 import java.nio.channels.*;
     44 import java.security.*;
     45 import javax.net.ssl.*;
     46 
     47 /**
     48  * The main server base class.
     49  * <P>
     50  * This class is responsible for setting up most of the server state
     51  * before the actual server subclasses take over.
     52  *
     53  * @author Mark Reinhold
     54  * @author Brad R. Wetmore
     55  */
     56 public abstract class Server {
     57 
     58     ServerSocketChannel ssc;
     59     SSLContext sslContext = null;
     60 
     61     static private int PORT = 8000;
     62     static private int BACKLOG = 1024;
     63     static private boolean SECURE = false;
     64 
     65     Server(int port, int backlog,
     66             boolean secure) throws Exception {
     67 
     68         if (secure) {
     69             createSSLContext();
     70         }
     71 
     72         ssc = ServerSocketChannel.open();
     73         ssc.socket().setReuseAddress(true);
     74         ssc.socket().bind(new InetSocketAddress(port), backlog);
     75     }
     76 
     77     /*
     78      * If this is a secure server, we now setup the SSLContext we'll
     79      * use for creating the SSLEngines throughout the lifetime of
     80      * this process.
     81      */
     82     private void createSSLContext() throws Exception {
     83 
     84         char[] passphrase = "passphrase".toCharArray();
     85 
     86         KeyStore ks = KeyStore.getInstance("JKS");
     87         ks.load(new FileInputStream("testkeys"), passphrase);
     88 
     89         KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
     90         kmf.init(ks, passphrase);
     91 
     92         TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
     93         tmf.init(ks);
     94 
     95         sslContext = SSLContext.getInstance("TLS");
     96         sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
     97     }
     98 
     99     abstract void runServer() throws Exception;
    100 
    101     static private void usage() {
    102         System.out.println(
    103             "Usage:  Server <type> [options]\n"
    104                 + "     type:\n"
    105                 + "             B1      Blocking/Single-threaded Server\n"
    106                 + "             BN      Blocking/Multi-threaded Server\n"
    107                 + "             BP      Blocking/Pooled-Thread Server\n"
    108                 + "             N1      Nonblocking/Single-threaded Server\n"
    109                 + "             N2      Nonblocking/Dual-threaded Server\n"
    110                 + "\n"
    111                 + "     options:\n"
    112                 + "             -port port              port number\n"
    113                 + "                 default:  " + PORT + "\n"
    114                 + "             -backlog backlog        backlog\n"
    115                 + "                 default:  " + BACKLOG + "\n"
    116                 + "             -secure                 encrypt with SSL/TLS");
    117         System.exit(1);
    118     }
    119 
    120     /*
    121      * Parse the arguments, decide what type of server to run,
    122      * see if there are any defaults to change.
    123      */
    124     static private Server createServer(String args[]) throws Exception {
    125         if (args.length < 1) {
    126             usage();
    127         }
    128 
    129         int port = PORT;
    130         int backlog = BACKLOG;
    131         boolean secure = SECURE;
    132 
    133         for (int i = 1; i < args.length; i++) {
    134             if (args[i].equals("-port")) {
    135                 checkArgs(i, args.length);
    136                 port = Integer.valueOf(args[++i]);
    137             } else if (args[i].equals("-backlog")) {
    138                 checkArgs(i, args.length);
    139                 backlog = Integer.valueOf(args[++i]);
    140             } else if (args[i].equals("-secure")) {
    141                 secure = true;
    142             } else {
    143                 usage();
    144             }
    145         }
    146 
    147         Server server = null;
    148 
    149         if (args[0].equals("B1")) {
    150             server = new B1(port, backlog, secure);
    151         } else if (args[0].equals("BN")) {
    152             server = new BN(port, backlog, secure);
    153         } else if (args[0].equals("BP")) {
    154             server = new BP(port, backlog, secure);
    155         } else if (args[0].equals("N1")) {
    156             server = new N1(port, backlog, secure);
    157         } else if (args[0].equals("N2")) {
    158             server = new N2(port, backlog, secure);
    159         }
    160 
    161         return server;
    162     }
    163 
    164     static private void checkArgs(int i, int len) {
    165         if ((i + 1) >= len) {
    166            usage();
    167         }
    168     }
    169 
    170     static public void main(String args[]) throws Exception {
    171         Server server = createServer(args);
    172 
    173         if (server == null) {
    174             usage();
    175         }
    176 
    177         System.out.println("Server started.");
    178         server.runServer();
    179     }
    180 }
    181