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 SSLContext sslContext;
82      private HttpConnectionFactory<? extends DefaultBHttpServerConnection> connectionFactory;
83      private ExceptionLogger exceptionLogger;
84  
85      private ServerBootstrap() {
86      }
87  
88      public static ServerBootstrap bootstrap() {
89          return new ServerBootstrap();
90      }
91  
92      /**
93       * Sets listener port number.
94       */
95      public final ServerBootstrap setListenerPort(final int listenerPort) {
96          this.listenerPort = listenerPort;
97          return this;
98      }
99  
100     /**
101      * Assigns local interface for the listener.
102      */
103     public final ServerBootstrap setLocalAddress(final InetAddress localAddress) {
104         this.localAddress = localAddress;
105         return this;
106     }
107 
108     /**
109      * Sets socket configuration.
110      */
111     public final ServerBootstrap setSocketConfig(final SocketConfig socketConfig) {
112         this.socketConfig = socketConfig;
113         return this;
114     }
115 
116     /**
117      * Sets connection configuration.
118      * <p/>
119      * Please note this value can be overridden by the {@link #setConnectionFactory(
120      * org.apache.http.HttpConnectionFactory)} method.
121      */
122     public final ServerBootstrap setConnectionConfig(final ConnectionConfig connectionConfig) {
123         this.connectionConfig = connectionConfig;
124         return this;
125     }
126 
127     /**
128      * Assigns {@link HttpProcessor} instance.
129      */
130     public final ServerBootstrap setHttpProcessor(final HttpProcessor httpProcessor) {
131         this.httpProcessor = httpProcessor;
132         return this;
133     }
134 
135     /**
136      * Adds this protocol interceptor to the head of the protocol processing list.
137      * <p/>
138      * Please note this value can be overridden by the {@link #setHttpProcessor(
139      * org.apache.http.protocol.HttpProcessor)} method.
140      */
141     public final ServerBootstrap addInterceptorFirst(final HttpResponseInterceptor itcp) {
142         if (itcp == null) {
143             return this;
144         }
145         if (responseFirst == null) {
146             responseFirst = new LinkedList<HttpResponseInterceptor>();
147         }
148         responseFirst.addFirst(itcp);
149         return this;
150     }
151 
152     /**
153      * Adds this protocol interceptor to the tail of the protocol processing list.
154      * <p/>
155      * Please note this value can be overridden by the {@link #setHttpProcessor(
156      * org.apache.http.protocol.HttpProcessor)} method.
157      */
158     public final ServerBootstrap addInterceptorLast(final HttpResponseInterceptor itcp) {
159         if (itcp == null) {
160             return this;
161         }
162         if (responseLast == null) {
163             responseLast = new LinkedList<HttpResponseInterceptor>();
164         }
165         responseLast.addLast(itcp);
166         return this;
167     }
168 
169     /**
170      * Adds this protocol interceptor to the head of the protocol processing list.
171      * <p/>
172      * Please note this value can be overridden by the {@link #setHttpProcessor(
173      * org.apache.http.protocol.HttpProcessor)} method.
174      */
175     public final ServerBootstrap addInterceptorFirst(final HttpRequestInterceptor itcp) {
176         if (itcp == null) {
177             return this;
178         }
179         if (requestFirst == null) {
180             requestFirst = new LinkedList<HttpRequestInterceptor>();
181         }
182         requestFirst.addFirst(itcp);
183         return this;
184     }
185 
186     /**
187      * Adds this protocol interceptor to the tail of the protocol processing list.
188      * <p/>
189      * Please note this value can be overridden by the {@link #setHttpProcessor(
190      * org.apache.http.protocol.HttpProcessor)} method.
191      */
192     public final ServerBootstrap addInterceptorLast(final HttpRequestInterceptor itcp) {
193         if (itcp == null) {
194             return this;
195         }
196         if (requestLast == null) {
197             requestLast = new LinkedList<HttpRequestInterceptor>();
198         }
199         requestLast.addLast(itcp);
200         return this;
201     }
202 
203     /**
204      * Assigns <tt>Server</tt> response header value.
205      * <p/>
206      * Please note this value can be overridden by the {@link #setHttpProcessor(
207      * org.apache.http.protocol.HttpProcessor)} method.
208      */
209     public final ServerBootstrap setServerInfo(final String serverInfo) {
210         this.serverInfo = serverInfo;
211         return this;
212     }
213 
214     /**
215      * Assigns {@link ConnectionReuseStrategy} instance.
216      */
217     public final ServerBootstrap setConnectionReuseStrategy(final ConnectionReuseStrategy connStrategy) {
218         this.connStrategy = connStrategy;
219         return this;
220     }
221 
222     /**
223      * Assigns {@link HttpResponseFactory} instance.
224      */
225     public final ServerBootstrap setResponseFactory(final HttpResponseFactory responseFactory) {
226         this.responseFactory = responseFactory;
227         return this;
228     }
229 
230     /**
231      * Assigns {@link HttpRequestHandlerMapper} instance.
232      */
233     public final ServerBootstrap setHandlerMapper(final HttpRequestHandlerMapper handlerMapper) {
234         this.handlerMapper = handlerMapper;
235         return this;
236     }
237 
238     /**
239      * Registers the given {@link HttpRequestHandler} as a handler for URIs
240      * matching the given pattern.
241      * <p/>
242      * Please note this value can be overridden by the {@link #setHandlerMapper(
243      *   org.apache.http.protocol.HttpRequestHandlerMapper)} method.
244      *
245      * @param pattern the pattern to register the handler for.
246      * @param handler the handler.
247      */
248     public final ServerBootstrap registerHandler(final String pattern, final HttpRequestHandler handler) {
249         if (pattern == null || handler == null) {
250             return this;
251         }
252         if (handlerMap == null) {
253             handlerMap = new HashMap<String, HttpRequestHandler>();
254         }
255         handlerMap.put(pattern, handler);
256         return this;
257     }
258 
259     /**
260      * Assigns {@link HttpExpectationVerifier} instance.
261      */
262     public final ServerBootstrap setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
263         this.expectationVerifier = expectationVerifier;
264         return this;
265     }
266 
267     /**
268      * Assigns {@link HttpConnectionFactory} instance.
269      */
270     public final ServerBootstrap setConnectionFactory(
271             final HttpConnectionFactory<? extends DefaultBHttpServerConnection> connectionFactory) {
272         this.connectionFactory = connectionFactory;
273         return this;
274     }
275 
276     /**
277      * Assigns {@link javax.net.ssl.SSLContext} instance.
278      */
279     public final ServerBootstrap setSslContext(final SSLContext sslContext) {
280         this.sslContext = sslContext;
281         return this;
282     }
283 
284     /**
285      * Assigns {@link org.apache.http.ExceptionLogger} instance.
286      */
287     public final ServerBootstrap setExceptionLogger(final ExceptionLogger exceptionLogger) {
288         this.exceptionLogger = exceptionLogger;
289         return this;
290     }
291 
292     public HttpServer create() {
293 
294         HttpProcessor httpProcessorCopy = this.httpProcessor;
295         if (httpProcessorCopy == null) {
296 
297             final HttpProcessorBuilder b = HttpProcessorBuilder.create();
298             if (requestFirst != null) {
299                 for (final HttpRequestInterceptor i: requestFirst) {
300                     b.addFirst(i);
301                 }
302             }
303             if (responseFirst != null) {
304                 for (final HttpResponseInterceptor i: responseFirst) {
305                     b.addFirst(i);
306                 }
307             }
308 
309             String serverInfoCopy = this.serverInfo;
310             if (serverInfoCopy == null) {
311                 serverInfoCopy = "Apache-HttpCore/1.1";
312             }
313 
314             b.addAll(
315                     new ResponseDate(),
316                     new ResponseServer(serverInfoCopy),
317                     new ResponseContent(),
318                     new ResponseConnControl());
319             if (requestLast != null) {
320                 for (final HttpRequestInterceptor i: requestLast) {
321                     b.addLast(i);
322                 }
323             }
324             if (responseLast != null) {
325                 for (final HttpResponseInterceptor i: responseLast) {
326                     b.addLast(i);
327                 }
328             }
329             httpProcessorCopy = b.build();
330         }
331 
332         HttpRequestHandlerMapper handlerMapperCopy = this.handlerMapper;
333         if (handlerMapperCopy == null) {
334             final UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
335             if (handlerMap != null) {
336                 for (Map.Entry<String, HttpRequestHandler> entry: handlerMap.entrySet()) {
337                     reqistry.register(entry.getKey(), entry.getValue());
338                 }
339             }
340             handlerMapperCopy = reqistry;
341         }
342 
343         ConnectionReuseStrategy connStrategyCopy = this.connStrategy;
344         if (connStrategyCopy == null) {
345             connStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
346         }
347 
348         HttpResponseFactory responseFactoryCopy = this.responseFactory;
349         if (responseFactoryCopy == null) {
350             responseFactoryCopy = DefaultHttpResponseFactory.INSTANCE;
351         }
352 
353         final HttpService httpService = new HttpService(
354                 httpProcessorCopy, connStrategyCopy, responseFactoryCopy, handlerMapperCopy,
355                 this.expectationVerifier);
356 
357         final ServerSocketFactory serverSocketFactory;
358         if (this.sslContext != null) {
359             serverSocketFactory = this.sslContext.getServerSocketFactory();
360         } else {
361             serverSocketFactory = ServerSocketFactory.getDefault();
362         }
363 
364         HttpConnectionFactory<? extends DefaultBHttpServerConnection> connectionFactoryCopy = this.connectionFactory;
365         if (connectionFactoryCopy == null) {
366             if (this.connectionConfig != null) {
367                 connectionFactoryCopy = new DefaultBHttpServerConnectionFactory(this.connectionConfig);
368             } else {
369                 connectionFactoryCopy = DefaultBHttpServerConnectionFactory.INSTANCE;
370             }
371         }
372 
373         ExceptionLogger exceptionLoggerCopy = this.exceptionLogger;
374         if (exceptionLoggerCopy == null) {
375             exceptionLoggerCopy = ExceptionLogger.NO_OP;
376         }
377 
378         return new HttpServer(
379                 this.listenerPort > 0 ? this.listenerPort : 0,
380                 this.localAddress,
381                 this.socketConfig != null ? this.socketConfig : SocketConfig.DEFAULT,
382                 serverSocketFactory,
383                 httpService,
384                 connectionFactoryCopy,
385                 exceptionLoggerCopy);
386     }
387 
388 }