You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ro...@apache.org on 2007/02/20 15:28:19 UTC

svn commit: r509577 - in /jakarta/commons/proper/httpclient/trunk/src: contrib/org/apache/commons/httpclient/contrib/ssl/ java/org/apache/commons/httpclient/ test/org/apache/commons/httpclient/

Author: rolandw
Date: Tue Feb 20 06:28:18 2007
New Revision: 509577

URL: http://svn.apache.org/viewvc?view=rev&rev=509577
Log:
HTTPCLIENT-634

Added:
    jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/HostConfigurationWithStickyProtocol.java   (with props)
Modified:
    jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpClient.java
    jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHostConfiguration.java

Added: jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/HostConfigurationWithStickyProtocol.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/HostConfigurationWithStickyProtocol.java?view=auto&rev=509577
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/HostConfigurationWithStickyProtocol.java (added)
+++ jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/HostConfigurationWithStickyProtocol.java Tue Feb 20 06:28:18 2007
@@ -0,0 +1,69 @@
+package org.apache.commons.httpclient.contrib.ssl;
+
+import org.apache.commons.httpclient.HostConfiguration;
+import org.apache.commons.httpclient.HttpHost;
+import org.apache.commons.httpclient.protocol.Protocol;
+
+/**
+ * A kind of HostConfiguration that can retain its Protocol when its host name
+ * or port changes. HttpClient may clone its HostConfigurationWithStickyProtocol
+ * and change the host URL, without changing the specialized Protocol.
+ * <p>
+ * This is useful for integrating a specialized Protocol or SocketFactory; for
+ * example, a SecureSocketFactory that authenticates via SSL. Use
+ * HttpClient.setHostConfiguration to install a
+ * HostConfigurationWithStickyProtocol that contains the specialized Protocol or
+ * SocketFactory.
+ * <p>
+ * An alternative is to use Protocol.registerProtocol to register a specialized
+ * Protocol. But that has drawbacks: it makes it hard to integrate modules (e.g.
+ * web applications in a servlet container) with different strategies, because
+ * they share the specialized Protocol (Protocol.PROTOCOLS is static). Also, it
+ * can't handle multiple socket factories for the same host and port, since the
+ * URL path isn't a parameter to Protocol.getProtocol or socket factory methods.
+ * 
+ * @author John Kristian
+ */
+public class HostConfigurationWithStickyProtocol extends HostConfiguration
+{
+    public HostConfigurationWithStickyProtocol()
+    {
+    }
+
+    public HostConfigurationWithStickyProtocol(HostConfiguration hostConfiguration)
+    {
+        super(hostConfiguration);
+    }
+
+    public Object clone()
+    {
+        return new HostConfigurationWithStickyProtocol(this);
+    }
+
+    public synchronized void setHost(String host, int port, String scheme)
+    {
+        setHost(new HttpHost(host, port, getNewProtocol(host, port, scheme)));
+    }
+
+    /**
+     * Select a Protocol to be used for the given host, port and scheme. The
+     * current Protocol may be selected, if appropriate. This method need not be
+     * thread-safe; the caller must synchronize if necessary.
+     * <p>
+     * This implementation returns the current Protocol if it has the given
+     * scheme; otherwise it returns the Protocol registered for that scheme.
+     */
+    protected Protocol getNewProtocol(String host, int port, String scheme)
+    {
+        final Protocol oldProtocol = getProtocol();
+        if (oldProtocol != null) {
+            final String oldScheme = oldProtocol.getScheme();
+            if (oldScheme == scheme || (oldScheme != null && oldScheme.equalsIgnoreCase(scheme))) {
+                // The old {rotocol has the desired scheme.
+                return oldProtocol; // Retain it.
+            }
+        }
+        return Protocol.getProtocol(scheme);
+    }
+
+}

Propchange: jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/HostConfigurationWithStickyProtocol.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/HostConfigurationWithStickyProtocol.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/HostConfigurationWithStickyProtocol.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpClient.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpClient.java?view=diff&rev=509577&r1=509576&r2=509577
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpClient.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/java/org/apache/commons/httpclient/HttpClient.java Tue Feb 20 06:28:18 2007
@@ -383,7 +383,7 @@
         URI uri = method.getURI(); 
         if (hostconfig == defaulthostconfig || uri.isAbsoluteURI()) {
             // make a deep copy of the host defaults
-            hostconfig = new HostConfiguration(hostconfig);
+            hostconfig = (HostConfiguration) hostconfig.clone();
             if (uri.isAbsoluteURI()) {
                 hostconfig.setHost(uri);
             }

Modified: jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHostConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHostConfiguration.java?view=diff&rev=509577&r1=509576&r2=509577
==============================================================================
--- jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHostConfiguration.java (original)
+++ jakarta/commons/proper/httpclient/trunk/src/test/org/apache/commons/httpclient/TestHostConfiguration.java Tue Feb 20 06:28:18 2007
@@ -160,4 +160,73 @@
         }
     }
 
+    /**
+     * Test that HttpClient uses HostConfiguration.clone (not the copy
+     * constructor) to copy its default HostConfiguration when preparing to
+     * execute a method. This behavior is required to support specialized
+     * Protocols; for example, HostConfigurationWithStickyProtocol.
+     * 
+     * @see org.apache.commons.httpclient.contrib.ssl.HostConfigurationWithStickyProtocol
+     */
+    public void testClientClonesHostConfiguration() throws IOException {
+        this.server.setHttpService(new EchoService());
+        SpecialHostConfiguration configuration = new SpecialHostConfiguration(this.client
+                .getHostConfiguration());
+        configuration.setHost(this.server.getLocalAddress(), this.server.getLocalPort(),
+                new String(HttpURL.DEFAULT_SCHEME));
+        this.client.setHostConfiguration(configuration);
+
+        HttpMethod method = new GetMethod(configuration.getHostURL() + "/test/");
+        try {
+            this.client.executeMethod(method);
+            fail("HostConfiguration wasn't cloned");
+        } catch (ExpectedError e) {
+            assertNotSame("ExpectedError.configuration", configuration, e.configuration);
+        } finally {
+            method.releaseConnection();
+        }
+
+        method = new GetMethod("/test/");
+        try {
+            this.client.executeMethod(method);
+            fail("HostConfiguration wasn't cloned");
+        } catch (ExpectedError e) {
+            assertNotSame("ExpectedError.configuration", configuration, e.configuration);
+        } finally {
+            method.releaseConnection();
+        }
+    }
+
+    /** A HostConfiguration that refuses to provide a protocol. */
+    private class SpecialHostConfiguration extends HostConfiguration
+    {
+        SpecialHostConfiguration(HostConfiguration hostConfiguration)
+        {
+            super(hostConfiguration);
+        }
+
+        public Object clone()
+        {
+            return new SpecialHostConfiguration(this);
+        }
+
+        public synchronized Protocol getProtocol()
+        {
+            throw new ExpectedError(this);
+        }
+    }
+
+    private class ExpectedError extends Error
+    {
+        ExpectedError(SpecialHostConfiguration c)
+        {
+            configuration = c;
+        }
+
+        SpecialHostConfiguration configuration;
+
+        private static final long serialVersionUID = 1L;
+
+    }
+
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org