cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dk...@apache.org
Subject svn commit: r1024489 - in /cxf/trunk/rt/transports/http/src: main/java/org/apache/cxf/transport/http/ main/resources/schemas/wsdl/ test/java/org/apache/cxf/transport/http/
Date Wed, 20 Oct 2010 01:52:34 GMT
Author: dkulp
Date: Wed Oct 20 01:52:33 2010
New Revision: 1024489

URL: http://svn.apache.org/viewvc?rev=1024489&view=rev
Log:
[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/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java
  (with props)
    cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java
  (with props)
Modified:
    cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
    cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb
    cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd

Modified: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java?rev=1024489&r1=1024488&r2=1024489&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
(original)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
Wed Oct 20 01:52:33 2010
@@ -44,6 +44,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.
@@ -212,11 +230,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 
@@ -419,6 +447,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.
         connectionFactory = retrieveConnectionFactory(getAddress());
@@ -502,7 +552,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();
@@ -1045,25 +1095,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.
@@ -1351,7 +1443,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) {
@@ -1416,7 +1508,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.
@@ -1620,7 +1712,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());

Added: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java?rev=1024489&view=auto
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java
(added)
+++ cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java
Wed Oct 20 01:52:33 2010
@@ -0,0 +1,53 @@
+/**
+ * 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.
+ */
+package org.apache.cxf.transport.http;
+
+import java.util.regex.Pattern;
+
+/**
+ * Convert a "nonProxyHosts" formatted String into a usable regular expression usable in
{@code Pattern}. 
+ */
+public final class PatternBuilder {
+
+    /**
+     * Default empty constructor fot utility class.
+     */
+    private PatternBuilder() { }
+
+    /**
+     * Builds a {@code Pattern} from the given String argument.
+     * @param value pattern like expression
+     * @return a usable {@code Pattern}.
+     */
+    public static Pattern build(final String value) {
+
+        // Here is a usual nonProxyHosts value:
+        // localhost|www.google.*|*.apache.org
+        // '|' are separator for 'or' group
+        // '.' are real dots
+        // '*' means any char (length >= 0)
+
+        // So we need to convert that value a little bit to make it a real regular expression
suited for Java
+
+        String regexp = value.replace(".", "\\.");
+        regexp = regexp.replace("*", ".*");
+
+        return Pattern.compile(regexp);
+    }
+}

Propchange: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/transports/http/src/main/java/org/apache/cxf/transport/http/PatternBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb?rev=1024489&r1=1024488&r2=1024489&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb (original)
+++ cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xjb Wed Oct 20
01:52:33 2010
@@ -31,4 +31,20 @@
     <jaxb:bindings schemaLocation="http://schemas.xmlsoap.org/wsdl/2003-02-11.xsd" node="/xs:schema/xs:complexType[@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:complexType[@name='HTTPClientPolicy']">
+        <jaxb:bindings node="xs:complexContent/xs:extension">
+            <jaxb:bindings node="xs:attribute[@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/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd?rev=1024489&r1=1024488&r2=1024489&view=diff
==============================================================================
--- cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd (original)
+++ cxf/trunk/rt/transports/http/src/main/resources/schemas/wsdl/http-conf.xsd Wed Oct 20
01:52:33 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>

Added: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java?rev=1024489&view=auto
==============================================================================
--- cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java
(added)
+++ cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java
Wed Oct 20 01:52:33 2010
@@ -0,0 +1,76 @@
+/**
+ * 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.
+ */
+package org.apache.cxf.transport.http;
+
+import java.util.regex.Pattern;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * A {@code PatternBuilderTest} is ...
+ *
+ * @author Guillaume Sauthier
+ */
+public class PatternBuilderTest extends Assert {
+
+    @Test
+    public void testPatternBuilder() {
+
+        Pattern pattern = null;
+
+        // Simple matching
+        pattern = PatternBuilder.build("localhost");
+
+        assertTrue(pattern.matcher("localhost").matches());
+        assertFalse(pattern.matcher("localhost-after").matches());
+        assertFalse(pattern.matcher("before-localhost").matches());
+
+        // List matching
+        pattern = PatternBuilder.build("localhost|othername");
+
+        assertTrue(pattern.matcher("localhost").matches());
+        assertTrue(pattern.matcher("othername").matches());
+        assertFalse(pattern.matcher("somename").matches());
+
+        // Name with dots matching
+        pattern = PatternBuilder.build("www.apache.org");
+
+        assertTrue(pattern.matcher("www.apache.org").matches());
+        assertFalse(pattern.matcher("www1apache1org").matches());
+
+        // Wildcards matching 1/2
+        pattern = PatternBuilder.build("*.apache.org");
+
+        assertTrue(pattern.matcher("www.apache.org").matches());
+        assertTrue(pattern.matcher("svn.apache.org").matches());
+        assertFalse(pattern.matcher("apache.org").matches());
+        assertTrue(pattern.matcher(".apache.org").matches()); // not very useful ...
+
+        // Wildcards matching 2/2
+        pattern = PatternBuilder.build("www.apache.*");
+
+        assertTrue(pattern.matcher("www.apache.org").matches());
+        assertTrue(pattern.matcher("www.apache.net").matches());
+        assertFalse(pattern.matcher("www.apache").matches());
+        assertTrue(pattern.matcher("www.apache.").matches()); // not very useful ...
+
+    }
+
+}

Propchange: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/transports/http/src/test/java/org/apache/cxf/transport/http/PatternBuilderTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



Mime
View raw message