1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.nio.testserver;
29
30 import java.io.IOException;
31 import java.net.SocketException;
32 import java.util.concurrent.TimeUnit;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.apache.http.ConnectionClosedException;
37 import org.apache.http.ExceptionLogger;
38 import org.apache.http.impl.nio.DefaultNHttpServerConnection;
39 import org.apache.http.impl.nio.bootstrap.HttpServer;
40 import org.apache.http.impl.nio.bootstrap.ServerBootstrap;
41 import org.apache.http.impl.nio.reactor.IOReactorConfig;
42 import org.apache.http.nio.NHttpConnectionFactory;
43 import org.apache.http.nio.protocol.HttpAsyncExpectationVerifier;
44 import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
45 import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
46 import org.apache.http.nio.reactor.ListenerEndpoint;
47 import org.apache.http.protocol.HttpProcessor;
48 import org.apache.http.util.Asserts;
49
50 public class HttpServerNio {
51
52 private final UriHttpAsyncRequestHandlerMapper reqistry;
53 private volatile HttpAsyncExpectationVerifier expectationVerifier;
54 private volatile NHttpConnectionFactory<DefaultNHttpServerConnection> connectionFactory;
55 private volatile HttpProcessor httpProcessor;
56 private volatile int timeout;
57
58 private volatile HttpServer server;
59
60 public HttpServerNio() {
61 super();
62 this.reqistry = new UriHttpAsyncRequestHandlerMapper();
63 }
64
65 public int getTimeout() {
66 return this.timeout;
67 }
68
69 public void setTimeout(final int timeout) {
70 this.timeout = timeout;
71 }
72
73 public void registerHandler(
74 final String pattern,
75 final HttpAsyncRequestHandler handler) {
76 this.reqistry.register(pattern, handler);
77 }
78
79 public void setExpectationVerifier(final HttpAsyncExpectationVerifier expectationVerifier) {
80 this.expectationVerifier = expectationVerifier;
81 }
82
83 public void setConnectionFactory(final NHttpConnectionFactory<DefaultNHttpServerConnection> connectionFactory) {
84 this.connectionFactory = connectionFactory;
85 }
86
87 public void setHttpProcessor(final HttpProcessor httpProcessor) {
88 this.httpProcessor = httpProcessor;
89 }
90
91 public ListenerEndpoint getListenerEndpoint() {
92 final HttpServer local = this.server;
93 if (local != null) {
94 return this.server.getEndpoint();
95 } else {
96 throw new IllegalStateException("Server not running");
97 }
98 }
99
100 public void start() throws IOException {
101 Asserts.check(this.server == null, "Server already running");
102 this.server = ServerBootstrap.bootstrap()
103 .setIOReactorConfig(IOReactorConfig.custom()
104 .setSoTimeout(this.timeout)
105 .build())
106 .setServerInfo("TEST-SERVER/1.1")
107 .setConnectionFactory(connectionFactory)
108 .setExceptionLogger(new SimpleExceptionLogger())
109 .setExpectationVerifier(this.expectationVerifier)
110 .setHttpProcessor(this.httpProcessor)
111 .setHandlerMapper(this.reqistry)
112 .create();
113 this.server.start();
114 }
115
116 public void shutdown() {
117 final HttpServer local = this.server;
118 this.server = null;
119 if (local != null) {
120 local.shutdown(5, TimeUnit.SECONDS);
121 }
122 }
123
124 static class SimpleExceptionLogger implements ExceptionLogger {
125
126 private final Log log = LogFactory.getLog(HttpServer.class);
127
128 @Override
129 public void log(final Exception ex) {
130 if (ex instanceof ConnectionClosedException) {
131 this.log.debug(ex.getMessage());
132 } else if (ex instanceof SocketException) {
133 this.log.debug(ex.getMessage());
134 } else {
135 this.log.error(ex.getMessage(), ex);
136 }
137 }
138 }
139
140 }