Package org.jboss.soa.esb.http.configurators

Source Code of org.jboss.soa.esb.http.configurators.HttpProtocol

/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*
* (C) 2005-2006, JBoss Inc.
*/
package org.jboss.soa.esb.http.configurators;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Properties;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.ProxyHost;
import org.apache.commons.httpclient.contrib.ssl.StrictSSLProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.ssl.KeyMaterial;
import org.apache.commons.ssl.SSLClient;
import org.apache.log4j.Logger;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.http.Configurator;
import org.jboss.soa.esb.http.protocol.ProtocolSocketFactoryBuilder;
import org.jboss.soa.esb.util.ClassUtil;

/**
* HTTP Protocol configurator.
* <p/>
* Supports both HTTP and HTTPS, including configuring the socket factory and SSL keystore.  It
* supports the SSL keystore being on the classpath, filesystem or based on a {@link URI}.
* <p/>
* Properties:
* <ul>
*      <li><b>target-host-url</b>: (Required)</li>
*      <li><b>keystore</b>: (Optional).  See {@link KeyMaterial}. Defaults to "/keystore".</li>
*      <li><b>keystore-passwd</b>: (Optional).  See {@link KeyMaterial}. Defaults to "changeit".</li>
*      <li><b>protocol-socket-factory</b>: See {@link Protocol}. (Optional).
*          Defaults to {@link StrictSSLProtocolSocketFactory} for HTTPS, otherwise defaults to {@link DefaultProtocolSocketFactory}.
*          Configure with {@link org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory} for unauthenticated
*          SSL.  To authenticate with a self-signed certificate, use the
*          {@link org.jboss.soa.esb.http.protocol.SelfSignedSSLProtocolSocketFactoryBuilder} (test/demo only) and to perform
*          full authentication (2way) with CA Signed certs, use the {@link org.jboss.soa.esb.http.protocol.AuthSSLProtocolSocketFactoryBuilder}.</li>
* </ul>
* <p/>
* See <a href="http://jakarta.apache.org/commons/httpclient/sslguide.html">HttpClient HttpProtocol Guide</a>.
*
* @author <a href="mailto:tom.fennelly@jboss.com">tom.fennelly@jboss.com</a>
*/
public class HttpProtocol extends Configurator {
   
    private Logger log = Logger.getLogger(HttpProtocol.class);

    public void configure(HttpClient httpClient, Properties properties) throws ConfigurationException {
        URI targetURI = getTargetURI(properties, true);
        String factory;
        String scheme = targetURI.getScheme();
        int port = targetURI.getPort();
        org.apache.commons.httpclient.protocol.Protocol protocol;
        KeyMaterial keyMaterial = null;
        ProtocolSocketFactory socketFactory;

        if(!scheme.startsWith("http")) {
            // We're only interested in HTTP for this...
            return;
        }
       
        final int defaultPort ;
        boolean secure = "https".equals(scheme);
        if (secure) {
            factory = properties.getProperty("protocol-socket-factory", StrictSSLProtocolSocketFactory.class.getName());
            keyMaterial = getKeyMaterial(properties);
            defaultPort = 443;
        } else {
            factory = properties.getProperty("protocol-socket-factory", DefaultProtocolSocketFactory.class.getName());
            defaultPort = 80;
        }
        if (port <= 0) {
            port = defaultPort ;
        }
        assertPropertySetAndNotBlank(factory, "protocol-socket-factory");
        socketFactory = createFactoryClass(factory, keyMaterial, properties);

        // And finally... configure the host with the protocol....
        protocol = new Protocol(scheme, socketFactory, defaultPort);
        // these lines have to happen after registerProtocol, otherwise they pick up the wrong static value
        if (secure) {
          setHttpsProxyHost(httpClient, properties);
        } else {
          setHttpProxyHost(httpClient, properties);
        }
        // Use our own protocol, see JBESB-3021 comments for more information.
        httpClient.getHostConfiguration().setHost(targetURI.getHost(), port, protocol);
    }
   
    /**
     * Will create a ProxyHost using the properties 'http.proxyHost' and optionally
     * the property 'http.proxyPort'.
     *
     * @param httpClient    The HttpClient that should have its host configurations proxy host set.
     * @param properties    The properties that should be set.
     */
    void setHttpProxyHost(final HttpClient httpClient, final Properties properties) {
        ProxyHost proxyHost = createProxyHost("http.proxyHost", "http.proxyPort", 80, properties);
        if (proxyHost != null) {
            httpClient.getHostConfiguration().setProxyHost(proxyHost);
        }
    }
   
    /**
     * Will create a ProxyHost using the properties 'https.proxyHost' and optionally
     * the property 'https.proxyPort'.
     *
     * @param httpClient    The HttpClient that should have its host configurations proxy host set.
     * @param properties    The properties that should be set.
     */
    void setHttpsProxyHost(final HttpClient httpClient, final Properties properties) {
        ProxyHost proxyHost = createProxyHost("https.proxyHost", "https.proxyPort", 443, properties);
        if (proxyHost != null) {
            httpClient.getHostConfiguration().setProxyHost(proxyHost);
        }
    }
   
