1 package com.atlassian.httpclient.apache.httpcomponents;
2
3 import com.atlassian.httpclient.api.BannedHostException;
4 import com.atlassian.httpclient.api.HttpClient;
5 import com.atlassian.httpclient.api.factory.HttpClientOptions;
6 import com.atlassian.httpclient.api.factory.ProxyOptions;
7 import com.google.common.collect.ImmutableList;
8 import com.sun.net.httpserver.HttpExchange;
9 import com.sun.net.httpserver.HttpHandler;
10 import com.sun.net.httpserver.HttpsConfigurator;
11 import com.sun.net.httpserver.HttpsServer;
12 import org.junit.After;
13 import org.junit.Before;
14 import org.junit.Rule;
15 import org.junit.Test;
16 import org.junit.rules.ExpectedException;
17
18 import javax.net.ssl.KeyManagerFactory;
19 import javax.net.ssl.SSLContext;
20 import javax.net.ssl.SSLHandshakeException;
21 import javax.net.ssl.TrustManagerFactory;
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.net.InetSocketAddress;
25 import java.security.*;
26 import java.security.cert.CertificateException;
27
28 import static org.hamcrest.Matchers.isA;
29 import static org.junit.Assert.assertEquals;
30
31 public final class ApacheAsyncHttpClientTest {
32 private HttpsServer server;
33
34 private int port;
35
36 @Rule
37 public ExpectedException expectedException = ExpectedException.none();
38
39 @Before
40 public void setUp() throws Exception {
41 server = HttpsServer.create(new InetSocketAddress(0), 0);
42 port = server.getAddress().getPort();
43 server.setHttpsConfigurator(new HttpsConfigurator(getSslContext()));
44 server.createContext("/", new NoOpHandler());
45 server.setExecutor(null);
46 server.start();
47 }
48
49 @After
50 public void tearDown() throws Exception {
51 if (server != null) {
52 server.stop(3);
53 }
54 }
55
56 @Test
57 public void testGetWhenNotTrustingSelfSignedCertificates() {
58 HttpClientOptions options = new HttpClientOptions();
59 options.setTrustSelfSignedCertificates(false);
60 final HttpClient httpClient = new ApacheAsyncHttpClient<Void>("not-trusty-client", options);
61 try {
62 httpClient.newRequest(serverUrl()).get().claim();
63 } catch (RuntimeException expected) {
64 assertEquals(SSLHandshakeException.class, expected.getCause().getClass());
65 }
66 }
67
68 @Test
69 public void testGoingToAWSEndpoint() {
70 HttpClientOptions options = new HttpClientOptions();
71 options.setTrustSelfSignedCertificates(true);
72 options.setHostResolver(new BannedHostResolver(
73 ImmutableList.of("169.0.0.0/8")
74 ));
75
76 final HttpClient client = new ApacheAsyncHttpClient<>("trust-client", options);
77
78
79 client.newRequest(serverUrl()).get().claim();
80 expectedException.expectCause(isA(BannedHostException.class));
81 client.newRequest("http://169.254.169.254").get().claim();
82 }
83
84 @Test
85 public void testGetWhenTrustingSelfSignedCertificates() {
86 HttpClientOptions options = new HttpClientOptions();
87 options.setTrustSelfSignedCertificates(true);
88 final HttpClient httpClient = new ApacheAsyncHttpClient<Void>("trusty-client", options);
89 httpClient.newRequest(serverUrl()).get().claim();
90 }
91
92 @Test
93 public void testGetWithoutAProxy() {
94 HttpClientOptions options = new HttpClientOptions();
95 options.setProxyOptions(ProxyOptions.ProxyOptionsBuilder.create().withNoProxy().build());
96 options.setTrustSelfSignedCertificates(true);
97 final HttpClient httpClient = new ApacheAsyncHttpClient<Void>("trusty-client", options);
98 httpClient.newRequest(serverUrl()).get().claim();
99 }
100
101 private SSLContext getSslContext() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
102 char[] passphrase = "password".toCharArray();
103 KeyStore ks = KeyStore.getInstance("JKS");
104 ks.load(this.getClass().getResourceAsStream("/keystore.jks"), passphrase);
105
106 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
107 kmf.init(ks, passphrase);
108
109 TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
110 tmf.init(ks);
111
112 SSLContext ssl = SSLContext.getInstance("TLS");
113 ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
114 return ssl;
115 }
116
117 private final class NoOpHandler implements HttpHandler {
118 public void handle(HttpExchange t) throws IOException {
119 String response = "This is the response";
120 t.sendResponseHeaders(200, response.length());
121 OutputStream os = t.getResponseBody();
122 os.write(response.getBytes());
123 os.close();
124 }
125 }
126
127 private String serverUrl() {
128 return String.format("https://localhost:%d/", port);
129 }
130 }