001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-nio/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java $
003: * $Revision: 610464 $
004: * $Date: 2008-01-09 18:10:55 +0100 (Wed, 09 Jan 2008) $
005: *
006: * ====================================================================
007: * Licensed to the Apache Software Foundation (ASF) under one
008: * or more contributor license agreements. See the NOTICE file
009: * distributed with this work for additional information
010: * regarding copyright ownership. The ASF licenses this file
011: * to you under the Apache License, Version 2.0 (the
012: * "License"); you may not use this file except in compliance
013: * with the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing,
018: * software distributed under the License is distributed on an
019: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020: * KIND, either express or implied. See the License for the
021: * specific language governing permissions and limitations
022: * under the License.
023: * ====================================================================
024: *
025: * This software consists of voluntary contributions made by many
026: * individuals on behalf of the Apache Software Foundation. For more
027: * information on the Apache Software Foundation, please see
028: * <http://www.apache.org/>.
029: *
030: */
031:
032: package org.apache.http.examples.nio;
033:
034: import java.io.File;
035: import java.io.IOException;
036: import java.io.InterruptedIOException;
037: import java.io.OutputStream;
038: import java.io.OutputStreamWriter;
039: import java.net.InetSocketAddress;
040: import java.net.URL;
041: import java.net.URLDecoder;
042: import java.security.KeyStore;
043:
044: import javax.net.ssl.KeyManager;
045: import javax.net.ssl.KeyManagerFactory;
046: import javax.net.ssl.SSLContext;
047:
048: import org.apache.http.HttpEntity;
049: import org.apache.http.HttpEntityEnclosingRequest;
050: import org.apache.http.HttpException;
051: import org.apache.http.HttpRequest;
052: import org.apache.http.HttpResponse;
053: import org.apache.http.HttpStatus;
054: import org.apache.http.MethodNotSupportedException;
055: import org.apache.http.entity.ContentProducer;
056: import org.apache.http.entity.EntityTemplate;
057: import org.apache.http.entity.FileEntity;
058: import org.apache.http.impl.DefaultConnectionReuseStrategy;
059: import org.apache.http.impl.DefaultHttpResponseFactory;
060: import org.apache.http.params.BasicHttpParams;
061: import org.apache.http.impl.nio.SSLServerIOEventDispatch;
062: import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
063: import org.apache.http.nio.NHttpConnection;
064: import org.apache.http.nio.protocol.EventListener;
065: import org.apache.http.nio.protocol.BufferingHttpServiceHandler;
066: import org.apache.http.nio.reactor.IOEventDispatch;
067: import org.apache.http.nio.reactor.ListeningIOReactor;
068: import org.apache.http.params.CoreConnectionPNames;
069: import org.apache.http.params.HttpParams;
070: import org.apache.http.params.CoreProtocolPNames;
071: import org.apache.http.protocol.BasicHttpProcessor;
072: import org.apache.http.protocol.HttpContext;
073: import org.apache.http.protocol.HttpRequestHandler;
074: import org.apache.http.protocol.HttpRequestHandlerRegistry;
075: import org.apache.http.protocol.ResponseConnControl;
076: import org.apache.http.protocol.ResponseContent;
077: import org.apache.http.protocol.ResponseDate;
078: import org.apache.http.protocol.ResponseServer;
079: import org.apache.http.util.EntityUtils;
080:
081: public class NHttpSSLServer {
082:
083: public static void main(String[] args) throws Exception {
084: if (args.length < 1) {
085: System.err
086: .println("Please specify document root directory");
087: System.exit(1);
088: }
089:
090: ClassLoader cl = NHttpSSLServer.class.getClassLoader();
091: URL url = cl.getResource("test.keystore");
092: KeyStore keystore = KeyStore.getInstance("jks");
093: keystore.load(url.openStream(), "nopassword".toCharArray());
094: KeyManagerFactory kmfactory = KeyManagerFactory
095: .getInstance(KeyManagerFactory.getDefaultAlgorithm());
096: kmfactory.init(keystore, "nopassword".toCharArray());
097: KeyManager[] keymanagers = kmfactory.getKeyManagers();
098: SSLContext sslcontext = SSLContext.getInstance("TLS");
099: sslcontext.init(keymanagers, null, null);
100:
101: HttpParams params = new BasicHttpParams();
102: params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
103: .setIntParameter(
104: CoreConnectionPNames.SOCKET_BUFFER_SIZE,
105: 8 * 1024).setBooleanParameter(
106: CoreConnectionPNames.STALE_CONNECTION_CHECK,
107: false).setBooleanParameter(
108: CoreConnectionPNames.TCP_NODELAY, true)
109: .setParameter(CoreProtocolPNames.ORIGIN_SERVER,
110: "Jakarta-HttpComponents-NIO/1.1");
111:
112: BasicHttpProcessor httpproc = new BasicHttpProcessor();
113: httpproc.addInterceptor(new ResponseDate());
114: httpproc.addInterceptor(new ResponseServer());
115: httpproc.addInterceptor(new ResponseContent());
116: httpproc.addInterceptor(new ResponseConnControl());
117:
118: BufferingHttpServiceHandler handler = new BufferingHttpServiceHandler(
119: httpproc, new DefaultHttpResponseFactory(),
120: new DefaultConnectionReuseStrategy(), params);
121:
122: // Set up request handlers
123: HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
124: reqistry.register("*", new HttpFileHandler(args[0]));
125:
126: handler.setHandlerResolver(reqistry);
127:
128: // Provide an event logger
129: handler.setEventListener(new EventLogger());
130:
131: IOEventDispatch ioEventDispatch = new SSLServerIOEventDispatch(
132: handler, sslcontext, params);
133:
134: ListeningIOReactor ioReactor = new DefaultListeningIOReactor(2,
135: params);
136: try {
137: ioReactor.listen(new InetSocketAddress(8080));
138: ioReactor.execute(ioEventDispatch);
139: } catch (InterruptedIOException ex) {
140: System.err.println("Interrupted");
141: } catch (IOException e) {
142: System.err.println("I/O error: " + e.getMessage());
143: }
144: System.out.println("Shutdown");
145: }
146:
147: static class HttpFileHandler implements HttpRequestHandler {
148:
149: private final String docRoot;
150:
151: public HttpFileHandler(final String docRoot) {
152: super ();
153: this .docRoot = docRoot;
154: }
155:
156: public void handle(final HttpRequest request,
157: final HttpResponse response, final HttpContext context)
158: throws HttpException, IOException {
159:
160: String method = request.getRequestLine().getMethod()
161: .toUpperCase();
162: if (!method.equals("GET") && !method.equals("HEAD")
163: && !method.equals("POST")) {
164: throw new MethodNotSupportedException(method
165: + " method not supported");
166: }
167:
168: if (request instanceof HttpEntityEnclosingRequest) {
169: HttpEntity entity = ((HttpEntityEnclosingRequest) request)
170: .getEntity();
171: byte[] entityContent = EntityUtils.toByteArray(entity);
172: System.out.println("Incoming entity content (bytes): "
173: + entityContent.length);
174: }
175:
176: String target = request.getRequestLine().getUri();
177: final File file = new File(this .docRoot, URLDecoder.decode(
178: target, "UTF-8"));
179: if (!file.exists()) {
180:
181: response.setStatusCode(HttpStatus.SC_NOT_FOUND);
182: EntityTemplate body = new EntityTemplate(
183: new ContentProducer() {
184:
185: public void writeTo(
186: final OutputStream outstream)
187: throws IOException {
188: OutputStreamWriter writer = new OutputStreamWriter(
189: outstream, "UTF-8");
190: writer.write("<html><body><h1>");
191: writer.write("File ");
192: writer.write(file.getPath());
193: writer.write(" not found");
194: writer.write("</h1></body></html>");
195: writer.flush();
196: }
197:
198: });
199: body.setContentType("text/html; charset=UTF-8");
200: response.setEntity(body);
201: System.out.println("File " + file.getPath()
202: + " not found");
203:
204: } else if (!file.canRead() || file.isDirectory()) {
205:
206: response.setStatusCode(HttpStatus.SC_FORBIDDEN);
207: EntityTemplate body = new EntityTemplate(
208: new ContentProducer() {
209:
210: public void writeTo(
211: final OutputStream outstream)
212: throws IOException {
213: OutputStreamWriter writer = new OutputStreamWriter(
214: outstream, "UTF-8");
215: writer.write("<html><body><h1>");
216: writer.write("Access denied");
217: writer.write("</h1></body></html>");
218: writer.flush();
219: }
220:
221: });
222: body.setContentType("text/html; charset=UTF-8");
223: response.setEntity(body);
224: System.out
225: .println("Cannot read file " + file.getPath());
226:
227: } else {
228:
229: response.setStatusCode(HttpStatus.SC_OK);
230: FileEntity body = new FileEntity(file, "text/html");
231: response.setEntity(body);
232: System.out.println("Serving file " + file.getPath());
233:
234: }
235: }
236:
237: }
238:
239: static class EventLogger implements EventListener {
240:
241: public void connectionOpen(final NHttpConnection conn) {
242: System.out.println("Connection open: " + conn);
243: }
244:
245: public void connectionTimeout(final NHttpConnection conn) {
246: System.out.println("Connection timed out: " + conn);
247: }
248:
249: public void connectionClosed(final NHttpConnection conn) {
250: System.out.println("Connection closed: " + conn);
251: }
252:
253: public void fatalIOException(final IOException ex,
254: final NHttpConnection conn) {
255: System.err.println("I/O error: " + ex.getMessage());
256: }
257:
258: public void fatalProtocolException(final HttpException ex,
259: final NHttpConnection conn) {
260: System.err.println("HTTP error: " + ex.getMessage());
261: }
262:
263: }
264:
265: }
|