package er.distribution.client; import java.io.IOException; import java.net.Socket; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.swing.SwingUtilities; import org.apache.log4j.Logger; import com.webobjects.eodistribution.client.EOHTTPChannel; import com.webobjects.foundation.NSCoder; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSPropertyListSerialization; import er.extensions.foundation.ERXProperties; /** * * @property er.distribution.disallowHttpRequestsOnEventThread * throw an exception if an HTTP request is attempted on the Event Dispatch Thread (EDT); prevents creating a terrible UI. * * @property er.distribution.trustAllSslCertificates * disable SSL certificate checking; useful for development mode, but not really safe for production * * @property er.distribution.applicationUrl * the URL for connecting to the server application. * * @author john * */ public class ERHTTPChannel extends EOHTTPChannel { private static final Logger log = Logger.getLogger(ERHTTPChannel.class); private String url; public ERHTTPChannel() { this(ERXProperties.stringForKey("er.distribution.applicationUrl")); } public ERHTTPChannel(String url) { this.url = url; if (url != null) { setConnectionDictionary(new NSDictionary<String, String>(url, EOHTTPChannel.ApplicationURLKey)); } } public String url() { return url; } @Override public Object responseToMessage(Object message, NSCoder coder) { if (log.isDebugEnabled()) { log.debug("request: " + message.toString().replace('\n', ' ')); } if (NSPropertyListSerialization.booleanForString(System.getProperty("er.distribution.disallowHttpRequestsOnEventThread")) && SwingUtilities.isEventDispatchThread() && message.toString().indexOf("clientSideRequestHandleExit") == -1) { throw new IllegalStateException("HTTP requests are not allowed on the UI thread."); } Object response = super.responseToMessage(message, coder); // if (log.isDebugEnabled()) { // log.debug("response: " + response.toString().replace('\n', ' ')); // } return response; } @Override public Socket createSocket(String protocol, String hostName, int portNumber) throws IOException { if ("https".equals(protocol)) { return createSslSocket(protocol, hostName, portNumber); } else { return super.createSocket(protocol, hostName, portNumber); } } protected Socket createSslSocket(String protocol, String hostName, int portNumber) throws IOException { try { SocketFactory socketFactory; if (NSPropertyListSerialization.booleanForString(System.getProperty("er.distribution.trustAllSslCertificates"))) { socketFactory = trustAllSocketFactory(); } else { socketFactory = SSLSocketFactory.getDefault(); } Socket socket = socketFactory.createSocket(hostName, portNumber == 80 ? 443 : portNumber); return socket; } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (KeyManagementException e) { throw new RuntimeException(e); } } protected SocketFactory trustAllSocketFactory() throws NoSuchAlgorithmException, KeyManagementException { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { // Trust always } public void checkServerTrusted(X509Certificate[] certs, String authType) { // Trust always } } }; // Install the all-trusting trust manager SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); return sc.getSocketFactory(); } }