|
|
@ -16,13 +16,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.boot.web.client;
|
|
|
|
package org.springframework.boot.web.client;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.net.URI;
|
|
|
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import java.time.Duration;
|
|
|
|
import java.time.Duration;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import javax.net.ssl.SSLHandshakeException;
|
|
|
|
|
|
|
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.boot.ssl.SslBundle;
|
|
|
|
|
|
|
|
import org.springframework.boot.ssl.SslBundleKey;
|
|
|
|
|
|
|
|
import org.springframework.boot.ssl.jks.JksSslStoreBundle;
|
|
|
|
|
|
|
|
import org.springframework.boot.ssl.jks.JksSslStoreDetails;
|
|
|
|
|
|
|
|
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
|
|
|
|
|
|
|
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
|
|
|
|
|
|
|
import org.springframework.boot.web.server.Ssl;
|
|
|
|
|
|
|
|
import org.springframework.boot.web.server.Ssl.ClientAuth;
|
|
|
|
|
|
|
|
import org.springframework.boot.web.server.WebServer;
|
|
|
|
|
|
|
|
import org.springframework.http.HttpMethod;
|
|
|
|
|
|
|
|
import org.springframework.http.client.ClientHttpRequest;
|
|
|
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
|
|
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
|
|
|
|
|
|
|
import org.springframework.util.StreamUtils;
|
|
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Base classes for testing of {@link ClientHttpRequestFactories} with different HTTP
|
|
|
|
* Base classes for testing of {@link ClientHttpRequestFactories} with different HTTP
|
|
|
@ -31,6 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
* @param <T> the {@link ClientHttpRequestFactory} to be produced
|
|
|
|
* @param <T> the {@link ClientHttpRequestFactory} to be produced
|
|
|
|
* @author Andy Wilkinson
|
|
|
|
* @author Andy Wilkinson
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
@DirtiesUrlFactories
|
|
|
|
abstract class AbstractClientHttpRequestFactoriesTests<T extends ClientHttpRequestFactory> {
|
|
|
|
abstract class AbstractClientHttpRequestFactoriesTests<T extends ClientHttpRequestFactory> {
|
|
|
|
|
|
|
|
|
|
|
|
private final Class<T> requestFactoryType;
|
|
|
|
private final Class<T> requestFactoryType;
|
|
|
@ -76,6 +94,39 @@ abstract class AbstractClientHttpRequestFactoriesTests<T extends ClientHttpReque
|
|
|
|
assertThat(readTimeout((T) requestFactory)).isEqualTo(Duration.ofSeconds(120).toMillis());
|
|
|
|
assertThat(readTimeout((T) requestFactory)).isEqualTo(Duration.ofSeconds(120).toMillis());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
|
|
|
void connectWithSslBundle() throws Exception {
|
|
|
|
|
|
|
|
TomcatServletWebServerFactory webServerFactory = new TomcatServletWebServerFactory(0);
|
|
|
|
|
|
|
|
Ssl ssl = new Ssl();
|
|
|
|
|
|
|
|
ssl.setClientAuth(ClientAuth.NEED);
|
|
|
|
|
|
|
|
ssl.setKeyPassword("password");
|
|
|
|
|
|
|
|
ssl.setKeyStore("classpath:test.jks");
|
|
|
|
|
|
|
|
ssl.setTrustStore("classpath:test.jks");
|
|
|
|
|
|
|
|
webServerFactory.setSsl(ssl);
|
|
|
|
|
|
|
|
WebServer webServer = webServerFactory.getWebServer();
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
webServer.start();
|
|
|
|
|
|
|
|
int port = webServer.getPort();
|
|
|
|
|
|
|
|
URI uri = new URI("https://localhost:%s".formatted(port));
|
|
|
|
|
|
|
|
ClientHttpRequestFactory insecureRequestFactory = ClientHttpRequestFactories
|
|
|
|
|
|
|
|
.get(ClientHttpRequestFactorySettings.DEFAULTS);
|
|
|
|
|
|
|
|
ClientHttpRequest insecureRequest = insecureRequestFactory.createRequest(uri, HttpMethod.GET);
|
|
|
|
|
|
|
|
assertThatExceptionOfType(SSLHandshakeException.class)
|
|
|
|
|
|
|
|
.isThrownBy(() -> insecureRequest.execute().getBody());
|
|
|
|
|
|
|
|
JksSslStoreDetails storeDetails = JksSslStoreDetails.forLocation("classpath:test.jks");
|
|
|
|
|
|
|
|
JksSslStoreBundle stores = new JksSslStoreBundle(storeDetails, storeDetails);
|
|
|
|
|
|
|
|
SslBundle sslBundle = SslBundle.of(stores, SslBundleKey.of("password"));
|
|
|
|
|
|
|
|
ClientHttpRequestFactory secureRequestFactory = ClientHttpRequestFactories
|
|
|
|
|
|
|
|
.get(ClientHttpRequestFactorySettings.DEFAULTS.withSslBundle(sslBundle));
|
|
|
|
|
|
|
|
ClientHttpRequest secureRequest = secureRequestFactory.createRequest(uri, HttpMethod.GET);
|
|
|
|
|
|
|
|
String secureResponse = StreamUtils.copyToString(secureRequest.execute().getBody(), StandardCharsets.UTF_8);
|
|
|
|
|
|
|
|
assertThat(secureResponse).contains("HTTP Status 404 – Not Found");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
finally {
|
|
|
|
|
|
|
|
webServer.stop();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected abstract long connectTimeout(T requestFactory);
|
|
|
|
protected abstract long connectTimeout(T requestFactory);
|
|
|
|
|
|
|
|
|
|
|
|
protected abstract long readTimeout(T requestFactory);
|
|
|
|
protected abstract long readTimeout(T requestFactory);
|
|
|
|