Skip to content

Commit a94cd3e

Browse files
committed
Added ConnectionSocketFactory to Apache5Client builder same as Apache4
1 parent 9472ac8 commit a94cd3e

File tree

6 files changed

+557
-128
lines changed

6 files changed

+557
-128
lines changed

http-clients/apache5-client/src/main/java/software/amazon/awssdk/http/apache5/Apache5HttpClient.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@
5353
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
5454
import org.apache.hc.client5.http.protocol.HttpClientContext;
5555
import org.apache.hc.client5.http.routing.HttpRoutePlanner;
56+
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
5657
import org.apache.hc.client5.http.ssl.DefaultHostnameVerifier;
5758
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
58-
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
5959
import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
6060
import org.apache.hc.core5.http.ClassicHttpResponse;
6161
import org.apache.hc.core5.http.Header;
@@ -88,10 +88,10 @@
8888
import software.amazon.awssdk.http.apache5.internal.DefaultConfiguration;
8989
import software.amazon.awssdk.http.apache5.internal.SdkProxyRoutePlanner;
9090
import software.amazon.awssdk.http.apache5.internal.conn.ClientConnectionManagerFactory;
91+
import software.amazon.awssdk.http.apache5.internal.conn.ConnectionSocketFactoryToTlsStrategyAdapter;
9192
import software.amazon.awssdk.http.apache5.internal.conn.IdleConnectionReaper;
9293
import software.amazon.awssdk.http.apache5.internal.conn.SdkConnectionKeepAliveStrategy;
9394
import software.amazon.awssdk.http.apache5.internal.conn.SdkTlsSocketFactory;
94-
import software.amazon.awssdk.http.apache5.internal.conn.SslSocketFactoryToTlsStrategyAdapter;
9595
import software.amazon.awssdk.http.apache5.internal.impl.Apache5HttpRequestFactory;
9696
import software.amazon.awssdk.http.apache5.internal.impl.Apache5SdkHttpClient;
9797
import software.amazon.awssdk.http.apache5.internal.impl.ConnectionManagerAwareHttpClient;
@@ -461,12 +461,12 @@ public interface Builder extends SdkHttpClient.Builder<Apache5HttpClient.Builder
461461
* TLS_TRUST_MANAGERS_PROVIDER, and TLS_KEY_MANAGERS_PROVIDER are ignored.
462462
*/
463463
@Deprecated
464-
Builder socketFactory(SSLConnectionSocketFactory socketFactory);
464+
Builder socketFactory(ConnectionSocketFactory socketFactory);
465465

466466

467467
/**
468468
* Configure a custom TLS strategy for SSL/TLS connections.
469-
* This is the preferred method over the deprecated {@link #socketFactory(SSLConnectionSocketFactory)}.
469+
* This is the preferred method over the deprecated {@link #socketFactory(ConnectionSocketFactory)}.
470470
*
471471
* @param tlsSocketStrategy The TLS strategy to use for upgrading connections to TLS.
472472
* If null, default TLS configuration will be used.
@@ -532,7 +532,7 @@ private static final class DefaultBuilder implements Builder {
532532
private HttpRoutePlanner httpRoutePlanner;
533533
private CredentialsProvider credentialsProvider;
534534
private DnsResolver dnsResolver;
535-
private SSLConnectionSocketFactory legacySocketFactory;
535+
private ConnectionSocketFactory legacySocketFactory;
536536
private TlsSocketStrategy tlsStrategy;
537537

538538
private DefaultBuilder() {
@@ -655,13 +655,13 @@ public void setDnsResolver(DnsResolver dnsResolver) {
655655
}
656656

657657
@Override
658-
public Builder socketFactory(SSLConnectionSocketFactory socketFactory) {
658+
public Builder socketFactory(ConnectionSocketFactory socketFactory) {
659659
this.legacySocketFactory = socketFactory;
660660
this.tlsStrategy = null; // Clear any previously set strategy
661661
return this;
662662
}
663663

664-
public void setSocketFactory(SSLConnectionSocketFactory socketFactory) {
664+
public void setSocketFactory(ConnectionSocketFactory socketFactory) {
665665
socketFactory(socketFactory);
666666
}
667667

@@ -747,7 +747,7 @@ TlsSocketStrategy getEffectiveTlsStrategy() {
747747
return tlsStrategy;
748748
}
749749
if (legacySocketFactory != null) {
750-
return new SslSocketFactoryToTlsStrategyAdapter(legacySocketFactory);
750+
return new ConnectionSocketFactoryToTlsStrategyAdapter(legacySocketFactory);
751751
}
752752
return null;
753753
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 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.apache5.internal.conn;
17+
18+
import java.io.IOException;
19+
import java.net.Socket;
20+
import javax.net.ssl.SSLSocket;
21+
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
22+
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
23+
import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
24+
import org.apache.hc.core5.http.protocol.HttpContext;
25+
import software.amazon.awssdk.annotations.SdkInternalApi;
26+
27+
/**
28+
* Adapter to wrap ConnectionSocketFactory as TlsSocketStrategy.
29+
* Supports both plain and layered (SSL/TLS) socket factories.
30+
*/
31+
@SdkInternalApi
32+
public class ConnectionSocketFactoryToTlsStrategyAdapter implements TlsSocketStrategy {
33+
34+
private final ConnectionSocketFactory socketFactory;
35+
36+
public ConnectionSocketFactoryToTlsStrategyAdapter(ConnectionSocketFactory socketFactory) {
37+
this.socketFactory = socketFactory;
38+
}
39+
40+
@Override
41+
public SSLSocket upgrade(Socket socket,
42+
String target,
43+
int port,
44+
Object attachment,
45+
HttpContext context) throws IOException {
46+
47+
// Only LayeredConnectionSocketFactory can upgrade to SSL
48+
if (socketFactory instanceof LayeredConnectionSocketFactory) {
49+
LayeredConnectionSocketFactory layeredFactory = (LayeredConnectionSocketFactory) socketFactory;
50+
Socket upgradedSocket = layeredFactory.createLayeredSocket(socket, target, port, context);
51+
52+
if (upgradedSocket == null) {
53+
throw new IOException("LayeredConnectionSocketFactory.createLayeredSocket returned null");
54+
}
55+
if (!(upgradedSocket instanceof SSLSocket)) {
56+
throw new IOException("LayeredConnectionSocketFactory.createLayeredSocket did not return an SSLSocket. " +
57+
"Returned type: " + upgradedSocket.getClass().getName());
58+
}
59+
60+
return (SSLSocket) upgradedSocket;
61+
}
62+
63+
// For plain socket factories (like PlainConnectionSocketFactory),
64+
// we can't upgrade to TLS, but we shouldn't throw an exception
65+
// Return null to indicate no TLS upgrade is possible/needed
66+
return null;
67+
}
68+
69+
70+
}