    private ProxyHost createProxyHost(final String hostPropertyName, final String portPropertyName, final int defaultPort, final Properties properties) {
        final String proxyHost = (String) properties.get(hostPropertyName);
        ProxyHost proxy = null;
        if (proxyHost != null) {
            final String proxyPortStr = (String) properties.get(portPropertyName);
            if (proxyPortStr == null) {
                proxy = new ProxyHost(proxyHost, defaultPort);
            }
            else {
                proxy = new ProxyHost(proxyHost, Integer.parseInt(proxyPortStr));
            }
            log.debug("ProxyHost " + proxy.toString());
        }
        return proxy;
    }
   
    private KeyMaterial getKeyMaterial(Properties properties) throws ConfigurationException {
        String keyStore = properties.getProperty("keystore", "/keystore");
        String keyStorePassword = properties.getProperty("keystore-passw", "changeit");

        keyStorePassword = getPasswordFromFile(keyStorePassword);

        // Try it as a classpath resource ...
        InputStream keyStoreStream = ClassUtil.getResourceAsStream(keyStore, HttpProtocol.class);

        try {
            // Try it as a File resource...
            if(keyStoreStream == null) {
                File keyStoreFile = new File(keyStore);

                if(keyStoreFile.exists() && !keyStoreFile.isDirectory()) {
                    return new KeyMaterial(new FileInputStream(keyStoreFile), keyStorePassword.toCharArray());
                }
            } else {
                return new KeyMaterial(keyStoreStream, keyStorePassword.toCharArray());
            }

            // Try it as a URI resource...
            if(keyStoreStream == null) {
                try {
                    URI fileURI = new URI(keyStore);                   
                    if(fileURI.isAbsolute()) {
                        return new KeyMaterial(fileURI.toURL().openStream(), keyStorePassword.toCharArray());
                    }
                } catch (URISyntaxException e) {
                    throw new ConfigurationException("Failed to load keystore '" + keyStore + "'.");
                }
            }
        } catch (IOException e) {
            throw new ConfigurationException("Failed to load keystore '" + keyStore + "'.", e);
        } catch (GeneralSecurityException e) {
            throw new ConfigurationException("Failed to load keystore '" + keyStore + "'.", e);
        }

        throw new ConfigurationException("Failed to locate keystore '" + keyStore + "'.");
    }

    private ProtocolSocketFactory createFactoryClass(String factory, KeyMaterial keyMaterial, Properties properties) throws ConfigurationException {
        ProtocolSocketFactory socketFactory = null;

        try {
            Class<?> factoryClass = ClassUtil.forName(factory, HttpProtocol.class);

            if(ProtocolSocketFactoryBuilder.class.isAssignableFrom(factoryClass)) {
                try {
                    ProtocolSocketFactoryBuilder factoryBuilder = (ProtocolSocketFactoryBuilder) factoryClass.newInstance();
                    factoryBuilder.setConfiguration(properties);
                    socketFactory = factoryBuilder.newInstance();
                } catch (InstantiationException e) {
                    throw new ConfigurationException("Failed to instantiate ProtocolSocketFactoryBuilder implementation class [" + factory + "]. Must provide a default constructor.", e);
                } catch (IllegalAccessException e) {
                    throw new ConfigurationException("Failed to instantiate ProtocolSocketFactoryBuilder implementation class [" + factory + "]. Must provide a default constructor.", e);
                }
            } else {
                socketFactory = (ProtocolSocketFactory) factoryClass.newInstance();
            }
        } catch (ClassCastException e) {
            throw new ConfigurationException("Class [" + factory + "] must implement [" + ProtocolSocketFactory.class.getName() + "].", e);
        } catch (ClassNotFoundException e) {
            throw new ConfigurationException("ProtocolSocketFactory implementation class [" + factory + "] not found in classpath.", e);
        } catch (InstantiationException e) {
            throw new ConfigurationException("Failed to instantiate ProtocolSocketFactory implementation class [" + factory + "].", e);
        } catch (IllegalAccessException e) {
            throw new ConfigurationException("Failed to instantiate ProtocolSocketFactory implementation class [" + factory + "].", e);
        }

        if(socketFactory instanceof SSLClient && keyMaterial != null) {
            try {
                ((SSLClient)socketFactory).setKeyMaterial(keyMaterial);
            } catch (NoSuchAlgorithmException e) {
                throw new ConfigurationException("Failed to configure SSL Keystore on SSLClient.", e);
            } catch (KeyStoreException e) {
                throw new ConfigurationException("Failed to configure SSL Keystore on SSLClient.", e);
            } catch (KeyManagementException e) {
                throw new ConfigurationException("Failed to configure SSL Keystore on SSLClient.", e);
            } catch (IOException e) {
                throw new ConfigurationException("Failed to configure SSL Keystore on SSLClient.", e);
            } catch (CertificateException e) {
                throw new ConfigurationException("Failed to configure SSL Keystore on SSLClient.", e);
            }
        }

        return socketFactory;
    }


}
TOP

Related Classes of org.jboss.soa.esb.http.configurators.HttpProtocol

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.