Upgrade to HttpClient5 5.4
Closes gh-42675
This commit is contained in:
@@ -18,9 +18,8 @@ package org.springframework.boot.buildpack.platform.docker.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.sun.jna.Platform;
|
||||
import org.apache.hc.client5.http.DnsResolver;
|
||||
@@ -30,12 +29,11 @@ import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||
import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager;
|
||||
import org.apache.hc.client5.http.impl.io.DefaultHttpClientConnectionOperator;
|
||||
import org.apache.hc.client5.http.io.DetachedSocketFactory;
|
||||
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||
import org.apache.hc.client5.http.routing.HttpRoutePlanner;
|
||||
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.config.Registry;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
||||
@@ -48,6 +46,7 @@ import org.springframework.boot.buildpack.platform.socket.UnixDomainSocket;
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Scott Frederick
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
final class LocalHttpClientTransport extends HttpClientTransport {
|
||||
|
||||
@@ -62,9 +61,9 @@ final class LocalHttpClientTransport extends HttpClientTransport {
|
||||
}
|
||||
|
||||
static LocalHttpClientTransport create(ResolvedDockerHost dockerHost) {
|
||||
HttpClientBuilder builder = HttpClients.custom();
|
||||
builder.setConnectionManager(new LocalConnectionManager(dockerHost.getAddress()));
|
||||
builder.setRoutePlanner(new LocalRoutePlanner());
|
||||
HttpClientBuilder builder = HttpClients.custom()
|
||||
.setConnectionManager(new LocalConnectionManager(dockerHost))
|
||||
.setRoutePlanner(new LocalRoutePlanner());
|
||||
HttpHost host = new HttpHost(DOCKER_SCHEME, dockerHost.getAddress());
|
||||
return new LocalHttpClientTransport(builder.build(), host);
|
||||
}
|
||||
@@ -78,15 +77,34 @@ final class LocalHttpClientTransport extends HttpClientTransport {
|
||||
.setValidateAfterInactivity(TimeValue.NEG_ONE_MILLISECOND)
|
||||
.build();
|
||||
|
||||
LocalConnectionManager(String host) {
|
||||
super(getRegistry(host), null, null, new LocalDnsResolver());
|
||||
LocalConnectionManager(ResolvedDockerHost dockerHost) {
|
||||
super(new DefaultHttpClientConnectionOperator(new LocalDetachedSocketFactory(dockerHost), null,
|
||||
new LocalDnsResolver(), (name) -> null), null);
|
||||
setConnectionConfig(CONNECTION_CONFIG);
|
||||
}
|
||||
|
||||
private static Registry<ConnectionSocketFactory> getRegistry(String host) {
|
||||
RegistryBuilder<ConnectionSocketFactory> builder = RegistryBuilder.create();
|
||||
builder.register(DOCKER_SCHEME, new LocalConnectionSocketFactory(host));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link DetachedSocketFactory} for local Docker.
|
||||
*/
|
||||
static class LocalDetachedSocketFactory implements DetachedSocketFactory {
|
||||
|
||||
private static final String NPIPE_PREFIX = "npipe://";
|
||||
|
||||
private final ResolvedDockerHost dockerHost;
|
||||
|
||||
LocalDetachedSocketFactory(ResolvedDockerHost dockerHost) {
|
||||
this.dockerHost = dockerHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket create(Proxy proxy) throws IOException {
|
||||
String address = this.dockerHost.getAddress();
|
||||
if (address.startsWith(NPIPE_PREFIX)) {
|
||||
return NamedPipeSocket.get(address.substring(NPIPE_PREFIX.length()));
|
||||
}
|
||||
return (!Platform.isWindows()) ? UnixDomainSocket.get(address) : NamedPipeSocket.get(address);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -99,48 +117,17 @@ final class LocalHttpClientTransport extends HttpClientTransport {
|
||||
private static final InetAddress LOOPBACK = InetAddress.getLoopbackAddress();
|
||||
|
||||
@Override
|
||||
public InetAddress[] resolve(String host) throws UnknownHostException {
|
||||
public InetAddress[] resolve(String host) {
|
||||
return new InetAddress[] { LOOPBACK };
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveCanonicalHostname(String host) throws UnknownHostException {
|
||||
public String resolveCanonicalHostname(String host) {
|
||||
return LOOPBACK.getCanonicalHostName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ConnectionSocketFactory} that connects to the local Docker domain socket or
|
||||
* named pipe.
|
||||
*/
|
||||
private static class LocalConnectionSocketFactory implements ConnectionSocketFactory {
|
||||
|
||||
private static final String NPIPE_PREFIX = "npipe://";
|
||||
|
||||
private final String host;
|
||||
|
||||
LocalConnectionSocketFactory(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(HttpContext context) throws IOException {
|
||||
if (this.host.startsWith(NPIPE_PREFIX)) {
|
||||
return NamedPipeSocket.get(this.host.substring(NPIPE_PREFIX.length()));
|
||||
}
|
||||
return (!Platform.isWindows()) ? UnixDomainSocket.get(this.host) : NamedPipeSocket.get(this.host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket connectSocket(TimeValue connectTimeout, Socket socket, HttpHost host,
|
||||
InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpContext context)
|
||||
throws IOException {
|
||||
return socket;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link HttpRoutePlanner} for local Docker.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,8 +25,8 @@ import org.apache.hc.client5.http.classic.HttpClient;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
|
||||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||
import org.apache.hc.client5.http.ssl.TlsSocketStrategy;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.io.SocketConfig;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
@@ -74,7 +74,7 @@ final class RemoteHttpClientTransport extends HttpClientTransport {
|
||||
.create()
|
||||
.setDefaultSocketConfig(socketConfig);
|
||||
if (host.isSecure()) {
|
||||
connectionManagerBuilder.setSSLSocketFactory(getSecureConnectionSocketFactory(host, sslContextFactory));
|
||||
connectionManagerBuilder.setTlsSocketStrategy(getTlsSocketStrategy(host, sslContextFactory));
|
||||
}
|
||||
HttpClientBuilder builder = HttpClients.custom();
|
||||
builder.setConnectionManager(connectionManagerBuilder.build());
|
||||
@@ -83,13 +83,12 @@ final class RemoteHttpClientTransport extends HttpClientTransport {
|
||||
return new RemoteHttpClientTransport(builder.build(), httpHost);
|
||||
}
|
||||
|
||||
private static LayeredConnectionSocketFactory getSecureConnectionSocketFactory(DockerHost host,
|
||||
SslContextFactory sslContextFactory) {
|
||||
private static TlsSocketStrategy getTlsSocketStrategy(DockerHost host, SslContextFactory sslContextFactory) {
|
||||
String directory = host.getCertificatePath();
|
||||
Assert.hasText(directory,
|
||||
() -> "Docker host TLS verification requires trust material location to be specified with certificate path");
|
||||
SSLContext sslContext = sslContextFactory.forDirectory(directory);
|
||||
return new SSLConnectionSocketFactory(sslContext);
|
||||
return new DefaultClientTlsStrategy(sslContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user