http-clients/apache5-client/src/main/java/software/amazon/awssdk/http/apache5/internal/conn/SslSocketFactoryToTlsStrategyAdapter.java

Lines changed: 0 additions & 55 deletions
This file was deleted.

http-clients/apache5-client/src/test/java/software/amazon/awssdk/http/apache5/Apache5ClientTlsAuthTest.java

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
2121
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
2222
import static org.assertj.core.api.Assertions.assertThat;
23-
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
2423
import static org.assertj.core.api.Assertions.assertThatThrownBy;
2524
import static software.amazon.awssdk.utils.JavaSystemSetting.SSL_KEY_STORE;
2625
import static software.amazon.awssdk.utils.JavaSystemSetting.SSL_KEY_STORE_PASSWORD;
@@ -57,7 +56,6 @@
5756
import software.amazon.awssdk.http.SdkHttpRequest;
5857
import software.amazon.awssdk.http.TlsKeyManagersProvider;
5958
import software.amazon.awssdk.http.apache5.internal.conn.SdkTlsSocketFactory;
60-
import software.amazon.awssdk.http.apache5.internal.conn.SslSocketFactoryToTlsStrategyAdapter;
6159
import software.amazon.awssdk.internal.http.NoneTlsKeyManagersProvider;
6260

6361
/**
@@ -332,67 +330,4 @@ public void tls_strategy_overrides_legacy_factory() throws Exception {
332330
Mockito.verifyNoInteractions(legacyFactorySpy);
333331
}
334332

335-
@Test
336-
public void adapter_converts_non_sslSocketException() throws Exception {
337-
// Create mock that returns a regular Socket (not SSLSocket)
338-
SSLConnectionSocketFactory mockFactory = Mockito.mock(SSLConnectionSocketFactory.class);
339-
Socket nonSslSocket = Mockito.mock(Socket.class);
340-
341-
// Setup mock to return non-SSL socket
342-
Mockito.when(mockFactory.createLayeredSocket(
343-
Mockito.any(Socket.class),
344-
Mockito.eq("example.com"),
345-
Mockito.eq(443),
346-
Mockito.any()
347-
)).thenReturn(nonSslSocket);
348-
349-
// Create adapter
350-
SslSocketFactoryToTlsStrategyAdapter adapter =
351-
new SslSocketFactoryToTlsStrategyAdapter(mockFactory);
352-
353-
// Test should throw IOException
354-
Socket plainSocket = Mockito.mock(Socket.class);
355-
356-
assertThatExceptionOfType(IOException.class)
357-
.isThrownBy(() -> adapter.upgrade(plainSocket, "example.com", 443, null, null))
358-
.withMessageContaining("did not return an SSLSocket")
359-
.withMessageContaining(nonSslSocket.getClass().getName());
360-
}
361-
362-
363-
@Test
364-
public void adapter_handlesNullSocket() throws Exception {
365-
// Create mock that returns null
366-
SSLConnectionSocketFactory mockFactory = Mockito.mock(SSLConnectionSocketFactory.class);
367-
368-
Mockito.when(mockFactory.createLayeredSocket(
369-
Mockito.any(Socket.class),
370-
Mockito.anyString(),
371-
Mockito.anyInt(),
372-
Mockito.any(HttpContext.class)
373-
)).thenReturn(null);
374-
375-
// Create adapter
376-
SslSocketFactoryToTlsStrategyAdapter adapter =
377-
new SslSocketFactoryToTlsStrategyAdapter(mockFactory);
378-
379-
// Test should throw IOException
380-
Socket plainSocket = Mockito.mock(Socket.class);
381-
382-
assertThatExceptionOfType(IOException.class)
383-
.isThrownBy(() -> adapter.upgrade(plainSocket, "example.com", 443, null, null))
384-
.withMessageContaining("returned null");
385-
}
386-
387-
@Test
388-
public void null_tlsStrategy_falls_backToDefault() throws Exception {
389-
// Test that setting tlsSocketStrategy(null) works correctly
390-
client = Apache5HttpClient.builder()
391-
.tlsSocketStrategy(null)
392-
.tlsKeyManagersProvider(keyManagersProvider)
393-
.build();
394-
395-
HttpExecuteResponse response = makeRequestWithHttpClient(client);
396-
assertThat(response.httpResponse().isSuccessful()).isTrue();
397-
}
398333
}

0 commit comments

Comments
 (0)