Author: dkulp Date: Wed Oct 20 02:23:25 2010 New Revision: 1024503 URL: http://svn.apache.org/viewvc?rev=1024503&view=rev Log: Merged revisions 1024491 via svnmerge from https://svn.apache.org/repos/asf/cxf/branches/2.3.x-fixes
................ r1024491 | dkulp | 2010-10-19 21:57:40 -0400 (Tue, 19 Oct 2010) | 19 lines Merged revisions 1024489 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1024489 | dkulp | 2010-10-19 21:52:33 -0400 (Tue, 19 Oct 2010) | 11 lines [CXF-2839] CXF HttpConduit doesn't read VM proxy settings Patch from Guillaume Sauthier applied * Add NonProxyHosts as a configuration parameter in HTTPConduit * Introduce PatternBuilder + TestCase * Only use Proxy when the hostname is not in the nonProxyHosts list * Directly map HTTPClientPolicy.nonProxyHosts as a Pattern * Use PatternBuilder as a JAXB Adapter * Introduce a systemProxyConfiguration in the HTTPConduit * Hopefully make the proxy selection code a little more readable * Use constants for HTTP proxy property names ........ ................ Added: cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java - copied unchanged from r1024491, cxf/branches/2.3.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java cxf/branches/2.2.x-fixes/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java - copied unchanged from r1024491, cxf/branches/2.3.x-fixes/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java Modified: cxf/branches/2.2.x-fixes/ (props changed) cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd Propchange: cxf/branches/2.2.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java?rev=1024503&r1=1024502&r2=1024503&view=diff ============================================================================== --- cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java (original) +++ cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java Wed Oct 20 02:23:25 2010 @@ -42,6 +42,7 @@ import java.util.concurrent.ConcurrentHa import java.util.concurrent.Executor; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Pattern; import javax.xml.namespace.QName; @@ -78,6 +79,7 @@ import org.apache.cxf.transport.https.Ce import org.apache.cxf.transport.https.CertConstraintsInterceptor; import org.apache.cxf.transport.https.CertConstraintsJaxBUtils; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; +import org.apache.cxf.transports.http.configuration.ProxyServerType; import org.apache.cxf.version.Version; import org.apache.cxf.workqueue.WorkQueueManager; import org.apache.cxf.ws.addressing.EndpointReferenceType; @@ -175,7 +177,23 @@ public class HTTPConduit * Endpoint Qname to give the configuration name of this conduit. */ private static final String SC_HTTP_CONDUIT_SUFFIX = ".http-conduit"; - + + /** + * JVM/System property name holding the hostname of the http proxy. + */ + private static final String HTTP_PROXY_HOST = "http.proxyHost"; + + /** + * JVM/System property name holding the port of the http proxy. + */ + private static final String HTTP_PROXY_PORT = "http.proxyPort"; + + /** + * JVM/System property name holding the list of hosts/patterns that + * should not use the proxy configuration. + */ + private static final String HTTP_NON_PROXY_HOSTS = "http.nonProxyHosts"; + /** * This field holds the connection factory, which primarily is used to * factor out SSL specific code from this implementation. @@ -216,11 +234,21 @@ public class HTTPConduit /** * This field holds the QoS configuration settings for this conduit. - * This field is injected via spring configuration based on the conduit + * This field is injected via spring configuration based on the conduit * name. */ private HTTPClientPolicy clientSidePolicy; - + + /** + * This field holds ONLY the static System proxy configuration: + * + http.proxyHost + * + http.proxyPort (default 8080) + * + http.nonProxyHosts (default null) + * It is initialized at the instance creation (and may be null + * if there is no appropriate System properties) + */ + private HTTPClientPolicy systemProxyConfiguration; + /** * This field holds the password authorization configuration. * This field is injected via spring configuration based on the conduit @@ -423,6 +451,28 @@ public class HTTPConduit } } + // Retrieve system properties (if any) + String proxyHost = System.getProperty(HTTP_PROXY_HOST); + if (proxyHost != null) { + // System is configured with a proxy, use it + + systemProxyConfiguration = new HTTPClientPolicy(); + systemProxyConfiguration.setProxyServer(proxyHost); + systemProxyConfiguration.setProxyServerType(ProxyServerType.HTTP); + + // 8080 is the default proxy port value as pert some documentation + String proxyPort = System.getProperty(HTTP_PROXY_PORT, "8080"); + systemProxyConfiguration.setProxyServerPort(Integer.valueOf(proxyPort)); + + // Load non proxy hosts + String nonProxyHosts = System.getProperty(HTTP_NON_PROXY_HOSTS); + if (!StringUtils.isEmpty(nonProxyHosts)) { + Pattern pattern = PatternBuilder.build(nonProxyHosts); + systemProxyConfiguration.setNonProxyHosts(pattern); + } + } + + // Get the correct URLConnection factory based on the // configuration. retrieveConnectionFactory(getAddress()); @@ -501,7 +551,7 @@ public class HTTPConduit HTTPClientPolicy csPolicy = getClient(message); HttpURLConnectionFactory f = getConnectionFactory(currentURL); - HttpURLConnection connection = f.createConnection(getProxy(csPolicy), currentURL); + HttpURLConnection connection = f.createConnection(getProxy(csPolicy, currentURL), currentURL); connection.setDoOutput(true); long timeout = csPolicy.getConnectionTimeout(); @@ -1132,25 +1182,67 @@ public class HTTPConduit * * @return The proxy server or null, if not set. */ - private Proxy getProxy(HTTPClientPolicy policy) { - Proxy proxy = null; - if (policy != null - && policy.isSetProxyServer() - && !StringUtils.isEmpty(policy.getProxyServer())) { - proxy = new Proxy( - Proxy.Type.valueOf(policy.getProxyServerType().toString()), - new InetSocketAddress(policy.getProxyServer(), - policy.getProxyServerPort())); + private Proxy getProxy(HTTPClientPolicy policy, URL currentUrl) { + if (policy != null) { + // Maybe the user has provided some proxy information + if (policy.isSetProxyServer() + && !StringUtils.isEmpty(policy.getProxyServer())) { + return getProxy(policy, currentUrl.getHost()); + } else { + // There is a policy but no Proxy configuration, + // fallback on the system proxy configuration + return getSystemProxy(currentUrl.getHost()); + } + } else { + // Use system proxy configuration + return getSystemProxy(currentUrl.getHost()); + } + } + + /** + * Get the system proxy (if any) for the given URL's host. + */ + private Proxy getSystemProxy(String hostname) { + if (systemProxyConfiguration != null) { + return getProxy(systemProxyConfiguration, hostname); + } + + // No proxy configured + return null; + } + + /** + * Honor the nonProxyHosts property value (if set). + */ + private Proxy getProxy(final HTTPClientPolicy policy, final String hostname) { + if (policy.isSetNonProxyHosts()) { + + // Try to match the URL hostname with the exclusion pattern + Pattern pattern = policy.getNonProxyHosts(); + if (pattern.matcher(hostname).matches()) { + // Excluded hostname -> no proxy + return null; + } } - return proxy; + // Either nonProxyHosts is not set or the pattern did not match + return createProxy(policy); + } + + /** + * Construct a new {...@code Proxy} instance from the given policy. + */ + private Proxy createProxy(final HTTPClientPolicy policy) { + return new Proxy(Proxy.Type.valueOf(policy.getProxyServerType().toString()), + new InetSocketAddress(policy.getProxyServer(), + policy.getProxyServerPort())); } /** * This call places HTTP Header strings into the headers that are relevant - * to the Authorization policies that are set on this conduit by + * to the Authorization policies that are set on this conduit by * configuration. * <p> - * An AuthorizationPolicy may also be set on the message. If so, those + * An AuthorizationPolicy may also be set on the message. If so, those * policies are merged. A user name or password set on the messsage * overrides settings in the AuthorizationPolicy is retrieved from the * configuration. @@ -1436,7 +1528,7 @@ public class HTTPConduit /** * This method sets the Trust Decider for this HTTP Conduit. - * Using this method overrides any trust decider configured for this + * Using this method overrides any trust decider configured for this * HTTPConduit. */ public void setTrustDecider(MessageTrustDecider decider) { @@ -1501,7 +1593,7 @@ public class HTTPConduit /** * This method performs a redirection retransmit in response to * a 302 or 305 response code. - * + * * @param connection The active URL connection * @param message The outbound message. * @param cachedStream The cached request. @@ -1705,7 +1797,7 @@ public class HTTPConduit connection.disconnect(); HTTPClientPolicy cp = getClient(message); - connection = getConnectionFactory(newURL).createConnection(getProxy(cp), newURL); + connection = getConnectionFactory(newURL).createConnection(getProxy(cp, newURL), newURL); connection.setDoOutput(true); // TODO: using Message context to deceided HTTP send properties connection.setConnectTimeout((int)cp.getConnectionTimeout()); Modified: cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb?rev=1024503&r1=1024502&r2=1024503&view=diff ============================================================================== --- cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb (original) +++ cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb Wed Oct 20 02:23:25 2010 @@ -31,4 +31,20 @@ <jaxb:bindings schemaLocation="http://schemas.xmlsoap.org/wsdl/2003-02-11.xsd" node="/xs:schema/xs:complexty...@name='tExtensibilityElement']"> <jaxb:class implClass="org.apache.cxf.wsdl.TExtensibilityElementImpl"/> </jaxb:bindings> + + <!-- Map HTTPClientPolicy.nonProxyHosts to a Pattern using our own 'Adapter' --> + <jaxb:bindings schemaLocation="http-conf.xsd" + node="xs:complexty...@name='HTTPClientPolicy']"> + <jaxb:bindings node="xs:complexContent/xs:extension"> + <jaxb:bindings node="xs:attribu...@name='NonProxyHosts']"> + <jaxb:property> + <jaxb:baseType> + <jaxb:javaType name="java.util.regex.Pattern" + parseMethod="org.apache.cxf.transport.http.PatternBuilder.build" /> + </jaxb:baseType> + </jaxb:property> + </jaxb:bindings> + </jaxb:bindings> + </jaxb:bindings> + </jaxb:bindings> Modified: cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd?rev=1024503&r1=1024502&r2=1024503&view=diff ============================================================================== --- cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd (original) +++ cxf/branches/2.2.x-fixes/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd Wed Oct 20 02:23:25 2010 @@ -349,6 +349,17 @@ </xs:documentation> </xs:annotation> </xs:attribute> + <xs:attribute name="NonProxyHosts" type="xs:string" use="optional"> + <xs:annotation> + <xs:documentation> + Specifies the list of hostnames that will not use the proxy configuration. + Examples of value: + * "localhost" -> A single hostname + * "localhost|www.google.com" -> 2 hostnames that will not use the proxy configuration + * "localhost|www.google.*|*.apache.org" -> It's also possible to use a pattern-like value + </xs:documentation> + </xs:annotation> + </xs:attribute> <xs:attribute name="ProxyServerType" type="http-conf:proxyServerType" use="optional" default="HTTP"> <xs:annotation> <xs:documentation>
