001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027package org.apache.http.impl.nio;
028
029import javax.net.ssl.SSLContext;
030
031import org.apache.http.HttpHost;
032import org.apache.http.HttpRequest;
033import org.apache.http.HttpResponse;
034import org.apache.http.HttpResponseFactory;
035import org.apache.http.annotation.Contract;
036import org.apache.http.annotation.ThreadingBehavior;
037import org.apache.http.config.ConnectionConfig;
038import org.apache.http.entity.ContentLengthStrategy;
039import org.apache.http.impl.ConnSupport;
040import org.apache.http.impl.DefaultHttpResponseFactory;
041import org.apache.http.impl.nio.codecs.DefaultHttpResponseParserFactory;
042import org.apache.http.nio.NHttpConnectionFactory;
043import org.apache.http.nio.NHttpMessageParserFactory;
044import org.apache.http.nio.NHttpMessageWriterFactory;
045import org.apache.http.nio.reactor.IOSession;
046import org.apache.http.nio.reactor.ssl.SSLIOSession;
047import org.apache.http.nio.reactor.ssl.SSLMode;
048import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
049import org.apache.http.nio.util.ByteBufferAllocator;
050import org.apache.http.nio.util.HeapByteBufferAllocator;
051import org.apache.http.params.HttpParamConfig;
052import org.apache.http.params.HttpParams;
053import org.apache.http.ssl.SSLContexts;
054import org.apache.http.util.Args;
055
056/**
057 * Default factory for SSL encrypted, non-blocking
058 * {@link org.apache.http.nio.NHttpClientConnection}s.
059 *
060 * @since 4.2
061 */
062@SuppressWarnings("deprecation")
063@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
064public class SSLNHttpClientConnectionFactory
065    implements NHttpConnectionFactory<DefaultNHttpClientConnection> {
066
067    public static final SSLNHttpClientConnectionFactory INSTANCE = new SSLNHttpClientConnectionFactory();
068
069    private final ContentLengthStrategy incomingContentStrategy;
070    private final ContentLengthStrategy outgoingContentStrategy;
071    private final NHttpMessageParserFactory<HttpResponse> responseParserFactory;
072    private final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory;
073    private final ByteBufferAllocator allocator;
074    private final SSLContext sslContext;
075    private final SSLSetupHandler sslHandler;
076    private final ConnectionConfig cconfig;
077
078    /**
079     * @deprecated (4.3) use {@link
080     *   SSLNHttpClientConnectionFactory#SSLNHttpClientConnectionFactory(SSLContext,
081     *      SSLSetupHandler, NHttpMessageParserFactory, NHttpMessageWriterFactory,
082     *      ByteBufferAllocator, ConnectionConfig)}
083     */
084    @Deprecated
085    public SSLNHttpClientConnectionFactory(
086            final SSLContext sslContext,
087            final SSLSetupHandler sslHandler,
088            final HttpResponseFactory responseFactory,
089            final ByteBufferAllocator allocator,
090            final HttpParams params) {
091        super();
092        Args.notNull(responseFactory, "HTTP response factory");
093        Args.notNull(allocator, "Byte buffer allocator");
094        Args.notNull(params, "HTTP parameters");
095        this.sslContext = sslContext != null ? sslContext : SSLContexts.createSystemDefault();
096        this.sslHandler = sslHandler;
097        this.allocator = allocator;
098        this.incomingContentStrategy = null;
099        this.outgoingContentStrategy = null;
100        this.responseParserFactory = new DefaultHttpResponseParserFactory(null, responseFactory);
101        this.requestWriterFactory = null;
102        this.cconfig = HttpParamConfig.getConnectionConfig(params);
103    }
104
105    /**
106     * @deprecated (4.3) use {@link
107     *   SSLNHttpClientConnectionFactory#SSLNHttpClientConnectionFactory(SSLContext,
108     *     SSLSetupHandler, ConnectionConfig)}
109     */
110    @Deprecated
111    public SSLNHttpClientConnectionFactory(
112            final SSLContext sslContext,
113            final SSLSetupHandler sslHandler,
114            final HttpParams params) {
115        this(sslContext, sslHandler, DefaultHttpResponseFactory.INSTANCE,
116                HeapByteBufferAllocator.INSTANCE, params);
117    }
118
119    /**
120     * @deprecated (4.3) use {@link
121     *   SSLNHttpClientConnectionFactory#SSLNHttpClientConnectionFactory(ConnectionConfig)}
122     */
123    @Deprecated
124    public SSLNHttpClientConnectionFactory(final HttpParams params) {
125        this(null, null, params);
126    }
127
128    /**
129     * @since 4.3
130     */
131    public SSLNHttpClientConnectionFactory(
132            final SSLContext sslContext,
133            final SSLSetupHandler sslHandler,
134            final ContentLengthStrategy incomingContentStrategy,
135            final ContentLengthStrategy outgoingContentStrategy,
136            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
137            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
138            final ByteBufferAllocator allocator,
139            final ConnectionConfig cconfig) {
140        super();
141        this.sslContext = sslContext != null ? sslContext : SSLContexts.createSystemDefault();
142        this.sslHandler = sslHandler;
143        this.incomingContentStrategy = incomingContentStrategy;
144        this.outgoingContentStrategy = outgoingContentStrategy;
145        this.responseParserFactory = responseParserFactory;
146        this.requestWriterFactory = requestWriterFactory;
147        this.allocator = allocator;
148        this.cconfig = cconfig != null ? cconfig : ConnectionConfig.DEFAULT;
149    }
150
151    /**
152     * @since 4.3
153     */
154    public SSLNHttpClientConnectionFactory(
155            final SSLContext sslContext,
156            final SSLSetupHandler sslHandler,
157            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
158            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
159            final ByteBufferAllocator allocator,
160            final ConnectionConfig cconfig) {
161        this(sslContext, sslHandler,
162                null, null, responseParserFactory, requestWriterFactory, allocator, cconfig);
163    }
164
165    /**
166     * @since 4.3
167     */
168    public SSLNHttpClientConnectionFactory(
169            final SSLContext sslContext,
170            final SSLSetupHandler sslHandler,
171            final NHttpMessageParserFactory<HttpResponse> responseParserFactory,
172            final NHttpMessageWriterFactory<HttpRequest> requestWriterFactory,
173            final ConnectionConfig cconfig) {
174        this(sslContext, sslHandler,
175                null, null, responseParserFactory, requestWriterFactory, null, cconfig);
176    }
177
178    /**
179     * @since 4.3
180     */
181    public SSLNHttpClientConnectionFactory(
182            final SSLContext sslContext,
183            final SSLSetupHandler sslHandler,
184            final ConnectionConfig config) {
185        this(sslContext, sslHandler, null, null, null, null, null, config);
186    }
187
188    /**
189     * @since 4.3
190     */
191    public SSLNHttpClientConnectionFactory(final ConnectionConfig config) {
192        this(null, null, null, null, null, null, null, config);
193    }
194
195    /**
196     * @since 4.3
197     */
198    public SSLNHttpClientConnectionFactory() {
199        this(null, null, null, null, null, null);
200    }
201
202    /**
203     * @deprecated (4.3) no longer used.
204     */
205    @Deprecated
206    protected DefaultNHttpClientConnection createConnection(
207            final IOSession session,
208            final HttpResponseFactory responseFactory,
209            final ByteBufferAllocator allocator,
210            final HttpParams params) {
211        return new DefaultNHttpClientConnection(session, responseFactory, allocator, params);
212    }
213
214    /**
215     * @since 4.3
216     */
217    protected SSLIOSession createSSLIOSession(
218            final IOSession iosession,
219            final SSLContext sslContext,
220            final SSLSetupHandler sslHandler) {
221        final Object attachment = iosession.getAttribute(IOSession.ATTACHMENT_KEY);
222        return new SSLIOSession(iosession, SSLMode.CLIENT,
223                attachment instanceof HttpHost ? (HttpHost) attachment : null,
224                sslContext, sslHandler);
225    }
226
227    @Override
228    public DefaultNHttpClientConnection createConnection(final IOSession iosession) {
229        final SSLIOSession ssliosession = createSSLIOSession(iosession, this.sslContext, this.sslHandler);
230        iosession.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
231        return new DefaultNHttpClientConnection(
232                ssliosession,
233                this.cconfig.getBufferSize(),
234                this.cconfig.getFragmentSizeHint(),
235                this.allocator,
236                ConnSupport.createDecoder(this.cconfig),
237                ConnSupport.createEncoder(this.cconfig),
238                this.cconfig.getMessageConstraints(),
239                this.incomingContentStrategy,
240                this.outgoingContentStrategy,
241                this.requestWriterFactory,
242                this.responseParserFactory);
243    }
244
245}