View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.bootstrap;
28  
29  import java.net.InetAddress;
30  import java.util.HashMap;
31  import java.util.LinkedList;
32  import java.util.Map;
33  
34  import javax.net.ServerSocketFactory;
35  import javax.net.ssl.SSLContext;
36  
37  import org.apache.http.ConnectionReuseStrategy;
38  import org.apache.http.ExceptionLogger;
39  import org.apache.http.HttpConnectionFactory;
40  import org.apache.http.HttpRequestInterceptor;
41  import org.apache.http.HttpResponseFactory;
42  import org.apache.http.HttpResponseInterceptor;
43  import org.apache.http.config.ConnectionConfig;
44  import org.apache.http.config.SocketConfig;
45  import org.apache.http.impl.DefaultBHttpServerConnection;
46  import org.apache.http.impl.DefaultBHttpServerConnectionFactory;
47  import org.apache.http.impl.DefaultConnectionReuseStrategy;
48  import org.apache.http.impl.DefaultHttpResponseFactory;
49  import org.apache.http.protocol.HttpExpectationVerifier;
50  import org.apache.http.protocol.HttpProcessor;
51  import org.apache.http.protocol.HttpProcessorBuilder;
52  import org.apache.http.protocol.HttpRequestHandler;
53  import org.apache.http.protocol.HttpRequestHandlerMapper;
54  import org.apache.http.protocol.HttpService;
55  import org.apache.http.protocol.ResponseConnControl;
56  import org.apache.http.protocol.ResponseContent;
57  import org.apache.http.protocol.ResponseDate;
58  import org.apache.http.protocol.ResponseServer;
59  import org.apache.http.protocol.UriHttpRequestHandlerMapper;
60  
61  /**
62   * @since 4.4
63   */
64  public class ServerBootstrap {
65  
66      private int listenerPort;
67      private InetAddress localAddress;
68      private SocketConfig socketConfig;
69      private ConnectionConfig connectionConfig;
70      private LinkedList<HttpRequestInterceptor> requestFirst;
71      private LinkedList<HttpRequestInterceptor> requestLast;
72      private LinkedList<HttpResponseInterceptor> responseFirst;
73      private LinkedList<HttpResponseInterceptor> responseLast;
74      private String serverInfo;
75      private HttpProcessor httpProcessor;
76      private ConnectionReuseStrategy connStrategy;
77      private HttpResponseFactory responseFactory;
78      private HttpRequestHandlerMapper handlerMapper;
79      private Map<String, HttpRequestHandler> handlerMap;
80      private HttpExpectationVerifier expectationVerifier;
81      private ServerSocketFactory serverSocketFactory;
82      private SSLContext sslContext;
83      private SSLServerSetupHandler sslSetupHandler;
84      private HttpConnectionFactory<? extends DefaultBHttpServerConnection> connectionFactory;
85      private ExceptionLogger exceptionLogger;
86  
87      private ServerBootstrap() {
88      }
89  
90      public static ServerBootstrap bootstrap() {
91          return new ServerBootstrap();
92      }
93  
94      /**
95       * Sets listener port number.
96       */
97      public final ServerBootstrap setListenerPort(final int listenerPort) {
98          this.listenerPort = listenerPort;
99          return this;
100     }
101 
102     /**
103      * Assigns local interface for the listener.
104      */
105     public final ServerBootstrap setLocalAddress(final InetAddress localAddress) {
106         this.localAddress = localAddress;
107         return this;
108     }
109 
110     /**
111      * Sets socket configuration.
112      */
113     public final ServerBootstrap setSocketConfig(final SocketConfig socketConfig) {
114         this.socketConfig = socketConfig;
115         return this;
116     }
117 
118     /**
119      * Sets connection configuration.
120      * <p>
121      * Please note this value can be overridden by the {@link #setConnectionFactory(
122      * org.apache.http.HttpConnectionFactory)} method.
123      */
124     public final ServerBootstrap setConnectionConfig(final ConnectionConfig connectionConfig) {
125         this.connectionConfig = connectionConfig;
126         return this;
127     }
128 
129     /**
130      * Assigns {@link HttpProcessor} instance.
131      */
132     public final ServerBootstrap setHttpProcessor(final HttpProcessor httpProcessor) {
133         this.httpProcessor = httpProcessor;
134         return this;
135     }
136 
137     /**
138      * Adds this protocol interceptor to the head of the protocol processing list.
139      * <p>
140      * Please note this value can be overridden by the {@link #setHttpProcessor(
141      * org.apache.http.protocol.HttpProcessor)} method.
142      */
143     public final ServerBootstrap addInterceptorFirst(final HttpResponseInterceptor itcp) {
144         if (itcp == null) {
145             return this;
146         }
147         if (responseFirst == null) {
148             responseFirst = new LinkedList<HttpResponseInterceptor>();
149         }
150         responseFirst.addFirst(itcp);
151         return this;
152     }
153 
154     /**
155      * Adds this protocol interceptor to the tail of the protocol processing list.
156      * <p>
157      * Please note this value can be overridden by the {@link #setHttpProcessor(
158      * org.apache.http.protocol.HttpProcessor)} method.
159      */
160     public final ServerBootstrap addInterceptorLast(final HttpResponseInterceptor itcp) {
161         if (itcp == null) {
162             return this;
163         }
164         if (responseLast == null) {
165             responseLast = new LinkedList<HttpResponseInterceptor>();
166         }
167         responseLast.addLast(itcp);
168         return this;
169     }
170 
171     /**
172      * Adds this protocol interceptor to the head of the protocol processing list.
173      * <p>
174      * Please note this value can be overridden by the {@link #setHttpProcessor(
175      * org.apache.http.protocol.HttpProcessor)} method.
176      */
177     public final ServerBootstrap addInterceptorFirst(final HttpRequestInterceptor itcp) {
178         if (itcp == null) {
179             return this;
180         }
181         if (requestFirst == null) {
182             requestFirst = new LinkedList<HttpRequestInterceptor>();
183         }
184         requestFirst.addFirst(itcp);
185         return this;
186     }
187 
188     /**
189      * Adds this protocol interceptor to the tail of the protocol processing list.
190      * <p>
191      * Please note this value can be overridden by the {@link #setHttpProcessor(
192      * org.apache.http.protocol.HttpProcessor)} method.
193      */
194     public final ServerBootstrap addInterceptorLast(final HttpRequestInterceptor itcp) {
195         if (itcp == null) {
196             return this;
197         }
198         if (requestLast == null) {
199             requestLast = new LinkedList<HttpRequestInterceptor>();
200         }
201         requestLast.addLast(itcp);
202         return this;
203     }
204 
205     /**
206      * Assigns {@code Server} response header value.
207      * <p>
208      * Please note this value can be overridden by the {@link #setHttpProcessor(
209      * org.apache.http.protocol.HttpProcessor)} method.
210      */
211     public final ServerBootstrap setServerInfo(final String serverInfo) {
212         this.serverInfo = serverInfo;
213         return this;
214     }
215 
216     /**
217      * Assigns {@link ConnectionReuseStrategy} instance.
218      */
219     public final ServerBootstrap setConnectionReuseStrategy(final ConnectionReuseStrategy connStrategy) {
220         this.connStrategy = connStrategy;
221         return this;
222     }
223 
224     /**
225      * Assigns {@link HttpResponseFactory} instance.
226      */
227     public final ServerBootstrap setResponseFactory(final HttpResponseFactory responseFactory) {
228         this.responseFactory = responseFactory;
229         return this;
230     }
231 
232     /**
233      * Assigns {@link HttpRequestHandlerMapper} instance.
234      */
235     public final ServerBootstrap setHandlerMapper(final HttpRequestHandlerMapper handlerMapper) {
236         this.handlerMapper = handlerMapper;
237         return this;
238     }
239 
240     /**
241      * Registers the given {@link HttpRequestHandler} as a handler for URIs
242      * matching the given pattern.
243      * <p>
244      * Please note this value can be overridden by the {@link #setHandlerMapper(
245      *   org.apache.http.protocol.HttpRequestHandlerMapper)} method.
246      *
247      * @param pattern the pattern to register the handler for.
248      * @param handler the handler.
249      */
250     public final ServerBootstrap registerHandler(final String pattern, final HttpRequestHandler handler) {
251         if (pattern == null || handler == null) {
252             return this;
253         }
254         if (handlerMap == null) {
255             handlerMap = new HashMap<String, HttpRequestHandler>();
256         }
257         handlerMap.put(pattern, handler);
258         return this;
259     }
260 
261     /**
262      * Assigns {@link HttpExpectationVerifier} instance.
263      */
264     public final ServerBootstrap setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
265         this.expectationVerifier = expectationVerifier;
266         return this;
267     }
268 
269     /**
270      * Assigns {@link HttpConnectionFactory} instance.
271      */
272     public final ServerBootstrap setConnectionFactory(
273             final HttpConnectionFactory<? extends DefaultBHttpServerConnection> connectionFactory) {
274         this.connectionFactory = connectionFactory;
275         return this;
276     }
277 
278     /**
279      * Assigns {@link org.apache.http.impl.bootstrap.SSLServerSetupHandler} instance.
280      */
281     public final ServerBootstrap setSslSetupHandler(final SSLServerSetupHandler sslSetupHandler) {
282         this.sslSetupHandler = sslSetupHandler;
283         return this;
284     }
285 
286     /**
287      * Assigns {@link javax.net.ServerSocketFactory} instance.
288      */
289     public final ServerBootstrap setServerSocketFactory(final ServerSocketFactory serverSocketFactory) {
290         this.serverSocketFactory = serverSocketFactory;
291         return this;
292     }
293 
294     /**
295      * Assigns {@link javax.net.ssl.SSLContext} instance.
296      * <p>
297      * Please note this value can be overridden by the {@link #setServerSocketFactory(
298      *   javax.net.ServerSocketFactory)} method.
299      */
300     public final ServerBootstrap setSslContext(final SSLContext sslContext) {
301         this.sslContext = sslContext;
302         return this;
303     }
304 
305     /**
306      * Assigns {@link org.apache.http.ExceptionLogger} instance.
307      */
308     public final ServerBootstrap setExceptionLogger(final ExceptionLogger exceptionLogger) {
309         this.exceptionLogger = exceptionLogger;
310         return this;
311     }
312 
313     public HttpServer create() {
314 
315         HttpProcessor httpProcessorCopy = this.httpProcessor;
316         if (httpProcessorCopy == null) {
317 
318             final HttpProcessorBuilder b = HttpProcessorBuilder.create();
319             if (requestFirst != null) {
320                 for (final HttpRequestInterceptor i: requestFirst) {
321                     b.addFirst(i);
322                 }
323             }
324             if (responseFirst != null) {
325                 for (final HttpResponseInterceptor i: responseFirst) {
326                     b.addFirst(i);
327                 }
328             }
329 
330             String serverInfoCopy = this.serverInfo;
331             if (serverInfoCopy == null) {
332                 serverInfoCopy = "Apache-HttpCore/1.1";
333             }
334 
335             b.addAll(
336                     new ResponseDate(),
337                     new ResponseServer(serverInfoCopy),
338                     new ResponseContent(),
339                     new ResponseConnControl());
340             if (requestLast != null) {
341                 for (final HttpRequestInterceptor i: requestLast) {
342                     b.addLast(i);
343                 }
344             }
345             if (responseLast != null) {
346                 for (final HttpResponseInterceptor i: responseLast) {
347                     b.addLast(i);
348                 }
349             }
350             httpProcessorCopy = b.build();
351         }
352 
353         HttpRequestHandlerMapper handlerMapperCopy = this.handlerMapper;
354         if (handlerMapperCopy == null) {
355             final UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
356             if (handlerMap != null) {
357                 for (Map.Entry<String, HttpRequestHandler> entry: handlerMap.entrySet()) {
358                     reqistry.register(entry.getKey(), entry.getValue());
359                 }
360             }
361             handlerMapperCopy = reqistry;
362         }
363 
364         ConnectionReuseStrategy connStrategyCopy = this.connStrategy;
365         if (connStrategyCopy == null) {
366             connStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
367         }
368 
369         HttpResponseFactory responseFactoryCopy = this.responseFactory;
370         if (responseFactoryCopy == null) {
371             responseFactoryCopy = DefaultHttpResponseFactory.INSTANCE;
372         }
373 
374         final HttpService httpService = new HttpService(
375                 httpProcessorCopy, connStrategyCopy, responseFactoryCopy, handlerMapperCopy,
376                 this.expectationVerifier);
377 
378         ServerSocketFactory serverSocketFactoryCopy = this.serverSocketFactory;
379         if (serverSocketFactoryCopy == null) {
380             if (this.sslContext != null) {
381                 serverSocketFactoryCopy = this.sslContext.getServerSocketFactory();
382             } else {
383                 serverSocketFactoryCopy = ServerSocketFactory.getDefault();
384             }
385         }
386 
387         HttpConnectionFactory<? extends DefaultBHttpServerConnection> connectionFactoryCopy = this.connectionFactory;
388         if (connectionFactoryCopy == null) {
389             if (this.connectionConfig != null) {
390                 connectionFactoryCopy = new DefaultBHttpServerConnectionFactory(this.connectionConfig);
391             } else {
392                 connectionFactoryCopy = DefaultBHttpServerConnectionFactory.INSTANCE;
393             }
394         }
395 
396         ExceptionLogger exceptionLoggerCopy = this.exceptionLogger;
397         if (exceptionLoggerCopy == null) {
398             exceptionLoggerCopy = ExceptionLogger.NO_OP;
399         }
400 
401         return new HttpServer(
402                 this.listenerPort > 0 ? this.listenerPort : 0,
403                 this.localAddress,
404                 this.socketConfig != null ? this.socketConfig : SocketConfig.DEFAULT,
405                 serverSocketFactoryCopy,
406                 httpService,
407                 connectionFactoryCopy,
408                 this.sslSetupHandler,
409                 exceptionLoggerCopy);
410     }
411 
412 }