|
16 | 16 |
|
17 | 17 | package sample.tomcat.http2;
|
18 | 18 |
|
| 19 | +import java.security.KeyManagementException; |
| 20 | +import java.security.NoSuchAlgorithmException; |
| 21 | +import java.security.SecureRandom; |
| 22 | +import java.security.cert.CertificateException; |
| 23 | +import java.security.cert.X509Certificate; |
| 24 | +import java.util.Arrays; |
| 25 | + |
| 26 | +import javax.net.ssl.HostnameVerifier; |
| 27 | +import javax.net.ssl.SSLContext; |
| 28 | +import javax.net.ssl.TrustManager; |
| 29 | +import javax.net.ssl.X509TrustManager; |
| 30 | + |
| 31 | +import okhttp3.OkHttpClient; |
| 32 | +import okhttp3.Protocol; |
| 33 | +import okhttp3.Request; |
| 34 | +import okhttp3.Response; |
| 35 | +import org.junit.Before; |
| 36 | +import org.junit.Ignore; |
19 | 37 | import org.junit.Test;
|
20 | 38 | import org.junit.runner.RunWith;
|
21 | 39 |
|
22 |
| -import org.springframework.beans.factory.annotation.Autowired; |
23 | 40 | import org.springframework.boot.test.context.SpringBootTest;
|
24 | 41 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
25 |
| -import org.springframework.boot.test.web.client.TestRestTemplate; |
| 42 | +import org.springframework.boot.web.server.LocalServerPort; |
26 | 43 | import org.springframework.http.HttpStatus;
|
27 |
| -import org.springframework.http.ResponseEntity; |
28 | 44 | import org.springframework.test.annotation.DirtiesContext;
|
29 | 45 | import org.springframework.test.context.junit4.SpringRunner;
|
30 | 46 |
|
31 | 47 | import static org.assertj.core.api.Assertions.assertThat;
|
32 | 48 |
|
| 49 | +/** |
| 50 | + * Basic integration tests for sample application that verify HTTP/1.1 and HTTP/2 support. |
| 51 | + * |
| 52 | + * @author Paul Vorbach |
| 53 | + */ |
33 | 54 | @RunWith(SpringRunner.class)
|
34 | 55 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
35 | 56 | @DirtiesContext
|
36 | 57 | public class SampleTomcatHttp2ApplicationTests {
|
37 | 58 |
|
38 |
| - @Autowired |
39 |
| - private TestRestTemplate restTemplate; |
| 59 | + @LocalServerPort |
| 60 | + private int port; |
| 61 | + |
| 62 | + private OkHttpClient okHttp11Client; |
| 63 | + private OkHttpClient okHttp2Client; |
| 64 | + |
| 65 | + @Before |
| 66 | + public void setUp() throws Exception { |
| 67 | + this.okHttp11Client = createInsecureOkHttpClient(Protocol.HTTP_1_1); |
| 68 | + this.okHttp2Client = createInsecureOkHttpClient(Protocol.HTTP_1_1, Protocol.HTTP_2); |
| 69 | + } |
| 70 | + |
| 71 | + @Test |
| 72 | + public void testHttp11() throws Exception { |
| 73 | + final Request request = new Request.Builder() |
| 74 | + .url(String.format("https://localhost:%d/", port)) |
| 75 | + .build(); |
| 76 | + |
| 77 | + final Response response = okHttp11Client.newCall(request).execute(); |
40 | 78 |
|
| 79 | + assertThat(response.protocol()).isEqualTo(Protocol.HTTP_1_1); |
| 80 | + assertThat(response.code()).isEqualTo(HttpStatus.OK.value()); |
| 81 | + assertThat(response.body().string()).isEqualTo("Hello, world"); |
| 82 | + } |
| 83 | + |
| 84 | + /** |
| 85 | + * Tests that the server has HTTP/2 enabled. |
| 86 | + * <p> |
| 87 | + * This only works when both tomcat-native is in PATH <em>and</em> it is running on |
| 88 | + * Java 9, since OkHttp makes use of Java 9's support for ALPN. |
| 89 | + */ |
| 90 | + @Ignore |
41 | 91 | @Test
|
42 |
| - public void testHome() throws Exception { |
43 |
| - ResponseEntity<String> entity = this.restTemplate.getForEntity("/", String.class); |
44 |
| - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); |
45 |
| - assertThat(entity.getBody()).isEqualTo("Hello, world"); |
| 92 | + public void testHttp2() throws Exception { |
| 93 | + final Request request = new Request.Builder() |
| 94 | + .url(String.format("https://localhost:%d/", port)) |
| 95 | + .build(); |
| 96 | + |
| 97 | + final Response response = okHttp2Client.newCall(request).execute(); |
| 98 | + |
| 99 | + assertThat(response.protocol()).isEqualTo(Protocol.HTTP_2); |
| 100 | + assertThat(response.code()).isEqualTo(HttpStatus.OK.value()); |
| 101 | + assertThat(response.body().string()).isEqualTo("Hello, world"); |
| 102 | + } |
| 103 | + |
| 104 | + private static OkHttpClient createInsecureOkHttpClient(Protocol... supportedProtocols) |
| 105 | + throws NoSuchAlgorithmException, KeyManagementException { |
| 106 | + |
| 107 | + final HostnameVerifier acceptAllHostnamesVerifier = (hostname, sslSession) -> true; |
| 108 | + final InsecureTrustManager insecureTrustManager = new InsecureTrustManager(); |
| 109 | + final SSLContext sslContext = createSslContext(insecureTrustManager); |
| 110 | + |
| 111 | + return new OkHttpClient.Builder() |
| 112 | + .protocols(Arrays.asList(supportedProtocols)) |
| 113 | + .hostnameVerifier(acceptAllHostnamesVerifier) |
| 114 | + .sslSocketFactory(sslContext.getSocketFactory(), insecureTrustManager) |
| 115 | + .build(); |
| 116 | + } |
| 117 | + |
| 118 | + private static SSLContext createSslContext(TrustManager trustManager) |
| 119 | + throws KeyManagementException, NoSuchAlgorithmException { |
| 120 | + |
| 121 | + final SSLContext sslContext = SSLContext.getInstance("TLSv1"); |
| 122 | + |
| 123 | + sslContext.init(null, new TrustManager[] { trustManager }, new SecureRandom()); |
| 124 | + |
| 125 | + return sslContext; |
| 126 | + } |
| 127 | + |
| 128 | + private static class InsecureTrustManager implements X509TrustManager { |
| 129 | + |
| 130 | + @Override |
| 131 | + public void checkClientTrusted(X509Certificate[] chain, String authType) |
| 132 | + throws CertificateException { |
| 133 | + } |
| 134 | + |
| 135 | + @Override |
| 136 | + public void checkServerTrusted(X509Certificate[] chain, String authType) |
| 137 | + throws CertificateException { |
| 138 | + } |
| 139 | + |
| 140 | + @Override |
| 141 | + public X509Certificate[] getAcceptedIssuers() { |
| 142 | + return new X509Certificate[] {}; |
| 143 | + } |
46 | 144 | }
|
47 | 145 |
|
48 | 146 | }
|
0 commit comments