From 296dbc18a58bf84770f4bdb3e7788b917bc190f4 Mon Sep 17 00:00:00 2001 From: John Viegas Date: Wed, 21 Feb 2024 17:43:35 -0800 Subject: [PATCH 1/9] Http Client made consistent with Default Proxy Configurations --- .../bugfix-AWSSDKforJavav2-c277e61.json | 6 + .../ApacheClientProxyConfigurationTest.java | 65 ++++ .../crt/internal/AwsCrtClientBuilderBase.java | 2 +- .../AsyncCrtClientProxyConfigurationTest.java | 50 +++ .../SyncCrtClientProxyConfigurationTest.java | 51 +++ .../nio/netty/NettyNioAsyncHttpClient.java | 2 +- .../internal/AwaitCloseChannelPoolMap.java | 4 +- .../NettyClientProxyConfigurationTest.java | 48 +++ .../HttpClientDefaultPoxyConfigTest.java | 292 ++++++++++++++++++ 9 files changed, 516 insertions(+), 4 deletions(-) create mode 100644 .changes/next-release/bugfix-AWSSDKforJavav2-c277e61.json create mode 100644 http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java create mode 100644 http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java create mode 100644 http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java create mode 100644 http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java create mode 100644 test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-c277e61.json b/.changes/next-release/bugfix-AWSSDKforJavav2-c277e61.json new file mode 100644 index 000000000000..003fe1e06c0c --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-c277e61.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "AWS SDK for Java v2", + "contributor": "", + "description": "Addressing Issue [#4745](https://github.com/aws/aws-sdk-java-v2/issues/4745) , Netty and CRT clients' default proxy settings have been made consistent with the Apache client, now using environment and system property settings by default.\n To disable the use of environment variables and system properties by default, set useSystemPropertyValue(false) and useEnvironmentVariablesValues(false) in ProxyConfigurations." +} diff --git a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java new file mode 100644 index 000000000000..dae29ec0fe89 --- /dev/null +++ b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java @@ -0,0 +1,65 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.http.apache; + +import java.util.concurrent.ThreadLocalRandom; +import org.apache.http.conn.HttpHostConnectException; +import software.amazon.awssdk.http.SdkHttpClient; +import software.amazon.awssdk.http.async.SdkAsyncHttpClient; +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; +import java.net.ConnectException; + +public class ApacheClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { + + @Override + protected Class getProxyFailedExceptionType() { + return HttpHostConnectException.class; + + } + + @Override + protected Class getProxyFailedCauseExceptionType() { + return ConnectException.class; + } + + @Override + protected boolean isSyncClient() { + return true; + } + + @Override + protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { + throw new IllegalArgumentException("Async client is not supported"); + } + + @Override + protected SdkHttpClient createSyncHttpClientWithDefaultProxy() { + return ApacheHttpClient.builder().build(); + } + + /** + * Wrire code which inputs an integer args and returns one number between 0 to 65535 excluding number args + */ + private int getRandomPort(int currentPort) { + int randomPort; + do { + randomPort = ThreadLocalRandom.current().nextInt(65535); + } while (randomPort == currentPort); + return randomPort; + } + + +} \ No newline at end of file diff --git a/http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/internal/AwsCrtClientBuilderBase.java b/http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/internal/AwsCrtClientBuilderBase.java index 5fb70b7e2512..dbb1e84f3c8e 100644 --- a/http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/internal/AwsCrtClientBuilderBase.java +++ b/http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/internal/AwsCrtClientBuilderBase.java @@ -29,7 +29,7 @@ public class AwsCrtClientBuilderBase { private final AttributeMap.Builder standardOptions = AttributeMap.builder(); private Long readBufferSize; - private ProxyConfiguration proxyConfiguration; + private ProxyConfiguration proxyConfiguration = ProxyConfiguration.builder().build(); private ConnectionHealthConfiguration connectionHealthConfiguration; private TcpKeepAliveConfiguration tcpKeepAliveConfiguration; private Boolean postQuantumTlsEnabled; diff --git a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java new file mode 100644 index 000000000000..1da644f7a0c4 --- /dev/null +++ b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java @@ -0,0 +1,50 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.http.crt; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import software.amazon.awssdk.http.SdkHttpClient; +import software.amazon.awssdk.http.async.SdkAsyncHttpClient; +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; + +public class AsyncCrtClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { + + @Override + protected Class getProxyFailedExceptionType() { + return ExecutionException.class; + } + + @Override + protected Class getProxyFailedCauseExceptionType() { + return IOException.class; + } + + @Override + protected boolean isSyncClient() { + return false; + } + + @Override + protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { + return AwsCrtAsyncHttpClient.builder().build(); + } + + @Override + protected SdkHttpClient createSyncHttpClientWithDefaultProxy() { + throw new IllegalArgumentException("Sync client is not supported"); + } +} diff --git a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java new file mode 100644 index 000000000000..8ec532716b19 --- /dev/null +++ b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java @@ -0,0 +1,51 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.http.crt; + + +import java.io.IOException; +import software.amazon.awssdk.crt.http.HttpException; +import software.amazon.awssdk.http.SdkHttpClient; +import software.amazon.awssdk.http.async.SdkAsyncHttpClient; +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; + +public class SyncCrtClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { + + @Override + protected Class getProxyFailedExceptionType() { + return IOException.class; + } + + @Override + protected Class getProxyFailedCauseExceptionType() { + return HttpException.class; + } + + @Override + protected boolean isSyncClient() { + return true; + } + + @Override + protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { + throw new UnsupportedOperationException("Async client does not support proxy"); + } + + @Override + protected SdkHttpClient createSyncHttpClientWithDefaultProxy() { + return AwsCrtHttpClient.create(); + } +} diff --git a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java index c12aeab10180..70f62e1f6e77 100644 --- a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java +++ b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.java @@ -501,7 +501,7 @@ private static final class DefaultBuilder implements Builder { private Integer maxHttp2Streams; private Http2Configuration http2Configuration; private SslProvider sslProvider; - private ProxyConfiguration proxyConfiguration; + private ProxyConfiguration proxyConfiguration = ProxyConfiguration.builder().build(); private Boolean useNonBlockingDnsResolver; private DefaultBuilder() { diff --git a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/AwaitCloseChannelPoolMap.java b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/AwaitCloseChannelPoolMap.java index ca310593f040..648908a567c3 100644 --- a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/AwaitCloseChannelPoolMap.java +++ b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/AwaitCloseChannelPoolMap.java @@ -186,13 +186,13 @@ private Bootstrap createBootstrap(URI poolKey) { private boolean shouldUseProxyForHost(URI remoteAddr) { - if (proxyConfiguration == null) { + if (proxyConfiguration == null || proxyConfiguration.host() == null) { return false; } return shouldProxyForHostCache.computeIfAbsent(remoteAddr, (uri) -> - proxyConfiguration.nonProxyHosts().stream().noneMatch(h -> uri.getHost().matches(h)) + proxyConfiguration.nonProxyHosts().stream().noneMatch(h -> uri.getHost().matches(h)) ); } diff --git a/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java b/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java new file mode 100644 index 000000000000..6d0927b5969c --- /dev/null +++ b/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java @@ -0,0 +1,48 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + +import java.net.ConnectException; +import java.util.concurrent.ExecutionException; +import software.amazon.awssdk.http.SdkHttpClient; +import software.amazon.awssdk.http.async.SdkAsyncHttpClient; +import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient; +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; + +public class NettyClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { + @Override + protected boolean isSyncClient() { + return false; + } + + @Override + protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { + return NettyNioAsyncHttpClient.create(); + } + + @Override + protected SdkHttpClient createSyncHttpClientWithDefaultProxy() { + throw new IllegalArgumentException("Sync client not supported"); + } + + @Override + protected Class getProxyFailedExceptionType() { + return ExecutionException.class; + } + + @Override + protected Class getProxyFailedCauseExceptionType() { + return ConnectException.class; + } +} diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java new file mode 100644 index 000000000000..14cd9e57732c --- /dev/null +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java @@ -0,0 +1,292 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.http.proxy; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static java.util.Collections.emptyMap; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; +import software.amazon.awssdk.http.EmptyPublisher; +import software.amazon.awssdk.http.ExecutableHttpRequest; +import software.amazon.awssdk.http.HttpExecuteRequest; +import software.amazon.awssdk.http.HttpExecuteResponse; +import software.amazon.awssdk.http.SdkHttpClient; +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.http.SdkHttpMethod; +import software.amazon.awssdk.http.SdkHttpRequest; +import software.amazon.awssdk.http.SdkHttpResponse; +import software.amazon.awssdk.http.async.AsyncExecuteRequest; +import software.amazon.awssdk.http.async.SdkAsyncHttpClient; +import software.amazon.awssdk.http.async.SdkAsyncHttpResponseHandler; +import software.amazon.awssdk.testutils.EnvironmentVariableHelper; +import software.amazon.awssdk.utils.Pair; + +public abstract class HttpClientDefaultPoxyConfigTest { + + private static final EnvironmentVariableHelper ENVIRONMENT_VARIABLE_HELPER = new EnvironmentVariableHelper(); + + protected WireMockServer mockProxy = new WireMockServer(new WireMockConfiguration() + .dynamicPort() + .dynamicHttpsPort() + .enableBrowserProxying(true)); + + protected WireMockServer mockServer = new WireMockServer(new WireMockConfiguration() + .dynamicPort() + .dynamicHttpsPort()); + + protected abstract boolean isSyncClient(); + + protected abstract SdkAsyncHttpClient createHttpClientWithDefaultProxy(); + + protected abstract SdkHttpClient createSyncHttpClientWithDefaultProxy(); + + protected abstract Class getProxyFailedExceptionType(); + + protected abstract Class getProxyFailedCauseExceptionType(); + + + @BeforeEach + public void setup() { + mockProxy.start(); + mockServer.start(); + mockServer.stubFor(get(WireMock.urlMatching(".*")) + .willReturn(aResponse().withStatus(200).withBody("hello"))); + } + + @AfterEach + public void teardown() { + mockServer.stop(); + mockProxy.stop(); + ENVIRONMENT_VARIABLE_HELPER.reset(); + System.clearProperty("http.proxyHost"); + System.clearProperty("http.proxyPort"); + } + + public static Stream proxyConfigurationSettingWithConnectionFails() { + return Stream.of( + Arguments.of( + Arrays.asList( + Pair.of("http.proxyHost", "localhost"), + Pair.of("http.proxyPort", "%s")), + Arrays.asList( + Pair.of("http_proxy", + "http://" + "localhost" + ":" + "%s" + "/")), + "Provided system and environment variable when configured uses proxy config"), + + Arguments.of(Collections.singletonList( + Pair.of("http.none", "localhost")), + Arrays.asList( + Pair.of("http_proxy", + "http://" + "localhost" + ":" + "%s" + "/")), + "Provided environment and No system variables uses proxy config"), + Arguments.of( + Arrays.asList( + Pair.of("http.proxyHost", "localhost"), + Pair.of("http.proxyPort", "%s")), + Arrays.asList(Pair.of("none", "none")), + "Provided system and No environment variables uses proxy config") + ); + } + + @ParameterizedTest(name = "{index} - {2}.") + @MethodSource("proxyConfigurationSettingWithConnectionFails") + public void ensureProxyErrorsWhenIncorrectPortUsed(List> systemSettingsPair, + List> envSystemSetting, + String testCaseName) throws Throwable { + systemSettingsPair.forEach(settingsPair -> System.setProperty(settingsPair.left(), + + String.format(settingsPair.right(), + getRandomPort(mockProxy.port())))); + + envSystemSetting.forEach(settingsPair -> ENVIRONMENT_VARIABLE_HELPER.set( + settingsPair.left(), + String.format(settingsPair.right(), getRandomPort(mockProxy.port())))); + if (isSyncClient()) { + defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), + getProxyFailedExceptionType(), + getProxyFailedCauseExceptionType()); + } else { + defaultProxyConfigurationForAsyncHttp(createHttpClientWithDefaultProxy(), + getProxyFailedExceptionType(), + getProxyFailedCauseExceptionType()); + } + } + + @Test + public void ensureProxySucceedsWhenIncorrectPortUsed() throws Throwable { + if (isSyncClient()) { + defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), + null, + null); + } else { + defaultProxyConfigurationForAsyncHttp(createHttpClientWithDefaultProxy(), + null, + null); + } + } + + public void defaultProxyConfigurationForAsyncHttp(SdkAsyncHttpClient client, + Class proxyFailedExceptionType, + Class proxyFailedCauseExceptionType) throws Throwable { + CompletableFuture streamReceived = new CompletableFuture<>(); + AtomicReference response = new AtomicReference<>(null); + AtomicReference error = new AtomicReference<>(null); + Subscriber subscriber = createDummySubscriber(); + SdkAsyncHttpResponseHandler handler = createTestResponseHandler(response, streamReceived, error, subscriber); + URI uri = URI.create("http://localhost:" + mockServer.port()); + SdkHttpRequest request = createRequest(uri, "/server/test", null, SdkHttpMethod.GET, emptyMap()); + CompletableFuture future = client.execute(AsyncExecuteRequest.builder() + .request(request) + .responseHandler(handler) + .requestContentPublisher(new EmptyPublisher()) + .build()); + + if (proxyFailedExceptionType != null && proxyFailedCauseExceptionType != null) { + assertThatExceptionOfType(proxyFailedExceptionType).isThrownBy(() -> future.get(60, TimeUnit.SECONDS)) + .withCauseInstanceOf(proxyFailedCauseExceptionType); + } else { + future.get(60, TimeUnit.SECONDS); + assertThat(error.get()).isNull(); + assertThat(streamReceived.get(60, TimeUnit.SECONDS)).isTrue(); + assertThat(response.get().statusCode()).isEqualTo(200); + } + + + } + + + public void defaultProxyConfigurationSyncHttp(SdkHttpClient client, Class exceptionType, + Class proxyFailedCauseExceptionType) throws Throwable { + CompletableFuture streamReceived = new CompletableFuture<>(); + AtomicReference response = new AtomicReference<>(null); + AtomicReference error = new AtomicReference<>(null); + Subscriber subscriber = createDummySubscriber(); + SdkAsyncHttpResponseHandler handler = createTestResponseHandler(response, streamReceived, error, subscriber); + URI uri = URI.create("http://localhost:" + mockServer.port()); + SdkHttpRequest request = createRequest(uri, "/server/test", null, SdkHttpMethod.GET, emptyMap()); + ExecutableHttpRequest executableHttpRequest = client.prepareRequest(HttpExecuteRequest.builder() + .request(request) + .build()); + + if (exceptionType != null && proxyFailedCauseExceptionType != null) { + assertThatExceptionOfType(exceptionType).isThrownBy(() -> executableHttpRequest.call()) + .withCauseInstanceOf(proxyFailedCauseExceptionType); + } else { + HttpExecuteResponse executeResponse = executableHttpRequest.call(); + assertThat(error.get()).isNull(); + assertThat(executeResponse.httpResponse().statusCode()).isEqualTo(200); + } + + + } + + static Subscriber createDummySubscriber() { + return new Subscriber() { + @Override + public void onSubscribe(Subscription subscription) { + subscription.request(Long.MAX_VALUE); + } + + @Override + public void onNext(ByteBuffer byteBuffer) { + } + + @Override + public void onError(Throwable throwable) { + } + + @Override + public void onComplete() { + } + }; + } + + static SdkAsyncHttpResponseHandler createTestResponseHandler(AtomicReference response, + CompletableFuture streamReceived, + AtomicReference error, + Subscriber subscriber) { + return new SdkAsyncHttpResponseHandler() { + @Override + public void onHeaders(SdkHttpResponse headers) { + response.compareAndSet(null, headers); + } + + @Override + public void onStream(Publisher stream) { + stream.subscribe(subscriber); + streamReceived.complete(true); + } + + @Override + public void onError(Throwable t) { + error.compareAndSet(null, t); + } + }; + } + + static SdkHttpFullRequest createRequest(URI endpoint, + String resourcePath, + byte[] body, + SdkHttpMethod method, + Map params) { + String contentLength = (body == null) ? null : String.valueOf(body.length); + return SdkHttpFullRequest.builder() + .uri(endpoint) + .method(method) + .encodedPath(resourcePath) + .applyMutation(b -> params.forEach(b::putRawQueryParameter)) + .applyMutation(b -> { + b.putHeader("Host", endpoint.getHost()); + if (contentLength != null) { + b.putHeader("Content-Length", contentLength); + } + }).build(); + } + + private int getRandomPort(int currentPort) { + int randomPort; + do { + randomPort = ThreadLocalRandom.current().nextInt(65535); + } while (randomPort == currentPort); + return randomPort; + } + +} From 4d2e4729b3760398e29d85d91de70d5eacfe397d Mon Sep 17 00:00:00 2001 From: John Viegas Date: Thu, 22 Feb 2024 09:28:37 -0800 Subject: [PATCH 2/9] made changes for URL client --- .../UrlConnectionHttpClient.java | 2 +- .../UrlClientProxyConfigurationTest.java | 48 +++++++++++++++++++ .../HttpClientDefaultPoxyConfigTest.java | 16 +++++-- 3 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java diff --git a/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.java b/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.java index 8268cd3bfb60..44f2724836fc 100644 --- a/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.java +++ b/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.java @@ -503,7 +503,7 @@ public interface Builder extends SdkHttpClient.Builder getProxyFailedExceptionType() { + return IOException.class; + } + + @Override + protected Class getProxyFailedCauseExceptionType() { + return null; + } +} diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java index 14cd9e57732c..9621ad5a2bda 100644 --- a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; @@ -61,6 +62,8 @@ public abstract class HttpClientDefaultPoxyConfigTest { + static Random random = new Random(); + private static final EnvironmentVariableHelper ENVIRONMENT_VARIABLE_HELPER = new EnvironmentVariableHelper(); protected WireMockServer mockProxy = new WireMockServer(new WireMockConfiguration() @@ -206,9 +209,14 @@ public void defaultProxyConfigurationSyncHttp(SdkHttpClient client, Class executableHttpRequest.call()) - .withCauseInstanceOf(proxyFailedCauseExceptionType); + if (exceptionType != null) { + if (proxyFailedCauseExceptionType != null) { + assertThatExceptionOfType(exceptionType).isThrownBy(() -> executableHttpRequest.call()) + .withCauseInstanceOf(proxyFailedCauseExceptionType); + } else { + + assertThatExceptionOfType(exceptionType).isThrownBy(() -> executableHttpRequest.call()); + } } else { HttpExecuteResponse executeResponse = executableHttpRequest.call(); assertThat(error.get()).isNull(); @@ -284,7 +292,7 @@ static SdkHttpFullRequest createRequest(URI endpoint, private int getRandomPort(int currentPort) { int randomPort; do { - randomPort = ThreadLocalRandom.current().nextInt(65535); + randomPort = random.nextInt(65535); } while (randomPort == currentPort); return randomPort; } From 23e9db4d6165016c094dfda1f2ef77429e747890 Mon Sep 17 00:00:00 2001 From: John Viegas Date: Thu, 22 Feb 2024 14:26:37 -0800 Subject: [PATCH 3/9] Updated test case Name --- .../ApacheClientProxyConfigurationTest.java | 16 ++-------- .../AsyncCrtClientProxyConfigurationTest.java | 5 ++-- .../SyncCrtClientProxyConfigurationTest.java | 5 ++-- .../NettyClientProxyConfigurationTest.java | 4 +-- .../UrlClientProxyConfigurationTest.java | 4 +-- ...HttpClientDefaultPoxyConfigTestSuite.java} | 29 ++++--------------- 6 files changed, 15 insertions(+), 48 deletions(-) rename test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/{HttpClientDefaultPoxyConfigTest.java => HttpClientDefaultPoxyConfigTestSuite.java} (96%) diff --git a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java index dae29ec0fe89..29c870b0de94 100644 --- a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java +++ b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java @@ -19,10 +19,10 @@ import org.apache.http.conn.HttpHostConnectException; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; import java.net.ConnectException; -public class ApacheClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { +public class ApacheClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { @Override protected Class getProxyFailedExceptionType() { @@ -50,16 +50,4 @@ protected SdkHttpClient createSyncHttpClientWithDefaultProxy() { return ApacheHttpClient.builder().build(); } - /** - * Wrire code which inputs an integer args and returns one number between 0 to 65535 excluding number args - */ - private int getRandomPort(int currentPort) { - int randomPort; - do { - randomPort = ThreadLocalRandom.current().nextInt(65535); - } while (randomPort == currentPort); - return randomPort; - } - - } \ No newline at end of file diff --git a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java index 1da644f7a0c4..bbeb03b62610 100644 --- a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java +++ b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java @@ -19,10 +19,9 @@ import java.util.concurrent.ExecutionException; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; - -public class AsyncCrtClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; +public class AsyncCrtClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { @Override protected Class getProxyFailedExceptionType() { return ExecutionException.class; diff --git a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java index 8ec532716b19..95e4b8b68864 100644 --- a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java +++ b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java @@ -15,14 +15,13 @@ package software.amazon.awssdk.http.crt; - import java.io.IOException; import software.amazon.awssdk.crt.http.HttpException; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; -public class SyncCrtClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { +public class SyncCrtClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { @Override protected Class getProxyFailedExceptionType() { diff --git a/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java b/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java index 6d0927b5969c..2d4c51621909 100644 --- a/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java +++ b/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java @@ -18,9 +18,9 @@ import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; -public class NettyClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { +public class NettyClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { @Override protected boolean isSyncClient() { return false; diff --git a/http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java b/http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java index 1c34cbb2992a..827bcd310325 100644 --- a/http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java +++ b/http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java @@ -18,9 +18,9 @@ import java.io.IOException; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTest; +import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; -public class UrlClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTest { +public class UrlClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { @Override protected boolean isSyncClient() { return true; diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTestSuite.java similarity index 96% rename from test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java rename to test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTestSuite.java index 9621ad5a2bda..722ce3720417 100644 --- a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTest.java +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTestSuite.java @@ -26,13 +26,12 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import java.net.URI; import java.nio.ByteBuffer; +import java.security.SecureRandom; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Stream; @@ -60,17 +59,13 @@ import software.amazon.awssdk.testutils.EnvironmentVariableHelper; import software.amazon.awssdk.utils.Pair; -public abstract class HttpClientDefaultPoxyConfigTest { - - static Random random = new Random(); - +public abstract class HttpClientDefaultPoxyConfigTestSuite { + SecureRandom random = new SecureRandom(); private static final EnvironmentVariableHelper ENVIRONMENT_VARIABLE_HELPER = new EnvironmentVariableHelper(); - protected WireMockServer mockProxy = new WireMockServer(new WireMockConfiguration() .dynamicPort() .dynamicHttpsPort() .enableBrowserProxying(true)); - protected WireMockServer mockServer = new WireMockServer(new WireMockConfiguration() .dynamicPort() .dynamicHttpsPort()); @@ -85,7 +80,6 @@ public abstract class HttpClientDefaultPoxyConfigTest { protected abstract Class getProxyFailedCauseExceptionType(); - @BeforeEach public void setup() { mockProxy.start(); @@ -113,7 +107,6 @@ public static Stream proxyConfigurationSettingWithConnectionFails() { Pair.of("http_proxy", "http://" + "localhost" + ":" + "%s" + "/")), "Provided system and environment variable when configured uses proxy config"), - Arguments.of(Collections.singletonList( Pair.of("http.none", "localhost")), Arrays.asList( @@ -135,7 +128,6 @@ public void ensureProxyErrorsWhenIncorrectPortUsed(List> sy List> envSystemSetting, String testCaseName) throws Throwable { systemSettingsPair.forEach(settingsPair -> System.setProperty(settingsPair.left(), - String.format(settingsPair.right(), getRandomPort(mockProxy.port())))); @@ -156,13 +148,9 @@ public void ensureProxyErrorsWhenIncorrectPortUsed(List> sy @Test public void ensureProxySucceedsWhenIncorrectPortUsed() throws Throwable { if (isSyncClient()) { - defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), - null, - null); + defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), null, null); } else { - defaultProxyConfigurationForAsyncHttp(createHttpClientWithDefaultProxy(), - null, - null); + defaultProxyConfigurationForAsyncHttp(createHttpClientWithDefaultProxy(), null, null); } } @@ -181,7 +169,6 @@ public void defaultProxyConfigurationForAsyncHttp(SdkAsyncHttpClient client, .responseHandler(handler) .requestContentPublisher(new EmptyPublisher()) .build()); - if (proxyFailedExceptionType != null && proxyFailedCauseExceptionType != null) { assertThatExceptionOfType(proxyFailedExceptionType).isThrownBy(() -> future.get(60, TimeUnit.SECONDS)) .withCauseInstanceOf(proxyFailedCauseExceptionType); @@ -191,8 +178,6 @@ public void defaultProxyConfigurationForAsyncHttp(SdkAsyncHttpClient client, assertThat(streamReceived.get(60, TimeUnit.SECONDS)).isTrue(); assertThat(response.get().statusCode()).isEqualTo(200); } - - } @@ -214,7 +199,6 @@ public void defaultProxyConfigurationSyncHttp(SdkHttpClient client, Class executableHttpRequest.call()) .withCauseInstanceOf(proxyFailedCauseExceptionType); } else { - assertThatExceptionOfType(exceptionType).isThrownBy(() -> executableHttpRequest.call()); } } else { @@ -222,8 +206,6 @@ public void defaultProxyConfigurationSyncHttp(SdkHttpClient client, Class createDummySubscriber() { @@ -296,5 +278,4 @@ private int getRandomPort(int currentPort) { } while (randomPort == currentPort); return randomPort; } - } From cdf17503ded99b2a88cb62eb1e3d0e25cc267878 Mon Sep 17 00:00:00 2001 From: John Viegas Date: Fri, 23 Feb 2024 14:12:10 -0800 Subject: [PATCH 4/9] Updated comments related to test cases --- .../ApacheClientProxyConfigurationTest.java | 9 +- .../AsyncCrtClientProxyConfigurationTest.java | 8 +- .../SyncCrtClientProxyConfigurationTest.java | 6 +- .../internal/AwaitCloseChannelPoolMap.java | 2 +- .../NettyClientProxyConfigurationTest.java | 6 +- .../UrlClientProxyConfigurationTest.java | 6 +- ...ttpClientDefaultProxyConfigTestSuite.java} | 113 ++++++++++++------ 7 files changed, 94 insertions(+), 56 deletions(-) rename test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/{HttpClientDefaultPoxyConfigTestSuite.java => HttpClientDefaultProxyConfigTestSuite.java} (72%) diff --git a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java index 29c870b0de94..4b9ff8549912 100644 --- a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java +++ b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheClientProxyConfigurationTest.java @@ -15,14 +15,13 @@ package software.amazon.awssdk.http.apache; -import java.util.concurrent.ThreadLocalRandom; import org.apache.http.conn.HttpHostConnectException; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; +import software.amazon.awssdk.http.proxy.HttpClientDefaultProxyConfigTestSuite; import java.net.ConnectException; -public class ApacheClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { +public class ApacheClientProxyConfigurationTest extends HttpClientDefaultProxyConfigTestSuite { @Override protected Class getProxyFailedExceptionType() { @@ -42,12 +41,12 @@ protected boolean isSyncClient() { @Override protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { - throw new IllegalArgumentException("Async client is not supported"); + throw new IllegalArgumentException("Async client is not supported for this test."); } @Override protected SdkHttpClient createSyncHttpClientWithDefaultProxy() { - return ApacheHttpClient.builder().build(); + return ApacheHttpClient.create(); } } \ No newline at end of file diff --git a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java index bbeb03b62610..224ad778a95c 100644 --- a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java +++ b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/AsyncCrtClientProxyConfigurationTest.java @@ -19,9 +19,9 @@ import java.util.concurrent.ExecutionException; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; +import software.amazon.awssdk.http.proxy.HttpClientDefaultProxyConfigTestSuite; -public class AsyncCrtClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { +public class AsyncCrtClientProxyConfigurationTest extends HttpClientDefaultProxyConfigTestSuite { @Override protected Class getProxyFailedExceptionType() { return ExecutionException.class; @@ -39,11 +39,11 @@ protected boolean isSyncClient() { @Override protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { - return AwsCrtAsyncHttpClient.builder().build(); + return AwsCrtAsyncHttpClient.create(); } @Override protected SdkHttpClient createSyncHttpClientWithDefaultProxy() { - throw new IllegalArgumentException("Sync client is not supported"); + throw new IllegalArgumentException("Sync client is not supported for this test."); } } diff --git a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java index 95e4b8b68864..40208abc4d40 100644 --- a/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java +++ b/http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/SyncCrtClientProxyConfigurationTest.java @@ -19,9 +19,9 @@ import software.amazon.awssdk.crt.http.HttpException; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; +import software.amazon.awssdk.http.proxy.HttpClientDefaultProxyConfigTestSuite; -public class SyncCrtClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { +public class SyncCrtClientProxyConfigurationTest extends HttpClientDefaultProxyConfigTestSuite { @Override protected Class getProxyFailedExceptionType() { @@ -40,7 +40,7 @@ protected boolean isSyncClient() { @Override protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { - throw new UnsupportedOperationException("Async client does not support proxy"); + throw new UnsupportedOperationException("Async client is not supported for this test."); } @Override diff --git a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/AwaitCloseChannelPoolMap.java b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/AwaitCloseChannelPoolMap.java index 648908a567c3..e2fbd1c1adca 100644 --- a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/AwaitCloseChannelPoolMap.java +++ b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/internal/AwaitCloseChannelPoolMap.java @@ -192,7 +192,7 @@ private boolean shouldUseProxyForHost(URI remoteAddr) { return shouldProxyForHostCache.computeIfAbsent(remoteAddr, (uri) -> - proxyConfiguration.nonProxyHosts().stream().noneMatch(h -> uri.getHost().matches(h)) + proxyConfiguration.nonProxyHosts().stream().noneMatch(h -> uri.getHost().matches(h)) ); } diff --git a/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java b/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java index 2d4c51621909..0a149a972bd7 100644 --- a/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java +++ b/http-clients/netty-nio-client/src/test/java/NettyClientProxyConfigurationTest.java @@ -18,9 +18,9 @@ import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; +import software.amazon.awssdk.http.proxy.HttpClientDefaultProxyConfigTestSuite; -public class NettyClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { +public class NettyClientProxyConfigurationTest extends HttpClientDefaultProxyConfigTestSuite { @Override protected boolean isSyncClient() { return false; @@ -33,7 +33,7 @@ protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { @Override protected SdkHttpClient createSyncHttpClientWithDefaultProxy() { - throw new IllegalArgumentException("Sync client not supported"); + throw new IllegalArgumentException("Sync client is not supported for this test."); } @Override diff --git a/http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java b/http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java index 827bcd310325..4df7f7a02b6c 100644 --- a/http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java +++ b/http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlClientProxyConfigurationTest.java @@ -18,9 +18,9 @@ import java.io.IOException; import software.amazon.awssdk.http.SdkHttpClient; import software.amazon.awssdk.http.async.SdkAsyncHttpClient; -import software.amazon.awssdk.http.proxy.HttpClientDefaultPoxyConfigTestSuite; +import software.amazon.awssdk.http.proxy.HttpClientDefaultProxyConfigTestSuite; -public class UrlClientProxyConfigurationTest extends HttpClientDefaultPoxyConfigTestSuite { +public class UrlClientProxyConfigurationTest extends HttpClientDefaultProxyConfigTestSuite { @Override protected boolean isSyncClient() { return true; @@ -28,7 +28,7 @@ protected boolean isSyncClient() { @Override protected SdkAsyncHttpClient createHttpClientWithDefaultProxy() { - throw new UnsupportedOperationException("Async client not supported"); + throw new UnsupportedOperationException("Async client is not supported for this test."); } @Override diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTestSuite.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java similarity index 72% rename from test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTestSuite.java rename to test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java index 722ce3720417..20c431a953cb 100644 --- a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultPoxyConfigTestSuite.java +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java @@ -27,8 +27,7 @@ import java.net.URI; import java.nio.ByteBuffer; import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -59,13 +58,14 @@ import software.amazon.awssdk.testutils.EnvironmentVariableHelper; import software.amazon.awssdk.utils.Pair; -public abstract class HttpClientDefaultPoxyConfigTestSuite { +public abstract class HttpClientDefaultProxyConfigTestSuite { SecureRandom random = new SecureRandom(); private static final EnvironmentVariableHelper ENVIRONMENT_VARIABLE_HELPER = new EnvironmentVariableHelper(); protected WireMockServer mockProxy = new WireMockServer(new WireMockConfiguration() .dynamicPort() .dynamicHttpsPort() .enableBrowserProxying(true)); + protected WireMockServer mockServer = new WireMockServer(new WireMockConfiguration() .dynamicPort() .dynamicHttpsPort()); @@ -95,45 +95,35 @@ public void teardown() { ENVIRONMENT_VARIABLE_HELPER.reset(); System.clearProperty("http.proxyHost"); System.clearProperty("http.proxyPort"); + System.clearProperty("https.proxyHost"); + System.clearProperty("https.proxyPort"); } - public static Stream proxyConfigurationSettingWithConnectionFails() { + public static Stream proxyConfigurationSettingsForEnvironmentAndSystemProperty() { return Stream.of( - Arguments.of( - Arrays.asList( - Pair.of("http.proxyHost", "localhost"), - Pair.of("http.proxyPort", "%s")), - Arrays.asList( - Pair.of("http_proxy", - "http://" + "localhost" + ":" + "%s" + "/")), - "Provided system and environment variable when configured uses proxy config"), - Arguments.of(Collections.singletonList( - Pair.of("http.none", "localhost")), - Arrays.asList( - Pair.of("http_proxy", - "http://" + "localhost" + ":" + "%s" + "/")), - "Provided environment and No system variables uses proxy config"), - Arguments.of( - Arrays.asList( - Pair.of("http.proxyHost", "localhost"), - Pair.of("http.proxyPort", "%s")), - Arrays.asList(Pair.of("none", "none")), - "Provided system and No environment variables uses proxy config") + Arguments.of(new TestData() + .addSystemProperKeyValue("http.proxyHost", "localhost") + .addSystemProperKeyValue("http.proxyPort", "%s") + .addEnvironmentPropertyProperKeyValue("https_proxy", "http://" + "localhost" + ":" + "%s" + "/") + , "Provided system and environment variable when configured uses proxy config"), + + Arguments.of(new TestData() + .addSystemProperKeyValue("http.proxyHost", "localhost") + .addSystemProperKeyValue("http.proxyPort", "%s") + .addEnvironmentPropertyProperKeyValue("none", "none") + , "Provided system and No environment variables uses proxy config"), + + Arguments.of(new TestData() + .addSystemProperKeyValue("none", "none") + .addEnvironmentPropertyProperKeyValue("http_proxy", "http://" + "localhost" + ":" + "%s" + "/") + , "Provided Environment Variables and No system variables uses proxy config") ); } - @ParameterizedTest(name = "{index} - {2}.") - @MethodSource("proxyConfigurationSettingWithConnectionFails") - public void ensureProxyErrorsWhenIncorrectPortUsed(List> systemSettingsPair, - List> envSystemSetting, - String testCaseName) throws Throwable { - systemSettingsPair.forEach(settingsPair -> System.setProperty(settingsPair.left(), - String.format(settingsPair.right(), - getRandomPort(mockProxy.port())))); - - envSystemSetting.forEach(settingsPair -> ENVIRONMENT_VARIABLE_HELPER.set( - settingsPair.left(), - String.format(settingsPair.right(), getRandomPort(mockProxy.port())))); + @ParameterizedTest(name = "{index} - {1}.") + @MethodSource("proxyConfigurationSettingsForEnvironmentAndSystemProperty") + public void ensureProxyErrorsWhenIncorrectPortUsed(TestData testData, String testCaseName) throws Throwable { + setSystemPropertyAndEnvironmentVariables(testData, getRandomPort(mockProxy.port())); if (isSyncClient()) { defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), getProxyFailedExceptionType(), @@ -145,8 +135,42 @@ public void ensureProxyErrorsWhenIncorrectPortUsed(List> sy } } + + private void setSystemPropertyAndEnvironmentVariablesToDivertToHttpsProxy(TestData testData, int port) { + testData.systemPropertyPair.stream() + .map(r -> isSyncClient() ? r : Pair.of(r.left().replace("http", "https"), + r.right().replace("http", "https"))) + .forEach(settingsPair -> System.setProperty(settingsPair.left(), String.format(settingsPair.right(), port))); + + testData.envSystemSetting.stream() + .map(r -> isSyncClient() ? r : Pair.of(r.left().replace("http", "https"), + r.right().replace("http", "https"))) + .forEach(settingsPair -> ENVIRONMENT_VARIABLE_HELPER.set(settingsPair.left(), + String.format(settingsPair.right(), port))); + } + + private void setSystemPropertyAndEnvironmentVariables(TestData testData, int port) { + testData.systemPropertyPair + .forEach(settingsPair -> System.setProperty(settingsPair.left(), + String.format(settingsPair.right(), port))); + testData.envSystemSetting + .forEach(settingsPair -> ENVIRONMENT_VARIABLE_HELPER.set(settingsPair.left(), + String.format(settingsPair.right(), port))); + } + + @ParameterizedTest(name = "{index} - {1}.") + @MethodSource("proxyConfigurationSettingsForEnvironmentAndSystemProperty") + public void ensureHttpCallsPassesWhenProxyWithCorrectPortIsUsed(TestData testData, String testCaseName) throws Throwable { + setSystemPropertyAndEnvironmentVariablesToDivertToHttpsProxy(testData, mockProxy.port()); + if (isSyncClient()) { + defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), null, null); + } else { + defaultProxyConfigurationForAsyncHttp(createHttpClientWithDefaultProxy(), null, null); + } + } + @Test - public void ensureProxySucceedsWhenIncorrectPortUsed() throws Throwable { + public void ensureHttpCallsPassesWhenProxyIsNotUsed() throws Throwable { if (isSyncClient()) { defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), null, null); } else { @@ -278,4 +302,19 @@ private int getRandomPort(int currentPort) { } while (randomPort == currentPort); return randomPort; } + + private static class TestData { + private List> envSystemSetting = new ArrayList<>(); + private List> systemPropertyPair = new ArrayList<>(); + + public TestData addSystemProperKeyValue(String key, String value) { + systemPropertyPair.add(Pair.of(key, value)); + return this; + } + + public TestData addEnvironmentPropertyProperKeyValue(String key, String value) { + envSystemSetting.add(Pair.of(key, value)); + return this; + } + } } From 4385fb62f658aa6f68939ebd38632871723d916a Mon Sep 17 00:00:00 2001 From: John Viegas Date: Sun, 25 Feb 2024 16:38:30 -0800 Subject: [PATCH 5/9] Updated change logs --- .../bugfix-AWSCRTHTTPClient-cfe4870.json | 6 ++++ ...ugfix-NettyNIOAsyncHTTPClient-edd86be.json | 6 ++++ ...HttpClientDefaultProxyConfigTestSuite.java | 36 ++++++++++--------- 3 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 .changes/next-release/bugfix-AWSCRTHTTPClient-cfe4870.json create mode 100644 .changes/next-release/bugfix-NettyNIOAsyncHTTPClient-edd86be.json diff --git a/.changes/next-release/bugfix-AWSCRTHTTPClient-cfe4870.json b/.changes/next-release/bugfix-AWSCRTHTTPClient-cfe4870.json new file mode 100644 index 000000000000..f4c2b6e1c75d --- /dev/null +++ b/.changes/next-release/bugfix-AWSCRTHTTPClient-cfe4870.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "AWS CRT HTTP Client", + "contributor": "", + "description": "Addressing Issue [#4745](https://github.com/aws/aws-sdk-java-v2/issues/4745) , Netty and CRT clients' default proxy settings have been made consistent with the Apache client, now using environment and system property settings by default.\\n To disable the use of environment variables and system properties by default, set useSystemPropertyValue(false) and useEnvironmentVariablesValues(false) in ProxyConfigurations." +} diff --git a/.changes/next-release/bugfix-NettyNIOAsyncHTTPClient-edd86be.json b/.changes/next-release/bugfix-NettyNIOAsyncHTTPClient-edd86be.json new file mode 100644 index 000000000000..637cc3f02d89 --- /dev/null +++ b/.changes/next-release/bugfix-NettyNIOAsyncHTTPClient-edd86be.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "Netty NIO Async HTTP Client", + "contributor": "", + "description": "Addressing Issue [#4745](https://github.com/aws/aws-sdk-java-v2/issues/4745) , Netty and CRT clients' default proxy settings have been made consistent with the Apache client, now using environment and system property settings by default.\\n To disable the use of environment variables and system properties by default, set useSystemPropertyValue(false) and useEnvironmentVariablesValues(false) in ProxyConfigurations" +} diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java index 20c431a953cb..a65b68c8bf0a 100644 --- a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java @@ -59,16 +59,18 @@ import software.amazon.awssdk.utils.Pair; public abstract class HttpClientDefaultProxyConfigTestSuite { - SecureRandom random = new SecureRandom(); + private static final EnvironmentVariableHelper ENVIRONMENT_VARIABLE_HELPER = new EnvironmentVariableHelper(); - protected WireMockServer mockProxy = new WireMockServer(new WireMockConfiguration() - .dynamicPort() - .dynamicHttpsPort() - .enableBrowserProxying(true)); - protected WireMockServer mockServer = new WireMockServer(new WireMockConfiguration() - .dynamicPort() - .dynamicHttpsPort()); + SecureRandom random = new SecureRandom(); + WireMockServer mockProxy = new WireMockServer(new WireMockConfiguration() + .dynamicPort() + .dynamicHttpsPort() + .enableBrowserProxying(true)); + + WireMockServer mockServer = new WireMockServer(new WireMockConfiguration() + .dynamicPort() + .dynamicHttpsPort()); protected abstract boolean isSyncClient(); @@ -104,19 +106,19 @@ public static Stream proxyConfigurationSettingsForEnvironmentAndSyste Arguments.of(new TestData() .addSystemProperKeyValue("http.proxyHost", "localhost") .addSystemProperKeyValue("http.proxyPort", "%s") - .addEnvironmentPropertyProperKeyValue("https_proxy", "http://" + "localhost" + ":" + "%s" + "/") - , "Provided system and environment variable when configured uses proxy config"), + .addEnvironmentPropertyProperKeyValue("https_proxy", "http://" + "localhost" + ":" + "%s" + "/"), + "Provided system and environment variable when configured uses proxy config"), Arguments.of(new TestData() .addSystemProperKeyValue("http.proxyHost", "localhost") .addSystemProperKeyValue("http.proxyPort", "%s") - .addEnvironmentPropertyProperKeyValue("none", "none") - , "Provided system and No environment variables uses proxy config"), + .addEnvironmentPropertyProperKeyValue("none", "none"), + "Provided system and No environment variables uses proxy config"), Arguments.of(new TestData() .addSystemProperKeyValue("none", "none") - .addEnvironmentPropertyProperKeyValue("http_proxy", "http://" + "localhost" + ":" + "%s" + "/") - , "Provided Environment Variables and No system variables uses proxy config") + .addEnvironmentPropertyProperKeyValue("http_proxy", "http://" + "localhost" + ":" + "%s" + "/"), + "Provided Environment Variables and No system variables uses proxy config") ); } @@ -140,13 +142,15 @@ private void setSystemPropertyAndEnvironmentVariablesToDivertToHttpsProxy(TestDa testData.systemPropertyPair.stream() .map(r -> isSyncClient() ? r : Pair.of(r.left().replace("http", "https"), r.right().replace("http", "https"))) - .forEach(settingsPair -> System.setProperty(settingsPair.left(), String.format(settingsPair.right(), port))); + .forEach(settingsPair -> System.setProperty(settingsPair.left(), + String.format(settingsPair.right(), port))); testData.envSystemSetting.stream() .map(r -> isSyncClient() ? r : Pair.of(r.left().replace("http", "https"), r.right().replace("http", "https"))) .forEach(settingsPair -> ENVIRONMENT_VARIABLE_HELPER.set(settingsPair.left(), - String.format(settingsPair.right(), port))); + String.format(settingsPair.right(), + port))); } private void setSystemPropertyAndEnvironmentVariables(TestData testData, int port) { From b321a78f4ba7c9d57baaf5bbe0a6f4b296f000cb Mon Sep 17 00:00:00 2001 From: John Viegas Date: Tue, 27 Feb 2024 16:18:18 -0800 Subject: [PATCH 6/9] Updated test case to clear all System properties --- .../HttpClientDefaultProxyConfigTestSuite.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java index a65b68c8bf0a..311270b815ff 100644 --- a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java @@ -84,6 +84,13 @@ public abstract class HttpClientDefaultProxyConfigTestSuite { @BeforeEach public void setup() { + System.clearProperty("http.proxyHost"); + System.clearProperty("http.proxyPort"); + System.clearProperty("https.proxyHost"); + System.clearProperty("https.proxyPort"); + System.clearProperty("http.nonProxyHosts"); + System.clearProperty("https.nonProxyHosts"); + System.clearProperty("https.proxyPort"); mockProxy.start(); mockServer.start(); mockServer.stubFor(get(WireMock.urlMatching(".*")) @@ -95,10 +102,6 @@ public void teardown() { mockServer.stop(); mockProxy.stop(); ENVIRONMENT_VARIABLE_HELPER.reset(); - System.clearProperty("http.proxyHost"); - System.clearProperty("http.proxyPort"); - System.clearProperty("https.proxyHost"); - System.clearProperty("https.proxyPort"); } public static Stream proxyConfigurationSettingsForEnvironmentAndSystemProperty() { @@ -117,7 +120,7 @@ public static Stream proxyConfigurationSettingsForEnvironmentAndSyste Arguments.of(new TestData() .addSystemProperKeyValue("none", "none") - .addEnvironmentPropertyProperKeyValue("http_proxy", "http://" + "localhost" + ":" + "%s" + "/"), + .addEnvironmentPropertyProperKeyValue("http_proxy", "http://" + "localhost" + ":" + "%s"), "Provided Environment Variables and No system variables uses proxy config") ); } From f64ecc1c3a4557fc409aab9afd6b337f062aa11f Mon Sep 17 00:00:00 2001 From: John Viegas Date: Wed, 28 Feb 2024 10:23:53 -0800 Subject: [PATCH 7/9] Non Proxy configs should be independently picked up irrespective of Proxy Host settings --- .../awssdk/crtcore/CrtProxyConfiguration.java | 3 + .../http/apache/ProxyConfiguration.java | 10 ++- .../http/apache/ApacheHttpProxyTest.java | 10 +-- .../http/nio/netty/ProxyConfiguration.java | 9 ++- .../urlconnection/ProxyConfiguration.java | 11 ++- .../http/proxy/ProxyConfigCommonTestData.java | 49 +++++++++++-- .../utils/NonProxyHostConfigProvider.java | 71 +++++++++++++++++++ .../awssdk/utils/ProxyConfigProvider.java | 3 +- .../awssdk/utils/http/SdkHttpUtils.java | 2 +- ...HostEnvironmentVariableConfigProvider.java | 42 +++++++++++ ...ProxyHostSystemPropertyConfigProvider.java | 43 +++++++++++ 11 files changed, 234 insertions(+), 19 deletions(-) create mode 100644 utils/src/main/java/software/amazon/awssdk/utils/NonProxyHostConfigProvider.java create mode 100644 utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostEnvironmentVariableConfigProvider.java create mode 100644 utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostSystemPropertyConfigProvider.java diff --git a/core/crt-core/src/main/java/software/amazon/awssdk/crtcore/CrtProxyConfiguration.java b/core/crt-core/src/main/java/software/amazon/awssdk/crtcore/CrtProxyConfiguration.java index 7c15675a5860..ddd214745476 100644 --- a/core/crt-core/src/main/java/software/amazon/awssdk/crtcore/CrtProxyConfiguration.java +++ b/core/crt-core/src/main/java/software/amazon/awssdk/crtcore/CrtProxyConfiguration.java @@ -19,6 +19,7 @@ import java.util.Objects; import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.utils.NonProxyHostConfigProvider; import software.amazon.awssdk.utils.ProxyConfigProvider; import software.amazon.awssdk.utils.ProxySystemSetting; import software.amazon.awssdk.utils.StringUtils; @@ -45,7 +46,9 @@ protected CrtProxyConfiguration(DefaultBuilder builder) { ProxyConfigProvider proxyConfigProvider = fromSystemEnvironmentSettings(builder.useSystemPropertyValues, builder.useEnvironmentVariableValues , builder.scheme); + this.host = resolveHost(builder, proxyConfigProvider); + this.port = resolvePort(builder, proxyConfigProvider); this.username = resolveUsername(builder, proxyConfigProvider); this.password = resolvePassword(builder, proxyConfigProvider); diff --git a/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ProxyConfiguration.java b/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ProxyConfiguration.java index c5e24a9e7e11..dcc6ecf18da6 100644 --- a/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ProxyConfiguration.java +++ b/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ProxyConfiguration.java @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.Set; import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.utils.NonProxyHostConfigProvider; import software.amazon.awssdk.utils.ProxyConfigProvider; import software.amazon.awssdk.utils.ProxySystemSetting; import software.amazon.awssdk.utils.ToString; @@ -58,11 +59,16 @@ private ProxyConfiguration(DefaultClientProxyConfigurationBuilder builder) { ProxyConfigProvider proxyConfiguration = fromSystemEnvironmentSettings(builder.useSystemPropertyValues, builder.useEnvironmentVariableValues, resolvedScheme); + + NonProxyHostConfigProvider nonProxyHostConfiguration = NonProxyHostConfigProvider. + fromSystemEnvironmentSettings(builder.useSystemPropertyValues, + builder.useEnvironmentVariableValues); + this.username = resolveUsername(builder, proxyConfiguration); this.password = resolvePassword(builder, proxyConfiguration); this.ntlmDomain = builder.ntlmDomain; this.ntlmWorkstation = builder.ntlmWorkstation; - this.nonProxyHosts = resolveNonProxyHosts(builder, proxyConfiguration); + this.nonProxyHosts = resolveNonProxyHosts(builder, nonProxyHostConfiguration); this.preemptiveBasicAuthenticationEnabled = builder.preemptiveBasicAuthenticationEnabled == null ? Boolean.FALSE : builder.preemptiveBasicAuthenticationEnabled; this.useSystemPropertyValues = builder.useSystemPropertyValues; @@ -91,7 +97,7 @@ private static String resolveUsername(DefaultClientProxyConfigurationBuilder bui private static Set resolveNonProxyHosts(DefaultClientProxyConfigurationBuilder builder, - ProxyConfigProvider proxyConfiguration) { + NonProxyHostConfigProvider proxyConfiguration) { if (builder.nonProxyHosts != null || proxyConfiguration == null) { return builder.nonProxyHosts; } diff --git a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheHttpProxyTest.java b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheHttpProxyTest.java index 2ae524bd0b17..91d85e93aeca 100644 --- a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheHttpProxyTest.java +++ b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheHttpProxyTest.java @@ -63,10 +63,10 @@ protected void assertProxyConfiguration(TestProxySetting userSetProxySettings, builder.useEnvironmentVariableValues(useEnvironmentVariable); } ProxyConfiguration proxyConfiguration = builder.build(); - assertThat(proxyConfiguration.host()).isEqualTo(expectedProxySettings.getHost()); - assertThat(proxyConfiguration.port()).isEqualTo(expectedProxySettings.getPort()); - assertThat(proxyConfiguration.username()).isEqualTo(expectedProxySettings.getUserName()); - assertThat(proxyConfiguration.password()).isEqualTo(expectedProxySettings.getPassword()); - assertThat(proxyConfiguration.nonProxyHosts()).isEqualTo(expectedProxySettings.getNonProxyHosts()); + assertThat(expectedProxySettings.getHost()).isEqualTo(proxyConfiguration.host()); + assertThat(expectedProxySettings.getPort()).isEqualTo(proxyConfiguration.port()); + assertThat(expectedProxySettings.getUserName()).isEqualTo(proxyConfiguration.username()); + assertThat(expectedProxySettings.getPassword()).isEqualTo(proxyConfiguration.password()); + assertThat(expectedProxySettings.getNonProxyHosts()).isEqualTo(proxyConfiguration.nonProxyHosts()); } } diff --git a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/ProxyConfiguration.java b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/ProxyConfiguration.java index 2c422fceb2b4..aa61eee52ada 100644 --- a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/ProxyConfiguration.java +++ b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/ProxyConfiguration.java @@ -19,6 +19,7 @@ import java.util.HashSet; import java.util.Set; import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.utils.NonProxyHostConfigProvider; import software.amazon.awssdk.utils.ProxyConfigProvider; import software.amazon.awssdk.utils.ProxyEnvironmentSetting; import software.amazon.awssdk.utils.ProxySystemSetting; @@ -52,14 +53,18 @@ private ProxyConfiguration(BuilderImpl builder) { ProxyConfigProvider.fromSystemEnvironmentSettings(builder.useSystemPropertyValues, builder.useEnvironmentVariablesValues, builder.scheme); + + NonProxyHostConfigProvider nonProxyHostConfigProvider = + NonProxyHostConfigProvider.fromSystemEnvironmentSettings(builder.useSystemPropertyValues, + builder.useEnvironmentVariablesValues); this.host = resolveHost(builder, proxyConfigProvider); this.port = resolvePort(builder, proxyConfigProvider); this.username = resolveUserName(builder, proxyConfigProvider); this.password = resolvePassword(builder, proxyConfigProvider); - this.nonProxyHosts = resolveNonProxyHosts(builder, proxyConfigProvider); + this.nonProxyHosts = resolveNonProxyHosts(builder, nonProxyHostConfigProvider); } - private static Set resolveNonProxyHosts(BuilderImpl builder, ProxyConfigProvider proxyConfigProvider) { + private static Set resolveNonProxyHosts(BuilderImpl builder, NonProxyHostConfigProvider proxyConfigProvider) { if (builder.nonProxyHosts != null || proxyConfigProvider == null) { return builder.nonProxyHosts; } else { diff --git a/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.java b/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.java index 8ca88eb36320..e926dfa4cc36 100644 --- a/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.java +++ b/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.java @@ -22,6 +22,7 @@ import java.util.HashSet; import java.util.Set; import software.amazon.awssdk.annotations.SdkPublicApi; +import software.amazon.awssdk.utils.NonProxyHostConfigProvider; import software.amazon.awssdk.utils.ProxyConfigProvider; import software.amazon.awssdk.utils.ProxyEnvironmentSetting; import software.amazon.awssdk.utils.ProxySystemSetting; @@ -62,9 +63,15 @@ private ProxyConfiguration(DefaultClientProxyConfigurationBuilder builder) { builder.useEnvironmentVariablesValues, resolvedScheme); + NonProxyHostConfigProvider nonProxyHostConfigProvider = + NonProxyHostConfigProvider.fromSystemEnvironmentSettings( + builder.useSystemPropertyValues, + builder.useEnvironmentVariablesValues); + + this.username = resolveUsername(builder, proxyConfigProvider); this.password = resolvePassword(builder, proxyConfigProvider); - this.nonProxyHosts = resolveNonProxyHosts(builder, proxyConfigProvider); + this.nonProxyHosts = resolveNonProxyHosts(builder, nonProxyHostConfigProvider); this.useSystemPropertyValues = builder.useSystemPropertyValues; if (builder.endpoint != null) { @@ -94,7 +101,7 @@ private static String resolvePassword(DefaultClientProxyConfigurationBuilder bui } private static Set resolveNonProxyHosts(DefaultClientProxyConfigurationBuilder builder, - ProxyConfigProvider proxyConfigProvider) { + NonProxyHostConfigProvider proxyConfigProvider) { return builder.nonProxyHosts != null || proxyConfigProvider == null ? builder.nonProxyHosts : proxyConfigProvider.nonProxyHosts(); } diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/ProxyConfigCommonTestData.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/ProxyConfigCommonTestData.java index 4dc1d58be2c7..1228ee9e58de 100644 --- a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/ProxyConfigCommonTestData.java +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/ProxyConfigCommonTestData.java @@ -199,7 +199,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE environmentSettingsWithNoPassword(), new TestProxySetting(), null, null, new TestProxySetting().host(SYSTEM_PROPERTY_HOST).port(Integer.parseInt(SYSTEM_PROPERTY_PORT_NUMBER)) - .password(SYSTEM_PROPERTY_PASSWORD)), + .password(SYSTEM_PROPERTY_PASSWORD).nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY)), Arguments.of( "Given password in System property when Password present in system property " @@ -209,7 +209,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE new TestProxySetting().password("passwordFromBuilder"), null, null, getSystemPropertyProxySettings().password("passwordFromBuilder") .userName(null) - .nonProxyHost(null)), + .nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY)), Arguments.of( "Given partial System Property and partial Environment variables when Builder method with Host " @@ -222,7 +222,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER) .port(USER_PORT_NUMBER_ON_BUILDER) .userName(null) - .nonProxyHost(null)), + .nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY)), Arguments.of( "Given System Property and Environment variables when valid empty Proxy config on Builder then " @@ -236,7 +236,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE + "set useEnvironmentVariable to true and default System property then default system property gets used.", getSystemPropertiesWithNoUserName(), environmentSettingsWithNoPassword(), - new TestProxySetting(), null, true, getSystemPropertyProxySettings().nonProxyHost(null) + new TestProxySetting(), null, true, getSystemPropertyProxySettings().nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY) .userName(null)), Arguments.of( @@ -245,7 +245,21 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE + "resolved", getSystemPropertiesWithNoUserName(), environmentSettingsWithNoPassword(), - new TestProxySetting(), false, true, getEnvironmentVariableProxySettings().password(null)) + new TestProxySetting(), false, true, getEnvironmentVariableProxySettings().password(null)), + + Arguments.of( + "Given", + systemPropertySettingsWithNoNonProxyHosts(), + environmentSettings(), + new TestProxySetting(), true, true, + getSystemPropertyProxySettings().nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY)), + + Arguments.of( + "Given", + systemPropertySettingsWithNoNonProxyHosts(), + environmentSettingsWithNoNonProxy(), + new TestProxySetting(), true, true, + getSystemPropertyProxySettings().nonProxyHost(null)) ); } @@ -264,6 +278,13 @@ private static TestProxySetting getTestProxySettings() { .nonProxyHost(USER_NONPROXY_ON_BUILDER); } + private static TestProxySetting getTestProxySettingsWithNoProxy() { + return new TestProxySetting().host(USER_HOST_ON_BUILDER) + .port(USER_PORT_NUMBER_ON_BUILDER) + .userName(USER_USERNAME_ON_BUILDER) + .password(USER_PASSWORD_ON_BUILDER); + } + private static TestProxySetting getSystemPropertyProxySettings() { return new TestProxySetting().host(SYSTEM_PROPERTY_HOST) @@ -292,6 +313,15 @@ private static List> environmentSettings() { ); } + + private static List> environmentSettingsWithNoNonProxy() { + return Arrays.asList( + Pair.of("%s_proxy", + "http://" + ENV_VARIABLE_USER + ":" + ENV_VARIABLE_PASSWORD + "@" + ENVIRONMENT_HOST + + ":" + ENVIRONMENT_VARIABLE_PORT_NUMBER + "/") + ); + } + private static List> environmentSettingsWithNoPassword() { return Arrays.asList( Pair.of("%s_proxy", @@ -308,4 +338,13 @@ private static List> systemPropertySettings() { Pair.of("%s.proxyUser", SYSTEM_PROPERTY_USER), Pair.of("%s.proxyPassword", SYSTEM_PROPERTY_PASSWORD)); } + + + private static List> systemPropertySettingsWithNoNonProxyHosts() { + return Arrays.asList( + Pair.of("%s.proxyHost", SYSTEM_PROPERTY_HOST), + Pair.of("%s.proxyPort", SYSTEM_PROPERTY_PORT_NUMBER), + Pair.of("%s.proxyUser", SYSTEM_PROPERTY_USER), + Pair.of("%s.proxyPassword", SYSTEM_PROPERTY_PASSWORD)); + } } diff --git a/utils/src/main/java/software/amazon/awssdk/utils/NonProxyHostConfigProvider.java b/utils/src/main/java/software/amazon/awssdk/utils/NonProxyHostConfigProvider.java new file mode 100644 index 000000000000..45421f25f0e0 --- /dev/null +++ b/utils/src/main/java/software/amazon/awssdk/utils/NonProxyHostConfigProvider.java @@ -0,0 +1,71 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.utils; + +import java.util.Collections; +import java.util.Set; +import software.amazon.awssdk.annotations.SdkProtectedApi; +import software.amazon.awssdk.utils.internal.proxy.NonProxyHostEnvironmentVariableConfigProvider; +import software.amazon.awssdk.utils.internal.proxy.NonProxyHostSystemPropertyConfigProvider; + + +/** + * Interface for providing proxy configuration settings. Implementations of this interface can retrieve proxy configuration from + * various sources such as system properties and environment variables. + **/ + +@SdkProtectedApi +public interface NonProxyHostConfigProvider { + + + /** + * Returns a {@link NonProxyHostConfigProvider} based on the specified settings for using system properties, environment + * variables, and the scheme. + * + * @param useSystemPropertyValues A {@code Boolean} indicating whether to use system property values. + * @param useEnvironmentVariableValues A {@code Boolean} indicating whether to use environment variable values. + * @return A {@link NonProxyHostConfigProvider} based on the specified settings. + */ + static NonProxyHostConfigProvider fromSystemEnvironmentSettings(Boolean useSystemPropertyValues, + Boolean useEnvironmentVariableValues) { + NonProxyHostConfigProvider resultProxyConfig = null; + if (Boolean.TRUE.equals(useSystemPropertyValues)) { + resultProxyConfig = fromSystemPropertySettings(); + } else if (Boolean.TRUE.equals(useEnvironmentVariableValues)) { + return fromEnvironmentSettings(); + } + if (resultProxyConfig != null && resultProxyConfig.nonProxyHosts() == null + && Boolean.TRUE.equals(useEnvironmentVariableValues)) { + return fromEnvironmentSettings(); + } + return resultProxyConfig; + } + + static NonProxyHostConfigProvider fromEnvironmentSettings() { + return new NonProxyHostEnvironmentVariableConfigProvider(); + } + + static NonProxyHostConfigProvider fromSystemPropertySettings() { + return new NonProxyHostSystemPropertyConfigProvider(); + } + + /** + * Gets the set of non-proxy hosts. + * + * @return A set containing the non-proxy host names. + */ + Set nonProxyHosts(); +} diff --git a/utils/src/main/java/software/amazon/awssdk/utils/ProxyConfigProvider.java b/utils/src/main/java/software/amazon/awssdk/utils/ProxyConfigProvider.java index 127fbe1fb32f..11213bbef80b 100644 --- a/utils/src/main/java/software/amazon/awssdk/utils/ProxyConfigProvider.java +++ b/utils/src/main/java/software/amazon/awssdk/utils/ProxyConfigProvider.java @@ -78,8 +78,7 @@ static ProxyConfigProvider fromSystemEnvironmentSettings(Boolean useSystemProper boolean isProxyConfigurationNotSet = resultProxyConfig != null && resultProxyConfig.host() == null && resultProxyConfig.port() == 0 && !resultProxyConfig.password().isPresent() - && !resultProxyConfig.userName().isPresent() - && CollectionUtils.isNullOrEmpty(resultProxyConfig.nonProxyHosts()); + && !resultProxyConfig.userName().isPresent(); if (isProxyConfigurationNotSet && Boolean.TRUE.equals(useEnvironmentVariableValues)) { return fromEnvironmentSettings(scheme); diff --git a/utils/src/main/java/software/amazon/awssdk/utils/http/SdkHttpUtils.java b/utils/src/main/java/software/amazon/awssdk/utils/http/SdkHttpUtils.java index 51f03585c51b..3b59efa2db56 100644 --- a/utils/src/main/java/software/amazon/awssdk/utils/http/SdkHttpUtils.java +++ b/utils/src/main/java/software/amazon/awssdk/utils/http/SdkHttpUtils.java @@ -441,7 +441,7 @@ private static Set extractNonProxyHosts(String nonProxyHosts) { .map(s -> StringUtils.replace(s, "*", ".*?")) .collect(Collectors.toSet()); } - return Collections.emptySet(); + return null; } public static Set parseNonProxyHostsEnvironmentVariable() { diff --git a/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostEnvironmentVariableConfigProvider.java b/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostEnvironmentVariableConfigProvider.java new file mode 100644 index 000000000000..78b9845b60ab --- /dev/null +++ b/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostEnvironmentVariableConfigProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.utils.internal.proxy; + +import static software.amazon.awssdk.utils.http.SdkHttpUtils.parseNonProxyHostsEnvironmentVariable; + +import java.util.Set; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.utils.NonProxyHostConfigProvider; + +/** + * An implementation of the {@link NonProxyHostConfigProvider} interface that retrieves non-proxy host configuration settings from + * environment variables. + * + * @see NonProxyHostConfigProvider + */ +@SdkInternalApi +public class NonProxyHostEnvironmentVariableConfigProvider implements NonProxyHostConfigProvider { + + /** + * Retrieves the set of non-proxy hosts from environment variables. + * + * @return The set of non-proxy hosts. + */ + @Override + public Set nonProxyHosts() { + return parseNonProxyHostsEnvironmentVariable(); + } +} \ No newline at end of file diff --git a/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostSystemPropertyConfigProvider.java b/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostSystemPropertyConfigProvider.java new file mode 100644 index 000000000000..6fba29aa2dca --- /dev/null +++ b/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostSystemPropertyConfigProvider.java @@ -0,0 +1,43 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.utils.internal.proxy; + +import static software.amazon.awssdk.utils.http.SdkHttpUtils.parseNonProxyHostsEnvironmentVariable; +import static software.amazon.awssdk.utils.http.SdkHttpUtils.parseNonProxyHostsProperty; + +import java.util.Set; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.utils.NonProxyHostConfigProvider; + +/** + * An implementation of the {@link NonProxyHostConfigProvider} interface that retrieves non-proxy host configuration settings from + * environment variables. + * + * @see NonProxyHostConfigProvider + */ +@SdkInternalApi +public class NonProxyHostSystemPropertyConfigProvider implements NonProxyHostConfigProvider { + + /** + * Retrieves the set of non-proxy hosts from environment variables. + * + * @return The set of non-proxy hosts. + */ + @Override + public Set nonProxyHosts() { + return parseNonProxyHostsProperty(); + } +} \ No newline at end of file From aac09a7f6461a5a3e8fca8e3f225e0972d407207 Mon Sep 17 00:00:00 2001 From: John Viegas Date: Wed, 28 Feb 2024 20:23:09 -0800 Subject: [PATCH 8/9] Revert "Non Proxy configs should be independently picked up irrespective of Proxy Host settings" This reverts commit f64ecc1c3a4557fc409aab9afd6b337f062aa11f. --- .../awssdk/crtcore/CrtProxyConfiguration.java | 3 - .../http/apache/ProxyConfiguration.java | 10 +-- .../http/apache/ApacheHttpProxyTest.java | 10 +-- .../http/nio/netty/ProxyConfiguration.java | 9 +-- .../urlconnection/ProxyConfiguration.java | 11 +-- .../http/proxy/ProxyConfigCommonTestData.java | 49 ++----------- .../utils/NonProxyHostConfigProvider.java | 71 ------------------- .../awssdk/utils/ProxyConfigProvider.java | 3 +- .../awssdk/utils/http/SdkHttpUtils.java | 2 +- ...HostEnvironmentVariableConfigProvider.java | 42 ----------- ...ProxyHostSystemPropertyConfigProvider.java | 43 ----------- 11 files changed, 19 insertions(+), 234 deletions(-) delete mode 100644 utils/src/main/java/software/amazon/awssdk/utils/NonProxyHostConfigProvider.java delete mode 100644 utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostEnvironmentVariableConfigProvider.java delete mode 100644 utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostSystemPropertyConfigProvider.java diff --git a/core/crt-core/src/main/java/software/amazon/awssdk/crtcore/CrtProxyConfiguration.java b/core/crt-core/src/main/java/software/amazon/awssdk/crtcore/CrtProxyConfiguration.java index ddd214745476..7c15675a5860 100644 --- a/core/crt-core/src/main/java/software/amazon/awssdk/crtcore/CrtProxyConfiguration.java +++ b/core/crt-core/src/main/java/software/amazon/awssdk/crtcore/CrtProxyConfiguration.java @@ -19,7 +19,6 @@ import java.util.Objects; import software.amazon.awssdk.annotations.SdkPublicApi; -import software.amazon.awssdk.utils.NonProxyHostConfigProvider; import software.amazon.awssdk.utils.ProxyConfigProvider; import software.amazon.awssdk.utils.ProxySystemSetting; import software.amazon.awssdk.utils.StringUtils; @@ -46,9 +45,7 @@ protected CrtProxyConfiguration(DefaultBuilder builder) { ProxyConfigProvider proxyConfigProvider = fromSystemEnvironmentSettings(builder.useSystemPropertyValues, builder.useEnvironmentVariableValues , builder.scheme); - this.host = resolveHost(builder, proxyConfigProvider); - this.port = resolvePort(builder, proxyConfigProvider); this.username = resolveUsername(builder, proxyConfigProvider); this.password = resolvePassword(builder, proxyConfigProvider); diff --git a/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ProxyConfiguration.java b/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ProxyConfiguration.java index dcc6ecf18da6..c5e24a9e7e11 100644 --- a/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ProxyConfiguration.java +++ b/http-clients/apache-client/src/main/java/software/amazon/awssdk/http/apache/ProxyConfiguration.java @@ -23,7 +23,6 @@ import java.util.HashSet; import java.util.Set; import software.amazon.awssdk.annotations.SdkPublicApi; -import software.amazon.awssdk.utils.NonProxyHostConfigProvider; import software.amazon.awssdk.utils.ProxyConfigProvider; import software.amazon.awssdk.utils.ProxySystemSetting; import software.amazon.awssdk.utils.ToString; @@ -59,16 +58,11 @@ private ProxyConfiguration(DefaultClientProxyConfigurationBuilder builder) { ProxyConfigProvider proxyConfiguration = fromSystemEnvironmentSettings(builder.useSystemPropertyValues, builder.useEnvironmentVariableValues, resolvedScheme); - - NonProxyHostConfigProvider nonProxyHostConfiguration = NonProxyHostConfigProvider. - fromSystemEnvironmentSettings(builder.useSystemPropertyValues, - builder.useEnvironmentVariableValues); - this.username = resolveUsername(builder, proxyConfiguration); this.password = resolvePassword(builder, proxyConfiguration); this.ntlmDomain = builder.ntlmDomain; this.ntlmWorkstation = builder.ntlmWorkstation; - this.nonProxyHosts = resolveNonProxyHosts(builder, nonProxyHostConfiguration); + this.nonProxyHosts = resolveNonProxyHosts(builder, proxyConfiguration); this.preemptiveBasicAuthenticationEnabled = builder.preemptiveBasicAuthenticationEnabled == null ? Boolean.FALSE : builder.preemptiveBasicAuthenticationEnabled; this.useSystemPropertyValues = builder.useSystemPropertyValues; @@ -97,7 +91,7 @@ private static String resolveUsername(DefaultClientProxyConfigurationBuilder bui private static Set resolveNonProxyHosts(DefaultClientProxyConfigurationBuilder builder, - NonProxyHostConfigProvider proxyConfiguration) { + ProxyConfigProvider proxyConfiguration) { if (builder.nonProxyHosts != null || proxyConfiguration == null) { return builder.nonProxyHosts; } diff --git a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheHttpProxyTest.java b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheHttpProxyTest.java index 91d85e93aeca..2ae524bd0b17 100644 --- a/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheHttpProxyTest.java +++ b/http-clients/apache-client/src/test/java/software/amazon/awssdk/http/apache/ApacheHttpProxyTest.java @@ -63,10 +63,10 @@ protected void assertProxyConfiguration(TestProxySetting userSetProxySettings, builder.useEnvironmentVariableValues(useEnvironmentVariable); } ProxyConfiguration proxyConfiguration = builder.build(); - assertThat(expectedProxySettings.getHost()).isEqualTo(proxyConfiguration.host()); - assertThat(expectedProxySettings.getPort()).isEqualTo(proxyConfiguration.port()); - assertThat(expectedProxySettings.getUserName()).isEqualTo(proxyConfiguration.username()); - assertThat(expectedProxySettings.getPassword()).isEqualTo(proxyConfiguration.password()); - assertThat(expectedProxySettings.getNonProxyHosts()).isEqualTo(proxyConfiguration.nonProxyHosts()); + assertThat(proxyConfiguration.host()).isEqualTo(expectedProxySettings.getHost()); + assertThat(proxyConfiguration.port()).isEqualTo(expectedProxySettings.getPort()); + assertThat(proxyConfiguration.username()).isEqualTo(expectedProxySettings.getUserName()); + assertThat(proxyConfiguration.password()).isEqualTo(expectedProxySettings.getPassword()); + assertThat(proxyConfiguration.nonProxyHosts()).isEqualTo(expectedProxySettings.getNonProxyHosts()); } } diff --git a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/ProxyConfiguration.java b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/ProxyConfiguration.java index aa61eee52ada..2c422fceb2b4 100644 --- a/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/ProxyConfiguration.java +++ b/http-clients/netty-nio-client/src/main/java/software/amazon/awssdk/http/nio/netty/ProxyConfiguration.java @@ -19,7 +19,6 @@ import java.util.HashSet; import java.util.Set; import software.amazon.awssdk.annotations.SdkPublicApi; -import software.amazon.awssdk.utils.NonProxyHostConfigProvider; import software.amazon.awssdk.utils.ProxyConfigProvider; import software.amazon.awssdk.utils.ProxyEnvironmentSetting; import software.amazon.awssdk.utils.ProxySystemSetting; @@ -53,18 +52,14 @@ private ProxyConfiguration(BuilderImpl builder) { ProxyConfigProvider.fromSystemEnvironmentSettings(builder.useSystemPropertyValues, builder.useEnvironmentVariablesValues, builder.scheme); - - NonProxyHostConfigProvider nonProxyHostConfigProvider = - NonProxyHostConfigProvider.fromSystemEnvironmentSettings(builder.useSystemPropertyValues, - builder.useEnvironmentVariablesValues); this.host = resolveHost(builder, proxyConfigProvider); this.port = resolvePort(builder, proxyConfigProvider); this.username = resolveUserName(builder, proxyConfigProvider); this.password = resolvePassword(builder, proxyConfigProvider); - this.nonProxyHosts = resolveNonProxyHosts(builder, nonProxyHostConfigProvider); + this.nonProxyHosts = resolveNonProxyHosts(builder, proxyConfigProvider); } - private static Set resolveNonProxyHosts(BuilderImpl builder, NonProxyHostConfigProvider proxyConfigProvider) { + private static Set resolveNonProxyHosts(BuilderImpl builder, ProxyConfigProvider proxyConfigProvider) { if (builder.nonProxyHosts != null || proxyConfigProvider == null) { return builder.nonProxyHosts; } else { diff --git a/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.java b/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.java index e926dfa4cc36..8ca88eb36320 100644 --- a/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.java +++ b/http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/ProxyConfiguration.java @@ -22,7 +22,6 @@ import java.util.HashSet; import java.util.Set; import software.amazon.awssdk.annotations.SdkPublicApi; -import software.amazon.awssdk.utils.NonProxyHostConfigProvider; import software.amazon.awssdk.utils.ProxyConfigProvider; import software.amazon.awssdk.utils.ProxyEnvironmentSetting; import software.amazon.awssdk.utils.ProxySystemSetting; @@ -63,15 +62,9 @@ private ProxyConfiguration(DefaultClientProxyConfigurationBuilder builder) { builder.useEnvironmentVariablesValues, resolvedScheme); - NonProxyHostConfigProvider nonProxyHostConfigProvider = - NonProxyHostConfigProvider.fromSystemEnvironmentSettings( - builder.useSystemPropertyValues, - builder.useEnvironmentVariablesValues); - - this.username = resolveUsername(builder, proxyConfigProvider); this.password = resolvePassword(builder, proxyConfigProvider); - this.nonProxyHosts = resolveNonProxyHosts(builder, nonProxyHostConfigProvider); + this.nonProxyHosts = resolveNonProxyHosts(builder, proxyConfigProvider); this.useSystemPropertyValues = builder.useSystemPropertyValues; if (builder.endpoint != null) { @@ -101,7 +94,7 @@ private static String resolvePassword(DefaultClientProxyConfigurationBuilder bui } private static Set resolveNonProxyHosts(DefaultClientProxyConfigurationBuilder builder, - NonProxyHostConfigProvider proxyConfigProvider) { + ProxyConfigProvider proxyConfigProvider) { return builder.nonProxyHosts != null || proxyConfigProvider == null ? builder.nonProxyHosts : proxyConfigProvider.nonProxyHosts(); } diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/ProxyConfigCommonTestData.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/ProxyConfigCommonTestData.java index 1228ee9e58de..4dc1d58be2c7 100644 --- a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/ProxyConfigCommonTestData.java +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/ProxyConfigCommonTestData.java @@ -199,7 +199,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE environmentSettingsWithNoPassword(), new TestProxySetting(), null, null, new TestProxySetting().host(SYSTEM_PROPERTY_HOST).port(Integer.parseInt(SYSTEM_PROPERTY_PORT_NUMBER)) - .password(SYSTEM_PROPERTY_PASSWORD).nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY)), + .password(SYSTEM_PROPERTY_PASSWORD)), Arguments.of( "Given password in System property when Password present in system property " @@ -209,7 +209,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE new TestProxySetting().password("passwordFromBuilder"), null, null, getSystemPropertyProxySettings().password("passwordFromBuilder") .userName(null) - .nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY)), + .nonProxyHost(null)), Arguments.of( "Given partial System Property and partial Environment variables when Builder method with Host " @@ -222,7 +222,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER) .port(USER_PORT_NUMBER_ON_BUILDER) .userName(null) - .nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY)), + .nonProxyHost(null)), Arguments.of( "Given System Property and Environment variables when valid empty Proxy config on Builder then " @@ -236,7 +236,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE + "set useEnvironmentVariable to true and default System property then default system property gets used.", getSystemPropertiesWithNoUserName(), environmentSettingsWithNoPassword(), - new TestProxySetting(), null, true, getSystemPropertyProxySettings().nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY) + new TestProxySetting(), null, true, getSystemPropertyProxySettings().nonProxyHost(null) .userName(null)), Arguments.of( @@ -245,21 +245,7 @@ null, null, getSystemPropertyProxySettings().host(USER_HOST_ON_BUILDER).port(USE + "resolved", getSystemPropertiesWithNoUserName(), environmentSettingsWithNoPassword(), - new TestProxySetting(), false, true, getEnvironmentVariableProxySettings().password(null)), - - Arguments.of( - "Given", - systemPropertySettingsWithNoNonProxyHosts(), - environmentSettings(), - new TestProxySetting(), true, true, - getSystemPropertyProxySettings().nonProxyHost(ENVIRONMENT_VARIABLE_NON_PROXY)), - - Arguments.of( - "Given", - systemPropertySettingsWithNoNonProxyHosts(), - environmentSettingsWithNoNonProxy(), - new TestProxySetting(), true, true, - getSystemPropertyProxySettings().nonProxyHost(null)) + new TestProxySetting(), false, true, getEnvironmentVariableProxySettings().password(null)) ); } @@ -278,13 +264,6 @@ private static TestProxySetting getTestProxySettings() { .nonProxyHost(USER_NONPROXY_ON_BUILDER); } - private static TestProxySetting getTestProxySettingsWithNoProxy() { - return new TestProxySetting().host(USER_HOST_ON_BUILDER) - .port(USER_PORT_NUMBER_ON_BUILDER) - .userName(USER_USERNAME_ON_BUILDER) - .password(USER_PASSWORD_ON_BUILDER); - } - private static TestProxySetting getSystemPropertyProxySettings() { return new TestProxySetting().host(SYSTEM_PROPERTY_HOST) @@ -313,15 +292,6 @@ private static List> environmentSettings() { ); } - - private static List> environmentSettingsWithNoNonProxy() { - return Arrays.asList( - Pair.of("%s_proxy", - "http://" + ENV_VARIABLE_USER + ":" + ENV_VARIABLE_PASSWORD + "@" + ENVIRONMENT_HOST - + ":" + ENVIRONMENT_VARIABLE_PORT_NUMBER + "/") - ); - } - private static List> environmentSettingsWithNoPassword() { return Arrays.asList( Pair.of("%s_proxy", @@ -338,13 +308,4 @@ private static List> systemPropertySettings() { Pair.of("%s.proxyUser", SYSTEM_PROPERTY_USER), Pair.of("%s.proxyPassword", SYSTEM_PROPERTY_PASSWORD)); } - - - private static List> systemPropertySettingsWithNoNonProxyHosts() { - return Arrays.asList( - Pair.of("%s.proxyHost", SYSTEM_PROPERTY_HOST), - Pair.of("%s.proxyPort", SYSTEM_PROPERTY_PORT_NUMBER), - Pair.of("%s.proxyUser", SYSTEM_PROPERTY_USER), - Pair.of("%s.proxyPassword", SYSTEM_PROPERTY_PASSWORD)); - } } diff --git a/utils/src/main/java/software/amazon/awssdk/utils/NonProxyHostConfigProvider.java b/utils/src/main/java/software/amazon/awssdk/utils/NonProxyHostConfigProvider.java deleted file mode 100644 index 45421f25f0e0..000000000000 --- a/utils/src/main/java/software/amazon/awssdk/utils/NonProxyHostConfigProvider.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.utils; - -import java.util.Collections; -import java.util.Set; -import software.amazon.awssdk.annotations.SdkProtectedApi; -import software.amazon.awssdk.utils.internal.proxy.NonProxyHostEnvironmentVariableConfigProvider; -import software.amazon.awssdk.utils.internal.proxy.NonProxyHostSystemPropertyConfigProvider; - - -/** - * Interface for providing proxy configuration settings. Implementations of this interface can retrieve proxy configuration from - * various sources such as system properties and environment variables. - **/ - -@SdkProtectedApi -public interface NonProxyHostConfigProvider { - - - /** - * Returns a {@link NonProxyHostConfigProvider} based on the specified settings for using system properties, environment - * variables, and the scheme. - * - * @param useSystemPropertyValues A {@code Boolean} indicating whether to use system property values. - * @param useEnvironmentVariableValues A {@code Boolean} indicating whether to use environment variable values. - * @return A {@link NonProxyHostConfigProvider} based on the specified settings. - */ - static NonProxyHostConfigProvider fromSystemEnvironmentSettings(Boolean useSystemPropertyValues, - Boolean useEnvironmentVariableValues) { - NonProxyHostConfigProvider resultProxyConfig = null; - if (Boolean.TRUE.equals(useSystemPropertyValues)) { - resultProxyConfig = fromSystemPropertySettings(); - } else if (Boolean.TRUE.equals(useEnvironmentVariableValues)) { - return fromEnvironmentSettings(); - } - if (resultProxyConfig != null && resultProxyConfig.nonProxyHosts() == null - && Boolean.TRUE.equals(useEnvironmentVariableValues)) { - return fromEnvironmentSettings(); - } - return resultProxyConfig; - } - - static NonProxyHostConfigProvider fromEnvironmentSettings() { - return new NonProxyHostEnvironmentVariableConfigProvider(); - } - - static NonProxyHostConfigProvider fromSystemPropertySettings() { - return new NonProxyHostSystemPropertyConfigProvider(); - } - - /** - * Gets the set of non-proxy hosts. - * - * @return A set containing the non-proxy host names. - */ - Set nonProxyHosts(); -} diff --git a/utils/src/main/java/software/amazon/awssdk/utils/ProxyConfigProvider.java b/utils/src/main/java/software/amazon/awssdk/utils/ProxyConfigProvider.java index 11213bbef80b..127fbe1fb32f 100644 --- a/utils/src/main/java/software/amazon/awssdk/utils/ProxyConfigProvider.java +++ b/utils/src/main/java/software/amazon/awssdk/utils/ProxyConfigProvider.java @@ -78,7 +78,8 @@ static ProxyConfigProvider fromSystemEnvironmentSettings(Boolean useSystemProper boolean isProxyConfigurationNotSet = resultProxyConfig != null && resultProxyConfig.host() == null && resultProxyConfig.port() == 0 && !resultProxyConfig.password().isPresent() - && !resultProxyConfig.userName().isPresent(); + && !resultProxyConfig.userName().isPresent() + && CollectionUtils.isNullOrEmpty(resultProxyConfig.nonProxyHosts()); if (isProxyConfigurationNotSet && Boolean.TRUE.equals(useEnvironmentVariableValues)) { return fromEnvironmentSettings(scheme); diff --git a/utils/src/main/java/software/amazon/awssdk/utils/http/SdkHttpUtils.java b/utils/src/main/java/software/amazon/awssdk/utils/http/SdkHttpUtils.java index 3b59efa2db56..51f03585c51b 100644 --- a/utils/src/main/java/software/amazon/awssdk/utils/http/SdkHttpUtils.java +++ b/utils/src/main/java/software/amazon/awssdk/utils/http/SdkHttpUtils.java @@ -441,7 +441,7 @@ private static Set extractNonProxyHosts(String nonProxyHosts) { .map(s -> StringUtils.replace(s, "*", ".*?")) .collect(Collectors.toSet()); } - return null; + return Collections.emptySet(); } public static Set parseNonProxyHostsEnvironmentVariable() { diff --git a/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostEnvironmentVariableConfigProvider.java b/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostEnvironmentVariableConfigProvider.java deleted file mode 100644 index 78b9845b60ab..000000000000 --- a/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostEnvironmentVariableConfigProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.utils.internal.proxy; - -import static software.amazon.awssdk.utils.http.SdkHttpUtils.parseNonProxyHostsEnvironmentVariable; - -import java.util.Set; -import software.amazon.awssdk.annotations.SdkInternalApi; -import software.amazon.awssdk.utils.NonProxyHostConfigProvider; - -/** - * An implementation of the {@link NonProxyHostConfigProvider} interface that retrieves non-proxy host configuration settings from - * environment variables. - * - * @see NonProxyHostConfigProvider - */ -@SdkInternalApi -public class NonProxyHostEnvironmentVariableConfigProvider implements NonProxyHostConfigProvider { - - /** - * Retrieves the set of non-proxy hosts from environment variables. - * - * @return The set of non-proxy hosts. - */ - @Override - public Set nonProxyHosts() { - return parseNonProxyHostsEnvironmentVariable(); - } -} \ No newline at end of file diff --git a/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostSystemPropertyConfigProvider.java b/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostSystemPropertyConfigProvider.java deleted file mode 100644 index 6fba29aa2dca..000000000000 --- a/utils/src/main/java/software/amazon/awssdk/utils/internal/proxy/NonProxyHostSystemPropertyConfigProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.utils.internal.proxy; - -import static software.amazon.awssdk.utils.http.SdkHttpUtils.parseNonProxyHostsEnvironmentVariable; -import static software.amazon.awssdk.utils.http.SdkHttpUtils.parseNonProxyHostsProperty; - -import java.util.Set; -import software.amazon.awssdk.annotations.SdkInternalApi; -import software.amazon.awssdk.utils.NonProxyHostConfigProvider; - -/** - * An implementation of the {@link NonProxyHostConfigProvider} interface that retrieves non-proxy host configuration settings from - * environment variables. - * - * @see NonProxyHostConfigProvider - */ -@SdkInternalApi -public class NonProxyHostSystemPropertyConfigProvider implements NonProxyHostConfigProvider { - - /** - * Retrieves the set of non-proxy hosts from environment variables. - * - * @return The set of non-proxy hosts. - */ - @Override - public Set nonProxyHosts() { - return parseNonProxyHostsProperty(); - } -} \ No newline at end of file From 951ae742d33feab0187085c1124d8cbdcf993df5 Mon Sep 17 00:00:00 2001 From: John Viegas Date: Wed, 28 Feb 2024 21:09:09 -0800 Subject: [PATCH 9/9] Handled Zoes comments to close the client --- ...HttpClientDefaultProxyConfigTestSuite.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java index 311270b815ff..04fc4a5d41f9 100644 --- a/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java +++ b/test/http-client-tests/src/main/java/software/amazon/awssdk/http/proxy/HttpClientDefaultProxyConfigTestSuite.java @@ -130,13 +130,17 @@ public static Stream proxyConfigurationSettingsForEnvironmentAndSyste public void ensureProxyErrorsWhenIncorrectPortUsed(TestData testData, String testCaseName) throws Throwable { setSystemPropertyAndEnvironmentVariables(testData, getRandomPort(mockProxy.port())); if (isSyncClient()) { - defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), + SdkHttpClient syncHttpClientWithDefaultProxy = createSyncHttpClientWithDefaultProxy(); + defaultProxyConfigurationSyncHttp(syncHttpClientWithDefaultProxy, getProxyFailedExceptionType(), getProxyFailedCauseExceptionType()); + syncHttpClientWithDefaultProxy.close(); } else { - defaultProxyConfigurationForAsyncHttp(createHttpClientWithDefaultProxy(), + SdkAsyncHttpClient httpClientWithDefaultProxy = createHttpClientWithDefaultProxy(); + defaultProxyConfigurationForAsyncHttp(httpClientWithDefaultProxy, getProxyFailedExceptionType(), getProxyFailedCauseExceptionType()); + httpClientWithDefaultProxy.close(); } } @@ -170,18 +174,27 @@ private void setSystemPropertyAndEnvironmentVariables(TestData testData, int por public void ensureHttpCallsPassesWhenProxyWithCorrectPortIsUsed(TestData testData, String testCaseName) throws Throwable { setSystemPropertyAndEnvironmentVariablesToDivertToHttpsProxy(testData, mockProxy.port()); if (isSyncClient()) { - defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), null, null); + SdkHttpClient syncHttpClientWithDefaultProxy = createSyncHttpClientWithDefaultProxy(); + defaultProxyConfigurationSyncHttp(syncHttpClientWithDefaultProxy, null, null); + syncHttpClientWithDefaultProxy.close(); + } else { - defaultProxyConfigurationForAsyncHttp(createHttpClientWithDefaultProxy(), null, null); + SdkAsyncHttpClient asyncHttpClient = createHttpClientWithDefaultProxy(); + defaultProxyConfigurationForAsyncHttp(asyncHttpClient, null, null); + asyncHttpClient.close(); } } @Test public void ensureHttpCallsPassesWhenProxyIsNotUsed() throws Throwable { if (isSyncClient()) { - defaultProxyConfigurationSyncHttp(createSyncHttpClientWithDefaultProxy(), null, null); + SdkHttpClient sdkHttpClient = createSyncHttpClientWithDefaultProxy(); + defaultProxyConfigurationSyncHttp(sdkHttpClient, null, null); + sdkHttpClient.close(); } else { - defaultProxyConfigurationForAsyncHttp(createHttpClientWithDefaultProxy(), null, null); + SdkAsyncHttpClient asyncHttpClient = createHttpClientWithDefaultProxy(); + defaultProxyConfigurationForAsyncHttp(asyncHttpClient, null, null); + asyncHttpClient.close(); } }