001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java $
003: * $Revision: 613298 $
004: * $Date: 2008-01-18 23:09:22 +0100 (Fri, 18 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: package org.apache.http.examples.nio;
032:
033: import java.io.File;
034: import java.io.IOException;
035: import java.io.InterruptedIOException;
036: import java.io.OutputStream;
037: import java.io.OutputStreamWriter;
038: import java.net.InetSocketAddress;
039: import java.net.URLDecoder;
040:
041: import org.apache.http.HttpEntity;
042: import org.apache.http.HttpEntityEnclosingRequest;
043: import org.apache.http.HttpException;
044: import org.apache.http.HttpRequest;
045: import org.apache.http.HttpResponse;
046: import org.apache.http.HttpStatus;
047: import org.apache.http.MethodNotSupportedException;
048: import org.apache.http.entity.ContentProducer;
049: import org.apache.http.entity.EntityTemplate;
050: import org.apache.http.entity.FileEntity;
051: import org.apache.http.impl.DefaultConnectionReuseStrategy;
052: import org.apache.http.impl.DefaultHttpResponseFactory;
053: import org.apache.http.params.BasicHttpParams;
054: import org.apache.http.impl.nio.DefaultServerIOEventDispatch;
055: import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
056: import org.apache.http.nio.NHttpConnection;
057: import org.apache.http.nio.protocol.EventListener;
058: import org.apache.http.nio.protocol.BufferingHttpServiceHandler;
059: import org.apache.http.nio.reactor.IOEventDispatch;
060: import org.apache.http.nio.reactor.ListeningIOReactor;
061: import org.apache.http.params.CoreConnectionPNames;
062: import org.apache.http.params.HttpParams;
063: import org.apache.http.params.CoreProtocolPNames;
064: import org.apache.http.protocol.BasicHttpProcessor;
065: import org.apache.http.protocol.HttpContext;
066: import org.apache.http.protocol.HttpRequestHandler;
067: import org.apache.http.protocol.HttpRequestHandlerRegistry;
068: import org.apache.http.protocol.ResponseConnControl;
069: import org.apache.http.protocol.ResponseContent;
070: import org.apache.http.protocol.ResponseDate;
071: import org.apache.http.protocol.ResponseServer;
072: import org.apache.http.util.EntityUtils;
073:
074: public class NHttpServer {
075:
076: public static void main(String[] args) throws Exception {
077: if (args.length < 1) {
078: System.err
079: .println("Please specify document root directory");
080: System.exit(1);
081: }
082: HttpParams params = new BasicHttpParams();
083: params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
084: .setIntParameter(
085: CoreConnectionPNames.SOCKET_BUFFER_SIZE,
086: 8 * 1024).setBooleanParameter(
087: CoreConnectionPNames.STALE_CONNECTION_CHECK,
088: false).setBooleanParameter(
089: CoreConnectionPNames.TCP_NODELAY, true)
090: .setParameter(CoreProtocolPNames.ORIGIN_SERVER,
091: "HttpComponents/1.1");
092:
093: BasicHttpProcessor httpproc = new BasicHttpProcessor();
094: httpproc.addInterceptor(new ResponseDate());
095: httpproc.addInterceptor(new ResponseServer());
096: httpproc.addInterceptor(new ResponseContent());
097: httpproc.addInterceptor(new ResponseConnControl());
098:
099: BufferingHttpServiceHandler handler = new BufferingHttpServiceHandler(
100: httpproc, new DefaultHttpResponseFactory(),
101: new DefaultConnectionReuseStrategy(), params);
102:
103: // Set up request handlers
104: HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
105: reqistry.register("*", new HttpFileHandler(args[0]));
106:
107: handler.setHandlerResolver(reqistry);
108:
109: // Provide an event logger
110: handler.setEventListener(new EventLogger());
111:
112: IOEventDispatch ioEventDispatch = new DefaultServerIOEventDispatch(
113: handler, params);
114: ListeningIOReactor ioReactor = new DefaultListeningIOReactor(2,
115: params);
116: try {
117: ioReactor.listen(new InetSocketAddress(8080));
118: ioReactor.execute(ioEventDispatch);
119: } catch (InterruptedIOException ex) {
120: System.err.println("Interrupted");
121: } catch (IOException e) {
122: System.err.println("I/O error: " + e.getMessage());
123: }
124: System.out.println("Shutdown");
125: }
126:
127: static class HttpFileHandler implements HttpRequestHandler {
128:
129: private final String docRoot;
130:
131: public HttpFileHandler(final String docRoot) {
132: super ();
133: this .docRoot = docRoot;
134: }
135:
136: public void handle(final HttpRequest request,
137: final HttpResponse response, final HttpContext context)
138: throws HttpException, IOException {
139:
140: String method = request.getRequestLine().getMethod()
141: .toUpperCase();
142: if (!method.equals("GET") && !method.equals("HEAD")
143: && !method.equals("POST")) {
144: throw new MethodNotSupportedException(method
145: + " method not supported");
146: }
147:
148: if (request instanceof HttpEntityEnclosingRequest) {
149: HttpEntity entity = ((HttpEntityEnclosingRequest) request)
150: .getEntity();
151: byte[] entityContent = EntityUtils.toByteArray(entity);
152: System.out.println("Incoming entity content (bytes): "
153: + entityContent.length);
154: }
155:
156: String target = request.getRequestLine().getUri();
157: final File file = new File(this .docRoot, URLDecoder.decode(
158: target, "UTF-8"));
159: if (!file.exists()) {
160:
161: response.setStatusCode(HttpStatus.SC_NOT_FOUND);
162: EntityTemplate body = new EntityTemplate(
163: new ContentProducer() {
164:
165: public void writeTo(
166: final OutputStream outstream)
167: throws IOException {
168: OutputStreamWriter writer = new OutputStreamWriter(
169: outstream, "UTF-8");
170: writer.write("<html><body><h1>");
171: writer.write("File ");
172: writer.write(file.getPath());
173: writer.write(" not found");
174: writer.write("</h1></body></html>");
175: writer.flush();
176: }
177:
178: });
179: body.setContentType("text/html; charset=UTF-8");
180: response.setEntity(body);
181: System.out.println("File " + file.getPath()
182: + " not found");
183:
184: } else if (!file.canRead() || file.isDirectory()) {
185:
186: response.setStatusCode(HttpStatus.SC_FORBIDDEN);
187: EntityTemplate body = new EntityTemplate(
188: new ContentProducer() {
189:
190: public void writeTo(
191: final OutputStream outstream)
192: throws IOException {
193: OutputStreamWriter writer = new OutputStreamWriter(
194: outstream, "UTF-8");
195: writer.write("<html><body><h1>");
196: writer.write("Access denied");
197: writer.write("</h1></body></html>");
198: writer.flush();
199: }
200:
201: });
202: body.setContentType("text/html; charset=UTF-8");
203: response.setEntity(body);
204: System.out
205: .println("Cannot read file " + file.getPath());
206:
207: } else {
208:
209: response.setStatusCode(HttpStatus.SC_OK);
210: FileEntity body = new FileEntity(file, "text/html");
211: response.setEntity(body);
212: System.out.println("Serving file " + file.getPath());
213:
214: }
215: }
216:
217: }
218:
219: static class EventLogger implements EventListener {
220:
221: public void connectionOpen(final NHttpConnection conn) {
222: System.out.println("Connection open: " + conn);
223: }
224:
225: public void connectionTimeout(final NHttpConnection conn) {
226: System.out.println("Connection timed out: " + conn);
227: }
228:
229: public void connectionClosed(final NHttpConnection conn) {
230: System.out.println("Connection closed: " + conn);
231: }
232:
233: public void fatalIOException(final IOException ex,
234: final NHttpConnection conn) {
235: System.err.println("I/O error: " + ex.getMessage());
236: }
237:
238: public void fatalProtocolException(final HttpException ex,
239: final NHttpConnection conn) {
240: System.err.println("HTTP error: " + ex.getMessage());
241: }
242:
243: }
244:
245: }
|