001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.http;
018    
019    import java.io.IOException;
020    import java.net.InetAddress;
021    import java.net.Socket;
022    import java.net.UnknownHostException;
023    
024    import javax.net.ssl.SSLContext;
025    import javax.net.ssl.SSLSocketFactory;
026    
027    import org.apache.camel.RuntimeCamelException;
028    import org.apache.camel.util.jsse.SSLContextParameters;
029    import org.apache.commons.httpclient.ConnectTimeoutException;
030    import org.apache.commons.httpclient.params.HttpConnectionParams;
031    import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
032    import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
033    
034    /**
035     * A {@code SecureProtocolSocketFactory} implementation to allow configuration
036     * of Commons HTTP SSL/TLS options based on a {@link #JSSEClientParameters}
037     * instance or a provided {@code SSLSocketFactory} instance.
038     */
039    public class SSLContextParametersSecureProtocolSocketFactory implements SecureProtocolSocketFactory {
040        
041        protected SSLSocketFactory factory;
042        
043        protected SSLContext context;
044        
045        /**
046         * Creates a new instance using the provided factory.
047         *
048         * @param factory the factory to use
049         */
050        public SSLContextParametersSecureProtocolSocketFactory(SSLSocketFactory factory) {
051            this.factory = factory;
052        } 
053        
054        /**
055         * Creates a new instance using a factory created by the provided client configuration
056         * parameters.
057         *
058         * @param params the configuration parameters to use when creating the socket factory
059         */
060        public SSLContextParametersSecureProtocolSocketFactory(SSLContextParameters params) {
061    
062            try {
063                this.context = params.createSSLContext();
064                this.factory = this.context.getSocketFactory();
065            } catch (Exception e) {
066                throw new RuntimeCamelException("Error creating the SSLContext.", e);
067            }
068        }    
069    
070        @Override
071        public Socket createSocket(String host, int port, 
072                                   InetAddress localAddress, int localPort) throws IOException, UnknownHostException {
073            return this.factory.createSocket(host, port, localAddress, localPort);
074        }
075    
076        @Override
077        public Socket createSocket(String host, int port, 
078                                   InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException,
079            ConnectTimeoutException {
080            
081            if (params == null) {
082                throw new IllegalArgumentException("Parameters may not be null");
083            }
084            int timeout = params.getConnectionTimeout();
085            if (timeout == 0) {
086                return createSocket(host, port, localAddress, localPort);
087            } else {
088                return ControllerThreadSocketFactory.createSocket(
089                        this, host, port, localAddress, localPort, timeout);
090            }
091        }
092    
093        @Override
094        public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
095            return this.factory.createSocket(host, port);
096        }
097    
098        @Override
099        public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
100            return this.factory.createSocket(socket, host, port, autoClose);
101        }
102    }