diff --git a/src/examples/org/apache/http/examples/client/ClientExecuteRequest.java b/src/examples/org/apache/http/examples/client/ClientExecuteRequest.java index 591f76418..9266dd485 100644 --- a/src/examples/org/apache/http/examples/client/ClientExecuteRequest.java +++ b/src/examples/org/apache/http/examples/client/ClientExecuteRequest.java @@ -49,6 +49,7 @@ import org.apache.http.protocol.RequestTargetHost; import org.apache.http.protocol.RequestUserAgent; import org.apache.http.conn.Scheme; +import org.apache.http.conn.SchemeSet; import org.apache.http.conn.SocketFactory; import org.apache.http.conn.PlainSocketFactory; import org.apache.http.conn.ClientConnectionManager; @@ -146,7 +147,7 @@ public class ClientExecuteRequest { // Register the "http" protocol scheme, it is required // by the default operator to look up socket factories. SocketFactory sf = PlainSocketFactory.getSocketFactory(); - Scheme.registerScheme("http", new Scheme("http", sf, 80)); + SchemeSet.DEFAULT.register(new Scheme("http", sf, 80)); // Prepare parameters. // Since this example doesn't use the full core framework, diff --git a/src/examples/org/apache/http/examples/conn/ManagerConnectDirect.java b/src/examples/org/apache/http/examples/conn/ManagerConnectDirect.java index c8f7fb3cb..c8f833696 100644 --- a/src/examples/org/apache/http/examples/conn/ManagerConnectDirect.java +++ b/src/examples/org/apache/http/examples/conn/ManagerConnectDirect.java @@ -45,12 +45,15 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpExecutionContext; import org.apache.http.conn.Scheme; +import org.apache.http.conn.SchemeSet; import org.apache.http.conn.SocketFactory; import org.apache.http.conn.PlainSocketFactory; import org.apache.http.conn.HostConfiguration; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.impl.ThreadSafeClientConnManager; +import org.apache.http.conn.impl.DefaultClientConnectionOperator; @@ -77,6 +80,12 @@ public class ManagerConnectDirect { */ private static HttpParams defaultParameters = null; + /** + * The scheme set. + * Instantiated in {@link #setup setup}. + */ + private static SchemeSet supportedSchemes; + /** * Main entry point to this example. @@ -143,7 +152,13 @@ public class ManagerConnectDirect { private final static ClientConnectionManager createManager() { - return new ThreadSafeClientConnManager(getParams()); + + return new ThreadSafeClientConnManager(getParams()) { + //@@@ we need a better way to pass in the SchemeSet or operator + protected ClientConnectionOperator createConnectionOperator() { + return new DefaultClientConnectionOperator(supportedSchemes); + } + }; } @@ -155,8 +170,9 @@ public class ManagerConnectDirect { // Register the "http" protocol scheme, it is required // by the default operator to look up socket factories. + supportedSchemes = new SchemeSet(); SocketFactory sf = PlainSocketFactory.getSocketFactory(); - Scheme.registerScheme("http", new Scheme("http", sf, 80)); + supportedSchemes.register(new Scheme("http", sf, 80)); // Prepare parameters. // Since this example doesn't use the full core framework, diff --git a/src/examples/org/apache/http/examples/conn/ManagerConnectProxy.java b/src/examples/org/apache/http/examples/conn/ManagerConnectProxy.java index d0a15a234..1b1e22f65 100644 --- a/src/examples/org/apache/http/examples/conn/ManagerConnectProxy.java +++ b/src/examples/org/apache/http/examples/conn/ManagerConnectProxy.java @@ -45,13 +45,16 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpExecutionContext; import org.apache.http.conn.Scheme; +import org.apache.http.conn.SchemeSet; import org.apache.http.conn.SocketFactory; import org.apache.http.conn.PlainSocketFactory; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.HostConfiguration; import org.apache.http.conn.ManagedClientConnection; import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionOperator; import org.apache.http.conn.impl.ThreadSafeClientConnManager; +import org.apache.http.conn.impl.DefaultClientConnectionOperator; @@ -78,6 +81,12 @@ public class ManagerConnectProxy { */ private static HttpParams defaultParameters = null; + /** + * The scheme set. + * Instantiated in {@link #setup setup}. + */ + private static SchemeSet supportedSchemes; + /** * Main entry point to this example. @@ -170,7 +179,13 @@ public class ManagerConnectProxy { private final static ClientConnectionManager createManager() { - return new ThreadSafeClientConnManager(getParams()); + + return new ThreadSafeClientConnManager(getParams()) { + //@@@ we need a better way to pass in the SchemeSet or operator + protected ClientConnectionOperator createConnectionOperator() { + return new DefaultClientConnectionOperator(supportedSchemes); + } + }; } @@ -182,10 +197,11 @@ public class ManagerConnectProxy { // Register the "http" and "https" protocol schemes, they are // required by the default operator to look up socket factories. + supportedSchemes = new SchemeSet(); SocketFactory sf = PlainSocketFactory.getSocketFactory(); - Scheme.registerScheme("http", new Scheme("http", sf, 80)); + supportedSchemes.register(new Scheme("http", sf, 80)); sf = SSLSocketFactory.getSocketFactory(); - Scheme.registerScheme("https", new Scheme("https", sf, 80)); + supportedSchemes.register(new Scheme("https", sf, 80)); // Prepare parameters. // Since this example doesn't use the full core framework, diff --git a/src/examples/org/apache/http/examples/conn/OperatorConnectDirect.java b/src/examples/org/apache/http/examples/conn/OperatorConnectDirect.java index 0b475bd10..dbf2ac0f7 100644 --- a/src/examples/org/apache/http/examples/conn/OperatorConnectDirect.java +++ b/src/examples/org/apache/http/examples/conn/OperatorConnectDirect.java @@ -45,6 +45,7 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpExecutionContext; import org.apache.http.conn.Scheme; +import org.apache.http.conn.SchemeSet; import org.apache.http.conn.SocketFactory; import org.apache.http.conn.PlainSocketFactory; import org.apache.http.conn.OperatedClientConnection; @@ -75,7 +76,13 @@ public class OperatorConnectDirect { * The default parameters. * Instantiated in {@link #setup setup}. */ - private static HttpParams defaultParameters = null; + private static HttpParams defaultParameters; + + /** + * The scheme set. + * Instantiated in {@link #setup setup}. + */ + private static SchemeSet supportedSchemes; /** @@ -123,7 +130,7 @@ public class OperatorConnectDirect { private final static ClientConnectionOperator createOperator() { - return new DefaultClientConnectionOperator(); + return new DefaultClientConnectionOperator(supportedSchemes); } private final static OperatedClientConnection createConnection() { @@ -139,8 +146,9 @@ public class OperatorConnectDirect { // Register the "http" protocol scheme, it is required // by the default operator to look up socket factories. + supportedSchemes = new SchemeSet(); SocketFactory sf = PlainSocketFactory.getSocketFactory(); - Scheme.registerScheme("http", new Scheme("http", sf, 80)); + supportedSchemes.register(new Scheme("http", sf, 80)); // Prepare parameters. // Since this example doesn't use the full core framework, diff --git a/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java b/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java index ab7855acd..fac531031 100644 --- a/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java +++ b/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java @@ -45,6 +45,7 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpExecutionContext; import org.apache.http.conn.Scheme; +import org.apache.http.conn.SchemeSet; import org.apache.http.conn.SocketFactory; import org.apache.http.conn.PlainSocketFactory; import org.apache.http.conn.ssl.SSLSocketFactory; @@ -78,6 +79,12 @@ public class OperatorConnectProxy { */ private static HttpParams defaultParameters = null; + /** + * The scheme set. + * Instantiated in {@link #setup setup}. + */ + private static SchemeSet supportedSchemes; + /** * Main entry point to this example. @@ -155,7 +162,7 @@ public class OperatorConnectProxy { private final static ClientConnectionOperator createOperator() { - return new DefaultClientConnectionOperator(); + return new DefaultClientConnectionOperator(supportedSchemes); } private final static OperatedClientConnection createConnection() { @@ -171,10 +178,11 @@ public class OperatorConnectProxy { // Register the "http" and "https" protocol schemes, they are // required by the default operator to look up socket factories. + supportedSchemes = new SchemeSet(); SocketFactory sf = PlainSocketFactory.getSocketFactory(); - Scheme.registerScheme("http", new Scheme("http", sf, 80)); + supportedSchemes.register(new Scheme("http", sf, 80)); sf = SSLSocketFactory.getSocketFactory(); - Scheme.registerScheme("https", new Scheme("https", sf, 80)); + supportedSchemes.register(new Scheme("https", sf, 80)); // Prepare parameters. // Since this example doesn't use the full core framework, diff --git a/src/java/org/apache/http/conn/Scheme.java b/src/java/org/apache/http/conn/Scheme.java index a6380f94e..b0d988ea7 100644 --- a/src/java/org/apache/http/conn/Scheme.java +++ b/src/java/org/apache/http/conn/Scheme.java @@ -38,212 +38,185 @@ import org.apache.http.util.CharArrayBuffer; import org.apache.http.util.LangUtils; /** - * A class to encapsulate the specifics of a protocol scheme. This class also - * provides the ability to customize the set and characteristics of the - * schemes used. - * - *

One use case for modifying the default set of protocols would be to set a - * custom SSL socket factory. This would look something like the following: - *

 
- * Scheme myHTTPS = new Scheme( "https", new MySSLSocketFactory(), 443 );
- * 
- * Scheme.registerScheme( "https", myHTTPS );
+ * Encapsulates specifics of a protocol scheme such as "http" or "https".
+ * Schemes are identified by lowercase names.
+ * Supported schemes are typically collected in a {@link SchemeSet SchemeSet}.
+ *
+ * 

+ * For example, to configure support for "https://" URLs, + * you could write code like the following: + *

+ *
+ * Scheme https = new Scheme("https", new MySecureSocketFactory(), 443);
+ * SchemeSet.DEFAULT.register(https);
  * 
* + * @author Roland Weber * @author Michael Becke * @author Jeff Dever * @author Mike Bowler - * - * @since 2.0 */ -public class Scheme { +public final class Scheme { - /** The available schemes */ - private static final Map SCHEMES = Collections.synchronizedMap(new HashMap()); - - /** - * Registers a new scheme with the given identifier. If a scheme with - * the given ID already exists it will be overridden. This ID is the same - * one used to retrieve the scheme from getScheme(String). - * - * @param id the identifier for this scheme - * @param scheme the scheme to register - * - * @see #getScheme(String) - */ - public static void registerScheme(final String id, final Scheme scheme) { - if (id == null) { - throw new IllegalArgumentException("Id may not be null"); - } - if (scheme == null) { - throw new IllegalArgumentException("Scheme may not be null"); - } - SCHEMES.put(id, scheme); - } - - /** - * Unregisters the scheme with the given ID. - * - * @param id the ID of the scheme to remove - */ - public static void unregisterScheme(final String id) { - if (id == null) { - throw new IllegalArgumentException("Id may not be null"); - } - SCHEMES.remove(id); - } - - /** - * Gets the scheme with the given ID. - * - * @param id the scheme ID - * - * @return Scheme a scheme - * - * @throws IllegalStateException if a scheme with the ID cannot be found - */ - public static Scheme getScheme(String id) - throws IllegalStateException { - - if (id == null) { - throw new IllegalArgumentException("id is null"); - } - Scheme scheme = (Scheme) SCHEMES.get(id); - if (scheme == null) { - throw new IllegalStateException("Unsupported scheme: '" + id + "'"); - } - return scheme; - } - - /** the scheme of this scheme (e.g. http, https) */ - private String name; + /** The name of this scheme, in lowercase. (e.g. http, https) */ + private final String name; /** The socket factory for this scheme */ - private SocketFactory socketFactory; + private final SocketFactory socketFactory; /** The default port for this scheme */ - private int defaultPort; + private final int defaultPort; - /** True if this scheme allows for layered connections */ - private boolean layered; - + /** Indicates whether this scheme allows for layered connections */ + private final boolean layered; + + + /** A string representation, for {@link #toString toString}. */ + private String stringRep; + + /** - * Constructs a new scheme. + * Creates a new scheme. * Whether the created scheme allows for layered connections * depends on the class of factory. - * - * @param name the scheme name (e.g. http, https) - * @param factory the factory for creating sockets for communication using - * this scheme - * @param defaultPort the port this scheme defaults to + * + * @param name the scheme name, for example "http". + * The name will be converted to lowercase. + * @param factory the factory for creating sockets for communication + * with this scheme + * @param port the default port for this scheme */ - public Scheme(final String name, final SocketFactory factory, int defaultPort) { - + public Scheme(final String name, + final SocketFactory factory, + final int port) { + if (name == null) { - throw new IllegalArgumentException("Scheme name may not be null"); + throw new IllegalArgumentException + ("Scheme name may not be null"); } if (factory == null) { - throw new IllegalArgumentException("Socket factory may not be null"); + throw new IllegalArgumentException + ("Socket factory may not be null"); } - if (defaultPort <= 0) { - throw new IllegalArgumentException("Port is invalid: " + defaultPort); + if ((port <= 0) || (port > 0xffff)) { + throw new IllegalArgumentException + ("Port is invalid: " + port); } - - this.name = name; + + this.name = name.toLowerCase(); this.socketFactory = factory; - this.defaultPort = defaultPort; + this.defaultPort = port; this.layered = (factory instanceof SecureSocketFactory); } - + + /** - * Returns the defaultPort. - * @return int + * Obtains the default port. + * + * @return the default port for this scheme */ - public int getDefaultPort() { + public final int getDefaultPort() { return defaultPort; } + /** - * Returns the socketFactory. If secure the factory is a SecureSocketFactory. - * @return SocketFactory + * Obtains the socket factory. + * If this scheme is {@link #isLayered layered}, the factory implements + * {@link SecureSocketFactory SecureSocketFactory}. + * + * @return the socket factory for this scheme */ - public SocketFactory getSocketFactory() { + public final SocketFactory getSocketFactory() { return socketFactory; } + /** - * Returns the scheme. - * @return The scheme + * Obtains the scheme name. + * + * @return the name of this scheme, in lowercase */ - public String getName() { + public final String getName() { return name; } + /** * Indicates whether this scheme allows for layered connections. + * * @return true if layered connections are possible, * false otherwise */ - public boolean isLayered() { + public final boolean isLayered() { return layered; } - + + /** - * Resolves the correct port for this scheme. Returns the given port if - * valid or the default port otherwise. + * Resolves the correct port for this scheme. + * Returns the given port if it is valid, the default port otherwise. * - * @param port the port to be resolved + * @param port the port to be resolved, + * a negative number to obtain the default port * * @return the given port or the defaultPort */ - public int resolvePort(int port) { - return port <= 0 ? getDefaultPort() : port; + public final int resolvePort(int port) { + return ((port <= 0) || (port > 0xffff)) ? defaultPort : port; } + /** * Return a string representation of this object. - * @return a string representation of this object. + * + * @return a human-readable string description of this scheme */ - public String toString() { - CharArrayBuffer buffer = new CharArrayBuffer(32); - buffer.append(this.name); - buffer.append(':'); - buffer.append(Integer.toString(this.defaultPort)); - return buffer.toString(); - } - - /** - * Return true if the specified object equals this object. - * @param obj The object to compare against. - * @return true if the objects are equal. - */ - public boolean equals(Object obj) { - if (obj == null) return false; - if (this == obj) return true; - if (obj instanceof Scheme) { - Scheme p = (Scheme) obj; - return ( - defaultPort == p.getDefaultPort() - && name.equalsIgnoreCase(p.getName()) - && layered == p.isLayered() - && socketFactory.equals(p.getSocketFactory())); - - } else { - return false; + public final String toString() { + if (stringRep == null) { + CharArrayBuffer buffer = new CharArrayBuffer(32); + buffer.append(this.name); + buffer.append(':'); + buffer.append(Integer.toString(this.defaultPort)); + stringRep = buffer.toString(); } - + return stringRep; } + /** - * Return a hash code for this object - * @return The hash code. + * Compares this scheme to an object. + * + * @param obj the object to compare with + * + * @return true iff the argument is equal to this scheme + */ + public final boolean equals(Object obj) { + if (obj == null) return false; + if (this == obj) return true; + if (!(obj instanceof Scheme)) return false; + + Scheme s = (Scheme) obj; + return (name.equals(s.name) && + defaultPort == s.defaultPort && + layered == s.layered && + socketFactory.equals(s.socketFactory) + ); + } // equals + + + /** + * Obtains a hash code for this scheme. + * + * @return the hash code */ public int hashCode() { int hash = LangUtils.HASH_SEED; hash = LangUtils.hashCode(hash, this.defaultPort); - hash = LangUtils.hashCode(hash, this.name.toLowerCase()); + hash = LangUtils.hashCode(hash, this.name); hash = LangUtils.hashCode(hash, this.layered); hash = LangUtils.hashCode(hash, this.socketFactory); return hash; } -} + +} // class Scheme diff --git a/src/java/org/apache/http/conn/SchemeSet.java b/src/java/org/apache/http/conn/SchemeSet.java new file mode 100644 index 000000000..5880fd0ff --- /dev/null +++ b/src/java/org/apache/http/conn/SchemeSet.java @@ -0,0 +1,167 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn; + + +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Collections; + + + +/** + * A set of supported protocol {@link Scheme schemes}. + * Schemes are identified by lowercase names. + * + * @author Roland Weber + * + * + * + * @version $Revision$ $Date$ + * + * @since 4.0 + */ +public final class SchemeSet { + + /** + * A default scheme set. + * It is empty by default, but can be initialized by any application. + * The default scheme set should only be used by applications that + * know for sure that this class is NOT shared with any other applications. + * For example a Servlet, Portlet or EJB should not rely on being the + * only user of this class. + */ + public final static SchemeSet DEFAULT = new SchemeSet(); + + + /** The available schemes in this set. */ + private final Map registeredSchemes; + + + /** + * Creates a new, empty scheme set. + */ + public SchemeSet() { + registeredSchemes = Collections.synchronizedMap(new HashMap()); + } + + + /** + * Obtains a scheme by name. + * + * @param name the name of the scheme to look up (in lowercase) + * + * @return the scheme, never null + * + * @throws IllegalStateException + * if the scheme with the given name is not registered + */ + public final Scheme getScheme(String name) { + Scheme found = get(name); + if (found == null) { + throw new IllegalStateException + ("Scheme '"+name+"' not registered."); + } + return found; + } + + + /** + * Obtains a scheme by name, if registered. + * + * @param name the name of the scheme to look up (in lowercase) + * + * @return the scheme, or + * null if there is none by this name + */ + public final Scheme get(String name) { + if (name == null) + throw new IllegalArgumentException("Name must not be null."); + + // leave it to the caller to use the correct name - all lowercase + //name = name.toLowerCase(); + Scheme found = (Scheme) registeredSchemes.get(name); + return found; + } + + + /** + * Registers a scheme in this set. + * The scheme can later be retrieved by it's name + * using {@link #getScheme getScheme} or {@link #get get}. + * + * @param sch the scheme to register + * + * @return the scheme previously registered with that name, or + * null if none was registered + */ + public final Scheme register(Scheme sch) { + if (sch == null) + throw new IllegalArgumentException("Scheme must not be null."); + + Scheme old = (Scheme) registeredSchemes.put(sch.getName(), sch); + return old; + } + + + /** + * Unregisters a scheme from this set. + * + * @param name the name of the scheme to unregister (in lowercase) + * + * @return the unregistered scheme, or + * null if there was none + */ + public final Scheme unregister(String name) { + if (name == null) + throw new IllegalArgumentException("Name must not be null."); + + // leave it to the caller to use the correct name - all lowercase + //name = name.toLowerCase(); + Scheme gone = (Scheme) registeredSchemes.remove(name); + return gone; + } + + + /** + * Obtains the names of the registered schemes. + * + * @return iterator over the registered scheme names. + * The iterator supports {@link Iterator#remove remove()}. + */ + public final Iterator getSchemeNames() { + return registeredSchemes.keySet().iterator(); + } + + +} // class SchemeSet + diff --git a/src/java/org/apache/http/conn/impl/DefaultClientConnectionOperator.java b/src/java/org/apache/http/conn/impl/DefaultClientConnectionOperator.java index 54f541e9f..e916930a4 100644 --- a/src/java/org/apache/http/conn/impl/DefaultClientConnectionOperator.java +++ b/src/java/org/apache/http/conn/impl/DefaultClientConnectionOperator.java @@ -41,6 +41,7 @@ import org.apache.http.params.HttpConnectionParams; import org.apache.http.protocol.HttpContext; import org.apache.http.conn.Scheme; +import org.apache.http.conn.SchemeSet; import org.apache.http.conn.SocketFactory; import org.apache.http.conn.SecureSocketFactory; import org.apache.http.conn.OperatedClientConnection; @@ -50,7 +51,7 @@ import org.apache.http.conn.ClientConnectionOperator; /** * Default implementation of a * {@link ClientConnectionOperator ClientConnectionOperator}. - * It uses the {@link Scheme Scheme} class to look up + * It uses a {@link SchemeSet SchemeSet} to look up * {@link SocketFactory SocketFactory} objects. * * @author Roland Weber @@ -65,8 +66,28 @@ public class DefaultClientConnectionOperator implements ClientConnectionOperator { + /** The scheme set for looking up socket factories. */ + protected SchemeSet schemeSet; - // public default constructor + + /** + * Creates a new client connection operator. + * Uses {@link SchemeSet#DEFAULT SchemeSet.DEFAULT} + * as the scheme set. + */ + public DefaultClientConnectionOperator() { + this(null); + } + + /** + * Creates a new client connection operator for the given scheme set. + * + * @param schemes the scheme set, or null to use + * {@link SchemeSet#DEFAULT SchemeSet.DEFAULT} + */ + public DefaultClientConnectionOperator(SchemeSet schemes) { + schemeSet = (schemes != null) ? schemes : SchemeSet.DEFAULT; + } @@ -96,9 +117,9 @@ public class DefaultClientConnectionOperator } InetAddress local = null; - //@@@ TODO: deal with local address stuff from context + //@@@ TODO: deal with local address stuff (from context?) - final Scheme schm = Scheme.getScheme(target.getSchemeName()); + final Scheme schm = schemeSet.getScheme(target.getSchemeName()); if (schm == null) { throw new IllegalArgumentException ("Unknown scheme '" + target.getSchemeName() + @@ -148,7 +169,7 @@ public class DefaultClientConnectionOperator ("Connection must be open."); } - final Scheme schm = Scheme.getScheme(target.getSchemeName()); + final Scheme schm = schemeSet.getScheme(target.getSchemeName()); if (schm == null) { throw new IllegalArgumentException ("Unknown scheme '" + target.getSchemeName() + diff --git a/src/java/org/apache/http/conn/impl/DefaultHttpHostConnection.java b/src/java/org/apache/http/conn/impl/DefaultHttpHostConnection.java index d2289530d..e005f451c 100644 --- a/src/java/org/apache/http/conn/impl/DefaultHttpHostConnection.java +++ b/src/java/org/apache/http/conn/impl/DefaultHttpHostConnection.java @@ -41,6 +41,7 @@ import org.apache.http.conn.HostConfiguration; import org.apache.http.conn.HttpConnectionManager; import org.apache.http.conn.HttpHostConnection; import org.apache.http.conn.Scheme; +import org.apache.http.conn.SchemeSet; import org.apache.http.conn.SecureSocketFactory; import org.apache.http.conn.SocketFactory; import org.apache.http.impl.SocketHttpClientConnection; @@ -130,7 +131,7 @@ public class DefaultHttpHostConnection } // Determine the type of the connection - Scheme scheme = Scheme.getScheme(host.getSchemeName()); + Scheme scheme = SchemeSet.DEFAULT.getScheme(host.getSchemeName()); SocketFactory socketFactory = scheme.getSocketFactory(); boolean secure = (socketFactory instanceof SecureSocketFactory); boolean proxied = (proxyHost != null); @@ -150,10 +151,10 @@ public class DefaultHttpHostConnection port = scheme.getDefaultPort(); } if (secure && proxied) { - scheme = Scheme.getScheme("http"); + scheme = SchemeSet.DEFAULT.getScheme("http"); socketFactory = scheme.getSocketFactory(); } else { - scheme = Scheme.getScheme(target.getSchemeName()); + scheme = SchemeSet.DEFAULT.getScheme(target.getSchemeName()); } socketFactory = scheme.getSocketFactory(); Socket socket = socketFactory.connectSocket( @@ -193,7 +194,7 @@ public class DefaultHttpHostConnection LOG.debug("Secure tunnel to " + host); } - Scheme scheme = Scheme.getScheme(host.getSchemeName()); + Scheme scheme = SchemeSet.DEFAULT.getScheme(host.getSchemeName()); SocketFactory socketFactory = scheme.getSocketFactory(); boolean secure = (socketFactory instanceof SecureSocketFactory); boolean proxied = (proxyHost != null); diff --git a/src/test/org/apache/http/conn/TestScheme.java b/src/test/org/apache/http/conn/TestScheme.java index b433c9219..5d211a7b8 100644 --- a/src/test/org/apache/http/conn/TestScheme.java +++ b/src/test/org/apache/http/conn/TestScheme.java @@ -31,6 +31,8 @@ package org.apache.http.conn; +import java.util.Iterator; + import org.apache.http.conn.ssl.SSLSocketFactory; import junit.framework.Test; @@ -38,8 +40,9 @@ import junit.framework.TestCase; import junit.framework.TestSuite; /** - * Unit tests for {@link Scheme}. + * Unit tests for {@link Scheme} and {@link SchemeSet}. * + * @author Roland Weber * @author Oleg Kalnichevski */ public class TestScheme extends TestCase { @@ -58,77 +61,153 @@ public class TestScheme extends TestCase { } public void testConstructor() { - Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme http = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); assertEquals("http", http.getName()); assertEquals(80, http.getDefaultPort()); - assertEquals(PlainSocketFactory.getSocketFactory(), http.getSocketFactory()); + assertSame(PlainSocketFactory.getSocketFactory(), + http.getSocketFactory()); assertFalse(http.isLayered()); - Scheme https = new Scheme("http", SSLSocketFactory.getSocketFactory(), 443); - assertEquals("http", https.getName()); + Scheme https = new Scheme + ("https", SSLSocketFactory.getSocketFactory(), 443); + assertEquals("https", https.getName()); assertEquals(443, https.getDefaultPort()); - assertEquals(SSLSocketFactory.getSocketFactory(), https.getSocketFactory()); + assertSame(SSLSocketFactory.getSocketFactory(), + https.getSocketFactory()); assertTrue(https.isLayered()); - + + Scheme hTtP = new Scheme + ("hTtP", PlainSocketFactory.getSocketFactory(), 80); + assertEquals("http", hTtP.getName()); + // the rest is no different from above + try { - new Scheme(null, PlainSocketFactory.getSocketFactory(), 80); - fail("IllegalArgumentException should have been thrown"); + new Scheme(null, PlainSocketFactory.getSocketFactory(), 80); + fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { - // expected + // expected } try { - new Scheme("http", null, 80); - fail("IllegalArgumentException should have been thrown"); + new Scheme("http", null, 80); + fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { - // expected + // expected } try { - new Scheme("http", PlainSocketFactory.getSocketFactory(), -1); - fail("IllegalArgumentException should have been thrown"); + new Scheme("http", PlainSocketFactory.getSocketFactory(), -1); + fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { - // expected + // expected + } + try { + new Scheme("http", PlainSocketFactory.getSocketFactory(), 70000); + fail("IllegalArgumentException should have been thrown"); + } catch (IllegalArgumentException ex) { + // expected } } public void testRegisterUnregister() { - Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme https = new Scheme("http", SSLSocketFactory.getSocketFactory(), 443); - Scheme.registerScheme("http", http); - Scheme.registerScheme("https", https); - assertEquals(http, Scheme.getScheme("http")); - assertEquals(https, Scheme.getScheme("https")); - Scheme.unregisterScheme("http"); - Scheme.unregisterScheme("https"); - + SchemeSet schmset = new SchemeSet(); + + Scheme http = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme https = new Scheme + ("https", SSLSocketFactory.getSocketFactory(), 443); + Scheme myhttp = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); + + assertNull(schmset.register(myhttp)); + assertNull(schmset.register(https)); + assertSame(myhttp, schmset.register(http)); + assertSame(http, schmset.getScheme("http")); + assertSame(https, schmset.getScheme("https")); + + schmset.unregister("http"); + schmset.unregister("https"); + + assertNull(schmset.get("http")); // get() does not throw exception try { - Scheme.getScheme("http"); - fail("IllegalStateException should have been thrown"); + schmset.getScheme("http"); // getScheme() does throw exception + fail("IllegalStateException should have been thrown"); } catch (IllegalStateException ex) { - // expected + // expected } } + + public void testIterator() { + SchemeSet schmset = new SchemeSet(); + + Iterator iter = schmset.getSchemeNames(); + assertNotNull(iter); + assertFalse(iter.hasNext()); + + Scheme http = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme https = new Scheme + ("https", SSLSocketFactory.getSocketFactory(), 443); + + schmset.register(http); + schmset.register(https); + + iter = schmset.getSchemeNames(); + assertNotNull(iter); + assertTrue(iter.hasNext()); + + boolean flaghttp = false; + boolean flaghttps = false; + String name = (String) iter.next(); + assertTrue(iter.hasNext()); + + if ("http".equals(name)) + flaghttp = true; + else if ("https".equals(name)) + flaghttps = true; + else + fail("unexpected name in iterator: " + name); + + assertNotNull(schmset.get(name)); + iter.remove(); + assertTrue(iter.hasNext()); + assertNull(schmset.get(name)); + + name = (String) iter.next(); + assertFalse(iter.hasNext()); + + if ("http".equals(name)) { + if (flaghttp) fail("name 'http' found twice"); + } else if ("https".equals(name)) { + if (flaghttps) fail("name 'https' found twice"); + } else { + fail("unexpected name in iterator: " + name); + } + + assertNotNull(schmset.get(name)); + } + public void testIllegalRegisterUnregister() { - Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); + SchemeSet schmset = new SchemeSet(); try { - Scheme.registerScheme(null, http); + schmset.register(null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } try { - Scheme.registerScheme("http", null); + schmset.unregister(null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } try { - Scheme.unregisterScheme(null); + schmset.get(null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected } try { - Scheme.getScheme(null); + schmset.getScheme(null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException ex) { // expected @@ -136,23 +215,33 @@ public class TestScheme extends TestCase { } public void testResolvePort() { - Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme http = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); + assertEquals(8080, http.resolvePort(8080)); assertEquals(80, http.resolvePort(-1)); } public void testHashCode() { - Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme myhttp = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme https = new Scheme("http", SSLSocketFactory.getSocketFactory(), 443); + Scheme http = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme myhttp = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme https = new Scheme + ("http", SSLSocketFactory.getSocketFactory(), 443); + assertTrue(http.hashCode() != https.hashCode()); assertTrue(http.hashCode() == myhttp.hashCode()); } public void testEquals() { - Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme myhttp = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); - Scheme https = new Scheme("http", SSLSocketFactory.getSocketFactory(), 443); + Scheme http = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme myhttp = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme https = new Scheme + ("http", SSLSocketFactory.getSocketFactory(), 443); + assertFalse(http.equals(https)); assertFalse(http.equals(null)); assertFalse(http.equals("http")); @@ -160,9 +249,10 @@ public class TestScheme extends TestCase { assertTrue(http.equals(myhttp)); assertFalse(http.equals(https)); } - + public void testToString() { - Scheme http = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); + Scheme http = new Scheme + ("http", PlainSocketFactory.getSocketFactory(), 80); assertEquals("http:80", http.toString()); }