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  
28  package org.apache.http.impl.nio;
29  
30  import java.io.IOException;
31  
32  import javax.net.ssl.SSLContext;
33  
34  import org.apache.http.HttpRequest;
35  import org.apache.http.HttpRequestFactory;
36  import org.apache.http.annotation.Contract;
37  import org.apache.http.annotation.ThreadingBehavior;
38  import org.apache.http.config.ConnectionConfig;
39  import org.apache.http.impl.nio.codecs.DefaultHttpRequestParserFactory;
40  import org.apache.http.impl.nio.reactor.AbstractIODispatch;
41  import org.apache.http.nio.NHttpConnectionFactory;
42  import org.apache.http.nio.NHttpMessageParserFactory;
43  import org.apache.http.nio.NHttpServerEventHandler;
44  import org.apache.http.nio.reactor.IOSession;
45  import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
46  import org.apache.http.params.HttpParams;
47  import org.apache.http.util.Args;
48  
49  /**
50   * Default {@link org.apache.http.nio.reactor.IOEventDispatch} implementation
51   * that supports both plain (non-encrypted) and SSL encrypted server side HTTP
52   * connections.
53   * @param <H> an implementation of {@link NHttpServerEventHandler}.
54   *
55   * @since 4.2
56   */
57  @SuppressWarnings("deprecation")
58  @Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
59  public class DefaultHttpServerIODispatch<H extends NHttpServerEventHandler>
60                      extends AbstractIODispatch<DefaultNHttpServerConnection> {
61  
62      /**
63       * Creates a new instance of this class to be used for dispatching I/O event
64       * notifications to the given protocol handler.
65       *
66       * @param handler the server protocol handler.
67       * @param sslContext an SSLContext or null (for a plain text connection.)
68       * @param config a connection configuration
69       * @return a new instance
70       * @since 4.4.7
71       */
72      public static <T extends NHttpServerEventHandler> DefaultHttpServerIODispatch<T> create(final T handler,
73              final SSLContext sslContext,
74              final ConnectionConfig config) {
75          return sslContext == null ? new DefaultHttpServerIODispatch<T>(handler, config)
76                  : new DefaultHttpServerIODispatch<T>(handler, sslContext, config);
77      }
78  
79      /**
80       * Creates a new instance of this class to be used for dispatching I/O event
81       * notifications to the given protocol handler.
82       *
83       * @param eventHandler the server protocol handler.
84       * @param sslContext an SSLContext or null (for a plain text connection.)
85       * @param config a connection configuration
86       * @param httpRequestFactory the request factory used by this object to generate {@link HttpRequest} instances.
87       * @return a new instance
88       * @since 4.4.10
89       */
90      public static <T extends NHttpServerEventHandler> DefaultHttpServerIODispatch<T> create(final T eventHandler,
91              final SSLContext sslContext, final ConnectionConfig config, final HttpRequestFactory httpRequestFactory) {
92          final NHttpMessageParserFactory<HttpRequest> httpRequestParserFactory = new DefaultHttpRequestParserFactory(
93                  null, httpRequestFactory);
94          // @formatter:off
95          return sslContext == null
96                  ? new DefaultHttpServerIODispatch<T>(eventHandler,
97                          new DefaultNHttpServerConnectionFactory(null, httpRequestParserFactory, null, config))
98                  : new DefaultHttpServerIODispatch<T>(eventHandler,
99                          new SSLNHttpServerConnectionFactory(sslContext, null, httpRequestParserFactory, null, config));
100         // @formatter:om
101     }
102 
103     /**
104      * Creates a new instance of this class to be used for dispatching I/O event
105      * notifications to the given protocol handler.
106      *
107      * @param handler the server protocol handler.
108      * @param sslContext an SSLContext or null (for a plain text connection.)
109      * @param sslHandler customizes various aspects of the TLS/SSL protocol.
110      * @param config a connection configuration
111      * @return a new instance
112      * @since 4.4.7
113      */
114     public static <T extends NHttpServerEventHandler> DefaultHttpServerIODispatch<T> create(final T handler,
115             final SSLContext sslContext,
116             final SSLSetupHandler sslHandler,
117             final ConnectionConfig config) {
118         return sslContext == null ? new DefaultHttpServerIODispatch<T>(handler, config)
119                 : new DefaultHttpServerIODispatch<T>(handler, sslContext, sslHandler, config);
120     }
121 
122     private final H handler;
123     private final NHttpConnectionFactory<? extends DefaultNHttpServerConnection> connectionFactory;
124 
125     public DefaultHttpServerIODispatch(
126             final H handler,
127             final NHttpConnectionFactory<? extends DefaultNHttpServerConnection> connFactory) {
128         super();
129         this.handler = Args.notNull(handler, "HTTP server handler");
130         this.connectionFactory = Args.notNull(connFactory, "HTTP server connection factory");
131     }
132 
133     /**
134      * @deprecated (4.3) use {@link DefaultHttpServerIODispatch#DefaultHttpServerIODispatch(
135      *   NHttpServerEventHandler, ConnectionConfig)}
136      */
137     @Deprecated
138     public DefaultHttpServerIODispatch(
139             final H handler,
140             final HttpParams params) {
141         this(handler, new DefaultNHttpServerConnectionFactory(params));
142     }
143 
144     /**
145      * @deprecated (4.3) use {@link DefaultHttpServerIODispatch#DefaultHttpServerIODispatch(
146      *   NHttpServerEventHandler, SSLContext, SSLSetupHandler, ConnectionConfig)}
147      */
148     @Deprecated
149     public DefaultHttpServerIODispatch(
150             final H handler,
151             final SSLContext sslContext,
152             final SSLSetupHandler sslHandler,
153             final HttpParams params) {
154         this(handler, new SSLNHttpServerConnectionFactory(sslContext, sslHandler, params));
155     }
156 
157     /**
158      * @deprecated (4.3) use {@link DefaultHttpServerIODispatch#DefaultHttpServerIODispatch(
159      *   NHttpServerEventHandler, SSLContext, ConnectionConfig)}
160      */
161     @Deprecated
162     public DefaultHttpServerIODispatch(
163             final H handler,
164             final SSLContext sslContext,
165             final HttpParams params) {
166         this(handler, sslContext, null, params);
167     }
168 
169     /**
170      * @since 4.3
171      */
172     public DefaultHttpServerIODispatch(final H handler, final ConnectionConfig config) {
173         this(handler, new DefaultNHttpServerConnectionFactory(config));
174     }
175 
176     /**
177      * @since 4.3
178      */
179     public DefaultHttpServerIODispatch(
180             final H handler,
181             final SSLContext sslContext,
182             final SSLSetupHandler sslHandler,
183             final ConnectionConfig config) {
184         this(handler, new SSLNHttpServerConnectionFactory(sslContext, sslHandler, config));
185     }
186 
187     /**
188      * @since 4.3
189      */
190     public DefaultHttpServerIODispatch(
191             final H handler,
192             final SSLContext sslContext,
193             final ConnectionConfig config) {
194         this(handler, new SSLNHttpServerConnectionFactory(sslContext, null, config));
195     }
196 
197     @Override
198     protected DefaultNHttpServerConnection createConnection(final IOSession session) {
199         return this.connectionFactory.createConnection(session);
200     }
201 
202     /**
203      * Gets the connection factory used to construct this dispatch.
204      *
205      * @return the connection factory used to construct this dispatch.
206      * @since 4.4.9
207      */
208     public NHttpConnectionFactory<? extends DefaultNHttpServerConnection> getConnectionFactory() {
209         return connectionFactory;
210     }
211 
212     /**
213      * Gets the handler used to construct this dispatch.
214      *
215      * @return the handler used to construct this dispatch.
216      * @since 4.4.9
217      */
218     public H getHandler() {
219         return handler;
220     }
221 
222     @Override
223     protected void onConnected(final DefaultNHttpServerConnection conn) {
224         try {
225             this.handler.connected(conn);
226         } catch (final Exception ex) {
227             this.handler.exception(conn, ex);
228         }
229     }
230 
231     @Override
232     protected void onClosed(final DefaultNHttpServerConnection conn) {
233         this.handler.closed(conn);
234     }
235 
236     @Override
237     protected void onException(final DefaultNHttpServerConnection conn, final IOException ex) {
238         this.handler.exception(conn, ex);
239     }
240 
241     @Override
242     protected void onInputReady(final DefaultNHttpServerConnection conn) {
243         conn.consumeInput(this.handler);
244     }
245 
246     @Override
247     protected void onOutputReady(final DefaultNHttpServerConnection conn) {
248         conn.produceOutput(this.handler);
249     }
250 
251     @Override
252     protected void onTimeout(final DefaultNHttpServerConnection conn) {
253         try {
254             this.handler.timeout(conn);
255         } catch (final Exception ex) {
256             this.handler.exception(conn, ex);
257         }
258     }
259 
260 }