1 A Simple NIO-based HTTP/HTTPS Server Example 2 3 4INTRODUCTION 5============ 6This directory contains a simple HTTP/HTTPS server. HTTP/HTTPS are two 7common network protocols that provide for data transfer, and are more 8fully described in RFC 2616 and RFC 2818 (Available at 9http://www.ietf.org ). HTTPS is essentially HTTP after the connection 10has been secured with SSL/TLS. TLS is the successor to SSL, and is 11described in RFC 2246. 12 13This server was written to demonstrate some of the functionality new to 14the Java 2 platform. The demo is not meant to be a full tutorial, and 15assumes the reader has some familiarity with the subject matter. 16 17In particular, it shows: 18 19 New I/O (java.nio, java.nio.channels, java.util.regex, java.nio.charset) 20 21 Introduced in version 1.4 of the platform, NIO was designed to 22 overcome some of the scalability limitations found in the 23 existing blocking java.net.* API's, and to address other 24 concepts such as Regular Expression parsing and Character 25 Sets. 26 27 This server demonstrates: 28 29 ByteBuffer 30 Blocking and Non-Blocking I/O 31 SocketChannel 32 ServerSocketChannel 33 Selector 34 CharacterSet 35 Pattern matching using Regular Expressions 36 37 JSSE (javax.net.ssl) 38 39 Introduced in version 1.4 of the platform, JSSE provides 40 network security using SSL/TLS for java.net.Socket-based 41 traffic. In version 1.5, the SSLEngine API was introduced 42 which separates the SSL/TLS functionality from the underlying 43 I/O model. By making this separation, applications can adapt 44 I/O and compute strategies to best fit their circumstances. 45 46 This server demonstrates: 47 48 Using SSLEngine to create a HTTPS server 49 Creating simple key material for use with HTTPS 50 51 Concurrency Library (java.util.concurrent) 52 53 Introduced in version 1.5 of the platform, the concurrency 54 library provides a mechanism which decouples task submission 55 from the mechanics of how each task will be run. 56 57 This server demonstrates: 58 59 A ThreadPool with a fixed number of threads, which is 60 based on the number of available processors. 61 62 63SETUP 64===== 65 66The server must be built on version 1.5 (or later) of the platform. 67Invoking the following should be sufficient: 68 69 % mkdir build 70 % javac -source 1.5 -target 1.5 -d build *.java 71 72The following creates the document root: 73 74 % mkdir root 75 76All documents should be placed in this directory. 77 78For HTTPS, the server authenticates itself to clients by using simple 79Public Key Infrastructure (PKI) credentials in the form of 80X509Certificates. You must create the server's credentials before 81attempting to run the server in "-secure" mode. The server is 82currently hardcoded to look for its credentials in a file called 83"testkeys". 84 85In this example, we'll create credentials for a fictional widget web 86site owned by the ubiquitous "Xyzzy, Inc.". When you run this in your 87own environment, replace "widgets.xyzzy.com" with the hostname of your 88server. 89 90The easiest way to create the SSL/TLS credentials is to use the 91java keytool, by doing the following: 92 93 (<CR> represents your end-of-line key) 94 95 % keytool -genkey -keyalg rsa -keystore testkeys -alias widgets 96 Enter keystore password: passphrase 97 What is your first and last name? 98 [Unknown]: widgets.xyzzy.com<CR> 99 What is the name of your organizational unit? 100 [Unknown]: Consumer Widgets Group<CR> 101 What is the name of your organization? 102 [Unknown]: Xyzzy, Inc.<CR> 103 What is the name of your City or Locality? 104 [Unknown]: Arcata<CR> 105 What is the name of your State or Province? 106 [Unknown]: CA<CR> 107 What is the two-letter country code for this unit? 108 [Unknown]: US<CR> 109 Is CN=widgets.xyzzy.com, OU=Consumer Widgets Group, O="Xyzzy, Inc.", 110 L=Arcata, ST=CA, C=US correct? 111 [no]: yes<CR> 112 113 Enter key password for <mykey> 114 (RETURN if same as keystore password): <CR> 115 116This directory also contain a very simple URL reader (URLDumper), which 117connects to a specified URL and places all output into a specified file. 118 119 120SERVER EXECUTION 121================ 122 123 % java -classpath build Server N1 124 125 Usage: Server <type> [options] 126 type: 127 B1 Blocking/Single-threaded Server 128 BN Blocking/Multi-threaded Server 129 BP Blocking/Pooled-thread Server 130 N1 Nonblocking/Single-threaded Server 131 N2 Nonblocking/Dual-threaded Server 132 133 options: 134 -port port port number 135 default: 8000 136 -backlog backlog backlog 137 default: 1024 138 -secure encrypt with SSL/TLS 139 default is insecure 140 141"http://" URLs should be used with insecure mode, and 142"https://" for secure mode. 143 144The "B*" servers use classic blocking I/O: in other words, calls to 145read()/write() will not return until the I/O operation has completed. The 146"N*" servers use non-blocking mode and Selectors to determine which 147Channels are ready to perform I/O. 148 149B1: A single-threaded server which completely services each 150 connection before moving to the next. 151 152B2: A multi-threaded server which creates a new thread for each 153 connection. This is not efficient for large numbers of 154 connections. 155 156BP: A multi-threaded server which creates a pool of threads for use 157 by the server. The Thread pool decides how to schedule those 158 threads. 159 160N1: A single-threaded server. All accept() and read()/write() 161 operations are performed by a single thread, but only after 162 being selected for those operations by a Selector. 163 164N2: A dual-threaded server which performs accept()s in one thread, and 165 services requests in a second. Both threads use select(). 166 167 168CLIENT EXECUTION 169================ 170You can test the server using any standard browser such as Internet 171Explorer or Mozilla, but since the browser will not trust the 172credentials you just created, you may need to accept the credentials 173via the browser's pop-up dialog box. 174 175Alternatively, to use the certificates using the simple included JSSE 176client URLDumper, export the server certificate into a new truststore, 177and then run the application using the new truststore. 178 179 % keytool -export -keystore testkeys -alias widgets -file widgets.cer 180 Enter keystore password: passphrase<CR> 181 Certificate stored in file <widgets.cer> 182 183 % keytool -import -keystore trustCerts -alias widgetServer \ 184 -file widgets.cer 185 Enter keystore password: passphrase<CR> 186 Owner: CN=widgets.xyzzy.com, OU=Consumer, O="xyzzy, inc.", L=Arcata, 187 ST=CA, C=US 188 Issuer: CN=widgets.xyzzy.com, OU=Consumer, O="xyzzy, inc.", 189 L=Arcata, ST=CA, C=US 190 Serial number: 4086cc7a 191 Valid from: Wed Apr 21 12:33:14 PDT 2004 until: Tue Jul 20 12:33:14 192 PDT 2004 193 Certificate fingerprints: 194 MD5: 39:71:42:CD:BF:0D:A9:8C:FB:8B:4A:CD:F8:6D:19:1F 195 SHA1: 69:5D:38:E9:F4:6C:E5:A7:4C:EA:45:8E:FB:3E:F3:9A:84:01:6F:22 196 Trust this certificate? [no]: yes<CR> 197 Certificate was added to keystore 198 199 % java -classpath build -Djavax.net.ssl.trustStore=trustCerts \ 200 -Djavax.net.ssl.TrustStorePassword=passphrase \ 201 URLDumper https://widgets.xyzzy.com:8000/ outputFile 202 203NOTE: The server must be run with "-secure" in order to receive 204"https://" URLs. 205 206WARNING: This is just a simple example for code exposition, you should 207spend more time understanding PKI security concerns. 208 209 210SOURCE CODE OVERVIEW 211==================== 212 213The main class is Server, which handles program startup, and is 214subclassed by the "B*" and "N*" server classes. 215 216Following a successful accept(), the "B*" variants each create a 217RequestServicer object to perform the actual request/reply operations. The 218primary differences between the different "B*" servers is how the 219RequestServicer is actually run: 220 221 B1: RequestServicer.run() is directly called. 222 BN: A new thread is started, and the thread calls RequestServicer.run(). 223 BP: A ThreadPool is created, and the pool framework is given Runnable 224 tasks to complete. 225 226In the "N*" variations, a Dispatcher object is created, which is 227responsible for performing the select, and then issuing the 228corresponding handler: 229 230 N1: A single thread is used for all accept()/read()/write() operations 231 N2: Similar to N1, but a separate thread is used for the accept() 232 operations. 233 234In all cases, once the connection has been accepted, a ChannelIO object 235is created to handle all I/O. In the insecure case, the corresponding 236SocketChannel methods are directly called. However in the secure case, 237more manipulations are needed to first secure the channel, then 238encrypt/decrypt the data, and finally properly send any shutdown 239messages. ChannelIOSecure extends ChannelIO, and provides the secure 240variants of the corresponding ChannelIO calls. 241 242RequestServicer and RequestHandler are the main drivers for the 243blocking and non-blocking variants, respectively. They are responsible 244for: 245 246 Performing any initial handshaking 247 248 Reading the request data 249 All data is stored in a local buffer in the ChannelIO 250 structure. 251 252 Parsing the request 253 The request data is obtained from the ChannelIO object, and 254 is processed by Request class, which represents the 255 parsed URI address. 256 257 Locating/preparing/sending the data or reporting error conditions. 258 A Reply object is created which represents the entire object to send, 259 including the HTTP/HTTPS headers. 260 261 Shutdown/closing the channel. 262 263 264CLOSING THOUGHTS 265================ 266This example represents a simple server: it is not production quality. 267It was primarily meant to demonstrate the new APIs in versions 1.4 and 2681.5 of the platform. 269 270This example could certainly be expanded to address other areas of 271concern: for example, assigning multiple threads to handle the selected 272Channels, or delegating SSLEngine tasks to multiple threads. There are 273so many ways to implement compute and I/O strategies, we encourage you 274to experiment and find what works best for your situation. 275 276To steal a phrase from many textbooks: 277 278 "It is left as an exercise for the reader..." 279 280