001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements.  See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License.  You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.activemq.transport.https;
019
020import java.io.IOException;
021import java.net.URI;
022
023import javax.net.ssl.HostnameVerifier;
024
025import org.apache.activemq.broker.SslContext;
026import org.apache.activemq.transport.http.HttpClientTransport;
027import org.apache.activemq.transport.util.TextWireFormat;
028import org.apache.activemq.util.IOExceptionSupport;
029import org.apache.http.config.Registry;
030import org.apache.http.config.RegistryBuilder;
031import org.apache.http.conn.HttpClientConnectionManager;
032import org.apache.http.conn.socket.ConnectionSocketFactory;
033import org.apache.http.conn.socket.PlainConnectionSocketFactory;
034import org.apache.http.conn.ssl.DefaultHostnameVerifier;
035import org.apache.http.conn.ssl.NoopHostnameVerifier;
036import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
037import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
038
039public class HttpsClientTransport extends HttpClientTransport {
040
041    private final javax.net.ssl.SSLSocketFactory sslSocketFactory;
042    private boolean verifyHostName = true;
043
044    public HttpsClientTransport(TextWireFormat wireFormat, URI remoteUrl) {
045        super(wireFormat, remoteUrl);
046        try {
047            sslSocketFactory = createSocketFactory();
048        } catch (IOException e) {
049            throw new IllegalStateException("Error trying to configure TLS", e);
050        }
051    }
052
053    @Override
054    protected HttpClientConnectionManager createClientConnectionManager() {
055        return new PoolingHttpClientConnectionManager(createRegistry());
056    }
057
058    private Registry<ConnectionSocketFactory> createRegistry() {
059
060        RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create();
061        try {
062            HostnameVerifier hostnameVerifier = verifyHostName ? new DefaultHostnameVerifier() : new NoopHostnameVerifier();
063            SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(sslSocketFactory, hostnameVerifier);
064            registryBuilder.register("https", sslConnectionFactory);
065            registryBuilder.register("http", PlainConnectionSocketFactory.INSTANCE);
066            return registryBuilder.build();
067        } catch (Exception e) {
068            throw new IllegalStateException("Failure trying to create scheme registry", e);
069        }
070    }
071
072    /**
073     * Creates a new SSL SocketFactory. The given factory will use user-provided
074     * key and trust managers (if the user provided them).
075     *
076     * @return Newly created (Ssl)SocketFactory.
077     * @throws IOException
078     */
079    protected javax.net.ssl.SSLSocketFactory createSocketFactory() throws IOException {
080        if (SslContext.getCurrentSslContext() != null) {
081            SslContext ctx = SslContext.getCurrentSslContext();
082            try {
083                return ctx.getSSLContext().getSocketFactory();
084            } catch (Exception e) {
085                throw IOExceptionSupport.create(e);
086            }
087        } else {
088            return (javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault();
089        }
090
091    }
092
093    @Override
094    protected String getSystemPropertyPrefix() {
095        return "https.";
096    }
097
098    public Boolean getVerifyHostName() {
099        return verifyHostName;
100    }
101
102    public void setVerifyHostName(Boolean verifyHostName) {
103        this.verifyHostName = verifyHostName;
104    }
105
106}