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