Skip to content

Commit 911496d

Browse files
kiiadimillems
authored andcommitted
Adding the ability to control how a HttpURLConnection gets created.
1 parent 472f5bf commit 911496d

File tree

5 files changed

+107
-6
lines changed

5 files changed

+107
-6
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"category": "URLConnection HTTP Client",
3+
"type": "feature",
4+
"description": "Adding a hook to enable custom creation of the initial `HttpURLConnection`. This enables customers to control how a connection is established for a given `URL` including handling any required proxy configuration etc."
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.http.urlconnection;
17+
18+
import java.net.HttpURLConnection;
19+
import java.net.URI;
20+
import software.amazon.awssdk.annotations.SdkPublicApi;
21+
22+
/**
23+
* An interface that, given a {@link URI} creates a new {@link HttpURLConnection}. This allows customization
24+
* of the creation and configuration of the {@link HttpURLConnection}.
25+
*/
26+
@FunctionalInterface
27+
@SdkPublicApi
28+
public interface UrlConnectionFactory {
29+
30+
/**
31+
* For the given {@link URI} create an {@link HttpURLConnection}.
32+
* @param uri the {@link URI} of the request
33+
* @return a {@link HttpURLConnection} to the given {@link URI}
34+
*/
35+
HttpURLConnection createConnection(URI uri);
36+
}

http-clients/url-connection-client/src/main/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.io.IOException;
2626
import java.io.InputStream;
2727
import java.net.HttpURLConnection;
28+
import java.net.URI;
2829
import java.time.Duration;
2930
import java.util.List;
3031
import java.util.Map;
@@ -54,15 +55,42 @@
5455
public final class UrlConnectionHttpClient implements SdkHttpClient {
5556

5657
private final AttributeMap options;
58+
private final UrlConnectionFactory connectionFactory;
5759

58-
private UrlConnectionHttpClient(AttributeMap options) {
60+
private UrlConnectionHttpClient(AttributeMap options, UrlConnectionFactory connectionFactory) {
5961
this.options = options;
62+
if (connectionFactory != null) {
63+
this.connectionFactory = connectionFactory;
64+
} else {
65+
this.connectionFactory = this::createDefaultConnection;
66+
}
67+
6068
}
6169

6270
public static Builder builder() {
6371
return new DefaultBuilder();
6472
}
6573

74+
/**
75+
* Create a {@link HttpURLConnection} client with the default properties
76+
*
77+
* @return an {@link UrlConnectionHttpClient}
78+
*/
79+
public static SdkHttpClient create() {
80+
return new DefaultBuilder().build();
81+
}
82+
83+
/**
84+
* Use this method if you want to control the way a {@link HttpURLConnection} is created.
85+
* This will ignore SDK defaults like {@link SdkHttpConfigurationOption#CONNECTION_TIMEOUT}
86+
* and {@link SdkHttpConfigurationOption#READ_TIMEOUT}
87+
* @param connectionFactory a function that, given a {@link URI} will create an {@link HttpURLConnection}
88+
* @return an {@link UrlConnectionHttpClient}
89+
*/
90+
public static SdkHttpClient create(UrlConnectionFactory connectionFactory) {
91+
return new UrlConnectionHttpClient(AttributeMap.empty(), connectionFactory);
92+
}
93+
6694
@Override
6795
public ExecutableHttpRequest prepareRequest(HttpExecuteRequest request) {
6896
HttpURLConnection connection = createAndConfigureConnection(request);
@@ -75,8 +103,7 @@ public void close() {
75103
}
76104

77105
private HttpURLConnection createAndConfigureConnection(HttpExecuteRequest request) {
78-
HttpURLConnection connection =
79-
invokeSafely(() -> (HttpURLConnection) request.httpRequest().getUri().toURL().openConnection());
106+
HttpURLConnection connection = connectionFactory.createConnection(request.httpRequest().getUri());
80107
request.httpRequest()
81108
.headers()
82109
.forEach((key, values) -> values.forEach(value -> connection.setRequestProperty(key, value)));
@@ -85,9 +112,13 @@ private HttpURLConnection createAndConfigureConnection(HttpExecuteRequest reques
85112
connection.setDoOutput(true);
86113
}
87114

115+
return connection;
116+
}
117+
118+
private HttpURLConnection createDefaultConnection(URI uri) {
119+
HttpURLConnection connection = invokeSafely(() -> (HttpURLConnection) uri.toURL().openConnection());
88120
connection.setConnectTimeout(saturatedCast(options.get(CONNECTION_TIMEOUT).toMillis()));
89121
connection.setReadTimeout(saturatedCast(options.get(READ_TIMEOUT).toMillis()));
90-
91122
return connection;
92123
}
93124

@@ -210,7 +241,8 @@ public void setConnectionTimeout(Duration connectionTimeout) {
210241
public SdkHttpClient buildWithDefaults(AttributeMap serviceDefaults) {
211242
return new UrlConnectionHttpClient(standardOptions.build()
212243
.merge(serviceDefaults)
213-
.merge(SdkHttpConfigurationOption.GLOBAL_HTTP_DEFAULTS));
244+
.merge(SdkHttpConfigurationOption.GLOBAL_HTTP_DEFAULTS),
245+
null);
214246
}
215247
}
216248
}

http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClientWireMockTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@
2020
public final class UrlConnectionHttpClientWireMockTest extends SdkHttpClientTestSuite {
2121
@Override
2222
protected SdkHttpClient createSdkHttpClient(SdkHttpClientOptions options) {
23-
return UrlConnectionHttpClient.builder().build();
23+
return UrlConnectionHttpClient.create();
2424
}
2525
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
package software.amazon.awssdk.http.urlconnection;
16+
17+
import static software.amazon.awssdk.utils.FunctionalUtils.invokeSafely;
18+
19+
import java.net.HttpURLConnection;
20+
import software.amazon.awssdk.http.SdkHttpClient;
21+
import software.amazon.awssdk.http.SdkHttpClientTestSuite;
22+
23+
public final class UrlConnectionHttpClientWithCustomCreateWireMockTest extends SdkHttpClientTestSuite {
24+
@Override
25+
protected SdkHttpClient createSdkHttpClient(SdkHttpClientOptions options) {
26+
return UrlConnectionHttpClient.create((uri) -> invokeSafely(() -> (HttpURLConnection) uri.toURL().openConnection()));
27+
}
28+
}

0 commit comments

Comments
 (0)