diff --git a/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java b/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java index 65ce15f68..c8ebc8cde 100644 --- a/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java +++ b/httpclient/src/examples/org/apache/http/examples/client/ClientConfiguration.java @@ -167,7 +167,6 @@ public final static void main(String[] args) throws Exception { .setStaleConnectionCheckEnabled(true) .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)) .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)) - .setDefaultProxy(new HttpHost("myproxy", 8080)) .build(); // Create an HttpClient with the given custom dependencies and configuration. @@ -175,6 +174,7 @@ public final static void main(String[] args) throws Exception { .setConnectionManager(connManager) .setCookieStore(cookieStore) .setCredentialsProvider(credentialsProvider) + .setProxy(new HttpHost("myproxy", 8080)) .setDefaultRequestConfig(defaultRequestConfig) .build(); @@ -186,6 +186,7 @@ public final static void main(String[] args) throws Exception { .setSocketTimeout(5000) .setConnectTimeout(5000) .setConnectionRequestTimeout(5000) + .setProxy(new HttpHost("myotherproxy", 8080)) .build(); httpget.setConfig(requestConfig); diff --git a/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteProxy.java b/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteProxy.java index 108c08818..0c4d6a08b 100644 --- a/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteProxy.java +++ b/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteProxy.java @@ -51,7 +51,7 @@ public static void main(String[] args)throws Exception { HttpHost target = new HttpHost("issues.apache.org", 443, "https"); HttpHost proxy = new HttpHost("127.0.0.1", 8080, "http"); - RequestConfig config = RequestConfig.custom().setDefaultProxy(proxy).build(); + RequestConfig config = RequestConfig.custom().setProxy(proxy).build(); HttpGet request = new HttpGet("/"); request.setConfig(config); diff --git a/httpclient/src/examples/org/apache/http/examples/client/ClientProxyAuthentication.java b/httpclient/src/examples/org/apache/http/examples/client/ClientProxyAuthentication.java index f9d0411f5..b197dc787 100644 --- a/httpclient/src/examples/org/apache/http/examples/client/ClientProxyAuthentication.java +++ b/httpclient/src/examples/org/apache/http/examples/client/ClientProxyAuthentication.java @@ -56,7 +56,9 @@ public static void main(String[] args) throws Exception { HttpHost targetHost = new HttpHost("www.verisign.com", 443, "https"); HttpHost proxy = new HttpHost("localhost", 8080); - RequestConfig config = RequestConfig.custom().setDefaultProxy(proxy).build(); + RequestConfig config = RequestConfig.custom() + .setProxy(proxy) + .build(); HttpGet httpget = new HttpGet("/"); httpget.setConfig(config); diff --git a/httpclient/src/main/java/org/apache/http/client/config/RequestConfig.java b/httpclient/src/main/java/org/apache/http/client/config/RequestConfig.java index 1ba3aac1d..1c458d25b 100644 --- a/httpclient/src/main/java/org/apache/http/client/config/RequestConfig.java +++ b/httpclient/src/main/java/org/apache/http/client/config/RequestConfig.java @@ -37,7 +37,7 @@ public class RequestConfig implements Cloneable { public static final RequestConfig DEFAULT = new Builder().build(); private final boolean expectContinueEnabled; - private final HttpHost defaultProxy; + private final HttpHost proxy; private final InetAddress localAddress; private final boolean staleConnectionCheckEnabled; private final String cookieSpec; @@ -54,7 +54,7 @@ public class RequestConfig implements Cloneable { RequestConfig( final boolean expectContinueEnabled, - final HttpHost defaultProxy, + final HttpHost proxy, final InetAddress localAddress, final boolean staleConnectionCheckEnabled, final String cookieSpec, @@ -70,7 +70,7 @@ public class RequestConfig implements Cloneable { final int socketTimeout) { super(); this.expectContinueEnabled = expectContinueEnabled; - this.defaultProxy = defaultProxy; + this.proxy = proxy; this.localAddress = localAddress; this.staleConnectionCheckEnabled = staleConnectionCheckEnabled; this.cookieSpec = cookieSpec; @@ -90,8 +90,8 @@ public boolean isExpectContinueEnabled() { return expectContinueEnabled; } - public HttpHost getDefaultProxy() { - return defaultProxy; + public HttpHost getProxy() { + return proxy; } public InetAddress getLocalAddress() { @@ -155,7 +155,7 @@ protected RequestConfig clone() throws CloneNotSupportedException { public String toString() { StringBuilder builder = new StringBuilder(); builder.append(", expectContinueEnabled=").append(expectContinueEnabled); - builder.append(", defaultProxy=").append(defaultProxy); + builder.append(", proxy=").append(proxy); builder.append(", localAddress=").append(localAddress); builder.append(", staleConnectionCheckEnabled=").append(staleConnectionCheckEnabled); builder.append(", cookieSpec=").append(cookieSpec); @@ -180,7 +180,7 @@ public static RequestConfig.Builder custom() { public static RequestConfig.Builder copy(final RequestConfig config) { return new Builder() .setExpectContinueEnabled(config.isExpectContinueEnabled()) - .setDefaultProxy(config.getDefaultProxy()) + .setProxy(config.getProxy()) .setLocalAddress(config.getLocalAddress()) .setStaleConnectionCheckEnabled(config.isStaleConnectionCheckEnabled()) .setCookieSpec(config.getCookieSpec()) @@ -199,7 +199,7 @@ public static RequestConfig.Builder copy(final RequestConfig config) { public static class Builder { private boolean expectContinueEnabled; - private HttpHost defaultProxy; + private HttpHost proxy; private InetAddress localAddress; private boolean staleConnectionCheckEnabled; private String cookieSpec; @@ -231,8 +231,8 @@ public Builder setExpectContinueEnabled(boolean expectContinueEnabled) { return this; } - public Builder setDefaultProxy(final HttpHost defaultProxy) { - this.defaultProxy = defaultProxy; + public Builder setProxy(final HttpHost proxy) { + this.proxy = proxy; return this; } @@ -304,7 +304,7 @@ public Builder setSocketTimeout(final int socketTimeout) { public RequestConfig build() { return new RequestConfig( expectContinueEnabled, - defaultProxy, + proxy, localAddress, staleConnectionCheckEnabled, cookieSpec, diff --git a/httpclient/src/main/java/org/apache/http/client/params/HttpClientParamConfig.java b/httpclient/src/main/java/org/apache/http/client/params/HttpClientParamConfig.java index 9ea5cdd31..2a3fcf1ea 100644 --- a/httpclient/src/main/java/org/apache/http/client/params/HttpClientParamConfig.java +++ b/httpclient/src/main/java/org/apache/http/client/params/HttpClientParamConfig.java @@ -55,7 +55,7 @@ public static RequestConfig getRequestConfig(final HttpParams params) { .setConnectionRequestTimeout((int) HttpClientParams.getConnectionManagerTimeout(params)) .setConnectTimeout(HttpConnectionParams.getConnectionTimeout(params)) .setCookieSpec(HttpClientParams.getCookiePolicy(params)) - .setDefaultProxy(ConnRouteParams.getDefaultProxy(params)) + .setProxy(ConnRouteParams.getDefaultProxy(params)) .setExpectContinueEnabled(HttpProtocolParams.useExpectContinue(params)) .setLocalAddress(ConnRouteParams.getLocalAddress(params)) .setMaxRedirects(params.getIntParameter(ClientPNames.MAX_REDIRECTS, 50)) diff --git a/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java b/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java index 9bcf24254..b334fa330 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java @@ -38,6 +38,7 @@ import org.apache.http.ConnectionReuseStrategy; import org.apache.http.Header; +import org.apache.http.HttpHost; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponseInterceptor; import org.apache.http.annotation.NotThreadSafe; @@ -90,6 +91,7 @@ import org.apache.http.impl.client.execchain.RedirectExec; import org.apache.http.impl.client.execchain.RetryExec; import org.apache.http.impl.client.execchain.ServiceUnavailableRetryExec; +import org.apache.http.impl.conn.DefaultProxyRoutePlanner; import org.apache.http.impl.conn.DefaultRoutePlanner; import org.apache.http.impl.conn.DefaultSchemePortResolver; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; @@ -168,6 +170,7 @@ public class HttpClientBuilder { private CookieStore cookieStore; private CredentialsProvider credentialsProvider; private String userAgent; + private HttpHost proxy; private Collection defaultHeaders; private SocketConfig defaultSocketConfig; private ConnectionConfig defaultConnectionConfig; @@ -383,6 +386,11 @@ public final HttpClientBuilder setUserAgent(final String userAgent) { return this; } + public final HttpClientBuilder setProxy(final HttpHost proxy) { + this.proxy = proxy; + return this; + } + public final HttpClientBuilder setDefaultHeaders(final Collection defaultHeaders) { this.defaultHeaders = defaultHeaders; return this; @@ -617,7 +625,9 @@ public CloseableHttpClient build() { // Add redirect executor, if not disabled HttpRoutePlanner routePlanner = this.routePlanner; if (routePlanner == null) { - if (systemProperties) { + if (proxy != null) { + routePlanner = new DefaultProxyRoutePlanner(proxy, schemePortResolver); + } else if (systemProperties) { routePlanner = new SystemDefaultRoutePlanner( schemePortResolver, ProxySelector.getDefault()); } else { diff --git a/httpclient/src/main/java/org/apache/http/impl/client/MinimalHttpClient.java b/httpclient/src/main/java/org/apache/http/impl/client/MinimalHttpClient.java index 577eea81a..865b4cd2f 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/MinimalHttpClient.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/MinimalHttpClient.java @@ -107,7 +107,7 @@ protected CloseableHttpResponse doExecute( if (config == null) { config = RequestConfig.DEFAULT; } - if (config.getDefaultProxy() != null) { + if (config.getProxy() != null) { throw new ClientProtocolException("Minimal HttpClient does not support" + " request execution via proxy"); } diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/DefaultProxyRoutePlanner.java b/httpclient/src/main/java/org/apache/http/impl/conn/DefaultProxyRoutePlanner.java new file mode 100644 index 000000000..7fa362c19 --- /dev/null +++ b/httpclient/src/main/java/org/apache/http/impl/conn/DefaultProxyRoutePlanner.java @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * 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.impl.conn; + +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.annotation.Immutable; +import org.apache.http.conn.SchemePortResolver; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.Args; + +/** + * Implementation of an {@link HttpRoutePlanner} that routes requests through + * a default proxy. + * + * @since 4.3 + */ +@Immutable +public class DefaultProxyRoutePlanner extends DefaultRoutePlanner { + + private final HttpHost proxy; + + public DefaultProxyRoutePlanner(final HttpHost proxy, final SchemePortResolver schemePortResolver) { + super(schemePortResolver); + this.proxy = Args.notNull(proxy, "Proxy host"); + } + + @Override + protected HttpHost determineProxy( + final HttpHost target, + final HttpRequest request, + final HttpContext context) throws HttpException { + return proxy; + } + +} diff --git a/httpclient/src/main/java/org/apache/http/impl/conn/DefaultRoutePlanner.java b/httpclient/src/main/java/org/apache/http/impl/conn/DefaultRoutePlanner.java index b5ca6b2fc..8b3ec0b13 100644 --- a/httpclient/src/main/java/org/apache/http/impl/conn/DefaultRoutePlanner.java +++ b/httpclient/src/main/java/org/apache/http/impl/conn/DefaultRoutePlanner.java @@ -36,22 +36,18 @@ import org.apache.http.client.config.RequestConfig; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.SchemePortResolver; -import org.apache.http.conn.params.ConnRouteParams; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.protocol.HttpContext; import org.apache.http.util.Args; /** - * Default implementation of an {@link HttpRoutePlanner}. This implementation - * is based on {@link org.apache.http.conn.params.ConnRoutePNames parameters}. - * It will not make use of any Java system properties, nor of system or - * browser proxy settings. + * Default implementation of an {@link HttpRoutePlanner}. It will not make use of + * any Java system properties, nor of system or browser proxy settings. * * @since 4.3 */ @Immutable -@SuppressWarnings("deprecation") public class DefaultRoutePlanner implements HttpRoutePlanner { private final SchemePortResolver schemePortResolver; @@ -68,19 +64,12 @@ public HttpRoute determineRoute( final HttpContext context) throws HttpException { Args.notNull(host, "Target host"); Args.notNull(request, "Request"); - - // If we have a forced route, we can do without a target. - HttpRoute route = ConnRouteParams.getForcedRoute(request.getParams()); - if (route != null) { - return route; - } - HttpClientContext clientContext = HttpClientContext.adapt(context); RequestConfig config = clientContext.getRequestConfig(); InetAddress local = config.getLocalAddress(); - HttpHost proxy = determineProxy(host, request, context); + HttpHost proxy = config.getProxy(); if (proxy == null) { - proxy = config.getDefaultProxy(); + proxy = determineProxy(host, request, context); } HttpHost target; diff --git a/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultProxyRoutePlanner.java b/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultProxyRoutePlanner.java new file mode 100644 index 000000000..5cc2ecb64 --- /dev/null +++ b/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultProxyRoutePlanner.java @@ -0,0 +1,92 @@ +/* + * ==================================================================== + * 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.impl.conn; + +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpVersion; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.conn.SchemePortResolver; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.message.BasicHttpRequest; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +/** + * Tests for {@link DefaultProxyRoutePlanner}. + */ +public class TestDefaultProxyRoutePlanner { + + private HttpHost defaultProxy; + private SchemePortResolver schemePortResolver; + private DefaultProxyRoutePlanner routePlanner; + + @Before + public void setup() { + defaultProxy = new HttpHost("default.proxy.host", 8888); + schemePortResolver = Mockito.mock(SchemePortResolver.class); + routePlanner = new DefaultProxyRoutePlanner(defaultProxy, + schemePortResolver); + } + + @Test + public void testDefaultProxyDirect() throws Exception { + HttpHost target = new HttpHost("somehost", 80, "http"); + HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); + + HttpContext context = new BasicHttpContext(); + HttpRoute route = routePlanner.determineRoute(target, request, context); + + Assert.assertEquals(target, route.getTargetHost()); + Assert.assertEquals(defaultProxy, route.getProxyHost()); + Assert.assertEquals(2, route.getHopCount()); + Assert.assertFalse(route.isSecure()); + } + + @Test + public void testViaProxy() throws Exception { + HttpHost target = new HttpHost("somehost", 80, "http"); + HttpHost proxy = new HttpHost("custom.proxy.host", 8080); + HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); + + HttpClientContext context = HttpClientContext.create(); + context.setRequestConfig(RequestConfig.custom().setProxy(proxy).build()); + HttpRoute route = routePlanner.determineRoute(target, request, context); + + Assert.assertEquals(target, route.getTargetHost()); + Assert.assertEquals(proxy, route.getProxyHost()); + Assert.assertEquals(2, route.getHopCount()); + Assert.assertFalse(route.isSecure()); + } + +} diff --git a/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultRoutePlanner.java b/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultRoutePlanner.java index 1dc28213d..cfe97cbb5 100644 --- a/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultRoutePlanner.java +++ b/httpclient/src/test/java/org/apache/http/impl/conn/TestDefaultRoutePlanner.java @@ -30,6 +30,8 @@ import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpVersion; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.SchemePortResolver; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.message.BasicHttpRequest; @@ -82,4 +84,21 @@ public void testDirectDefaultPort() throws Exception { Assert.assertTrue(route.isSecure()); } + @Test + public void testViaProxy() throws Exception { + HttpHost target = new HttpHost("somehost", 80, "http"); + HttpHost proxy = new HttpHost("proxy", 8080); + HttpRequest request = new BasicHttpRequest("GET", "/", HttpVersion.HTTP_1_1); + + HttpClientContext context = HttpClientContext.create(); + context.setRequestConfig(RequestConfig.custom().setProxy(proxy).build()); + HttpRoute route = routePlanner.determineRoute(target, request, context); + + Assert.assertEquals(target, route.getTargetHost()); + Assert.assertEquals(proxy, route.getProxyHost()); + Assert.assertEquals(2, route.getHopCount()); + Assert.assertFalse(route.isSecure()); + Mockito.verify(schemePortResolver, Mockito.never()).resolve(Mockito.any()); + } + }