1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.client5.testing.external;
28
29 import java.util.Objects;
30
31 import javax.net.ssl.SSLContext;
32
33 import org.apache.hc.client5.http.auth.AuthScope;
34 import org.apache.hc.client5.http.auth.Credentials;
35 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
36 import org.apache.hc.client5.http.classic.methods.HttpGet;
37 import org.apache.hc.client5.http.classic.methods.HttpOptions;
38 import org.apache.hc.client5.http.config.RequestConfig;
39 import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
40 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
41 import org.apache.hc.client5.http.impl.classic.HttpClients;
42 import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
43 import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
44 import org.apache.hc.client5.http.protocol.HttpClientContext;
45 import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
46 import org.apache.hc.core5.http.ClassicHttpResponse;
47 import org.apache.hc.core5.http.HeaderElements;
48 import org.apache.hc.core5.http.HttpHeaders;
49 import org.apache.hc.core5.http.HttpHost;
50 import org.apache.hc.core5.http.HttpRequest;
51 import org.apache.hc.core5.http.HttpStatus;
52 import org.apache.hc.core5.http.io.entity.EntityUtils;
53 import org.apache.hc.core5.ssl.SSLContexts;
54 import org.apache.hc.core5.util.TextUtils;
55 import org.apache.hc.core5.util.TimeValue;
56
57 public class HttpClientCompatibilityTest {
58
59 public static void main(final String... args) throws Exception {
60 final HttpClientCompatibilityTestlientCompatibilityTest.html#HttpClientCompatibilityTest">HttpClientCompatibilityTest[] tests = new HttpClientCompatibilityTest[] {
61 new HttpClientCompatibilityTest(
62 new HttpHost("http", "localhost", 8080), null, null),
63 new HttpClientCompatibilityTest(
64 new HttpHost("http", "test-httpd", 8080), new HttpHost("localhost", 8888), null),
65 new HttpClientCompatibilityTest(
66 new HttpHost("http", "test-httpd", 8080), new HttpHost("localhost", 8889),
67 new UsernamePasswordCredentials("squid", "nopassword".toCharArray())),
68 new HttpClientCompatibilityTest(
69 new HttpHost("https", "localhost", 8443), null, null),
70 new HttpClientCompatibilityTest(
71 new HttpHost("https", "test-httpd", 8443), new HttpHost("localhost", 8888), null),
72 new HttpClientCompatibilityTest(
73 new HttpHost("https", "test-httpd", 8443), new HttpHost("localhost", 8889),
74 new UsernamePasswordCredentials("squid", "nopassword".toCharArray()))
75 };
76 for (final HttpClientCompatibilityTest test: tests) {
77 try {
78 test.execute();
79 } finally {
80 test.shutdown();
81 }
82 }
83 }
84
85 private final HttpHost target;
86 private final HttpHost proxy;
87 private final BasicCredentialsProvider credentialsProvider;
88 private final PoolingHttpClientConnectionManager connManager;
89 private final CloseableHttpClient client;
90
91 HttpClientCompatibilityTest(
92 final HttpHost target,
93 final HttpHost proxy,
94 final Credentials proxyCreds) throws Exception {
95 this.target = target;
96 this.proxy = proxy;
97 this.credentialsProvider = new BasicCredentialsProvider();
98 final RequestConfig requestConfig = RequestConfig.custom()
99 .setProxy(proxy)
100 .build();
101 if (proxy != null && proxyCreds != null) {
102 this.credentialsProvider.setCredentials(new AuthScope(proxy), proxyCreds);
103 }
104 final SSLContext sslContext = SSLContexts.custom()
105 .loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build();
106 this.connManager = PoolingHttpClientConnectionManagerBuilder.create()
107 .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext))
108 .build();
109 this.client = HttpClients.custom()
110 .setConnectionManager(this.connManager)
111 .setDefaultRequestConfig(requestConfig)
112 .build();
113 }
114
115 void shutdown() throws Exception {
116 client.close();
117 }
118
119 enum TestResult {OK, NOK}
120
121 private void logResult(final TestResult result, final HttpRequest request, final String message) {
122 final StringBuilder buf = new StringBuilder();
123 buf.append(result);
124 if (buf.length() == 2) {
125 buf.append(" ");
126 }
127 buf.append(": ").append(target);
128 if (proxy != null) {
129 buf.append(" via ").append(proxy);
130 }
131 buf.append(": ");
132 buf.append(request.getMethod()).append(" ").append(request.getRequestUri());
133 if (message != null && !TextUtils.isBlank(message)) {
134 buf.append(" -> ").append(message);
135 }
136 System.out.println(buf);
137 }
138
139 void execute() {
140
141
142 {
143 final HttpClientContext context = HttpClientContext.create();
144 context.setCredentialsProvider(credentialsProvider);
145 final HttpOptions options = new HttpOptions("*");
146 try (ClassicHttpResponse response = client.execute(target, options, context)) {
147 final int code = response.getCode();
148 EntityUtils.consume(response.getEntity());
149 if (code == HttpStatus.SC_OK) {
150 logResult(TestResult.OK, options, Objects.toString(response.getFirstHeader("server")));
151 } else {
152 logResult(TestResult.NOK, options, "(status " + code + ")");
153 }
154 } catch (final Exception ex) {
155 logResult(TestResult.NOK, options, "(" + ex.getMessage() + ")");
156 }
157 }
158
159 {
160 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
161 final HttpClientContext context = HttpClientContext.create();
162 context.setCredentialsProvider(credentialsProvider);
163 final String[] requestUris = new String[] {"/", "/news.html", "/status.html"};
164 for (final String requestUri: requestUris) {
165 final HttpGet httpGet = new HttpGet(requestUri);
166 try (ClassicHttpResponse response = client.execute(target, httpGet, context)) {
167 final int code = response.getCode();
168 EntityUtils.consume(response.getEntity());
169 if (code == HttpStatus.SC_OK) {
170 logResult(TestResult.OK, httpGet, "200");
171 } else {
172 logResult(TestResult.NOK, httpGet, "(status " + code + ")");
173 }
174 } catch (final Exception ex) {
175 logResult(TestResult.NOK, httpGet, "(" + ex.getMessage() + ")");
176 }
177 }
178 }
179
180 {
181 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
182 credentialsProvider.setCredentials(
183 new AuthScope("http", "otherhost", -1, "Restricted Files", null),
184 new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
185 final HttpClientContext context = HttpClientContext.create();
186 context.setCredentialsProvider(credentialsProvider);
187
188 final HttpGet httpGetSecret = new HttpGet("/private/big-secret.txt");
189 try (ClassicHttpResponse response = client.execute(target, httpGetSecret, context)) {
190 final int code = response.getCode();
191 EntityUtils.consume(response.getEntity());
192 if (code == HttpStatus.SC_UNAUTHORIZED) {
193 logResult(TestResult.OK, httpGetSecret, "401 (wrong target auth scope)");
194 } else {
195 logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
196 }
197 } catch (final Exception ex) {
198 logResult(TestResult.NOK, httpGetSecret, "(" + ex.getMessage() + ")");
199 }
200 }
201
202 {
203 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
204 credentialsProvider.setCredentials(
205 new AuthScope(target),
206 new UsernamePasswordCredentials("testuser", "wrong password".toCharArray()));
207 final HttpClientContext context = HttpClientContext.create();
208 context.setCredentialsProvider(credentialsProvider);
209
210 final HttpGet httpGetSecret = new HttpGet("/private/big-secret.txt");
211 try (ClassicHttpResponse response = client.execute(target, httpGetSecret, context)) {
212 final int code = response.getCode();
213 EntityUtils.consume(response.getEntity());
214 if (code == HttpStatus.SC_UNAUTHORIZED) {
215 logResult(TestResult.OK, httpGetSecret, "401 (wrong target creds)");
216 } else {
217 logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
218 }
219 } catch (final Exception ex) {
220 logResult(TestResult.NOK, httpGetSecret, "(" + ex.getMessage() + ")");
221 }
222 }
223
224 {
225 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
226 credentialsProvider.setCredentials(
227 new AuthScope(target),
228 new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
229 final HttpClientContext context = HttpClientContext.create();
230 context.setCredentialsProvider(credentialsProvider);
231
232 final HttpGet httpGetSecret = new HttpGet("/private/big-secret.txt");
233 try (ClassicHttpResponse response = client.execute(target, httpGetSecret, context)) {
234 final int code = response.getCode();
235 EntityUtils.consume(response.getEntity());
236 if (code == HttpStatus.SC_OK) {
237 logResult(TestResult.OK, httpGetSecret, "200 (correct target creds)");
238 } else {
239 logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
240 }
241 } catch (final Exception ex) {
242 logResult(TestResult.NOK, httpGetSecret, "(" + ex.getMessage() + ")");
243 }
244 }
245
246 {
247 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
248 credentialsProvider.setCredentials(
249 new AuthScope(target),
250 new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
251 final HttpClientContext context = HttpClientContext.create();
252 context.setCredentialsProvider(credentialsProvider);
253
254 final HttpGet httpGetSecret = new HttpGet("/private/big-secret.txt");
255 httpGetSecret.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
256 try (ClassicHttpResponse response = client.execute(target, httpGetSecret, context)) {
257 final int code = response.getCode();
258 EntityUtils.consume(response.getEntity());
259 if (code == HttpStatus.SC_OK) {
260 logResult(TestResult.OK, httpGetSecret, "200 (correct target creds / no keep-alive)");
261 } else {
262 logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
263 }
264 } catch (final Exception ex) {
265 logResult(TestResult.NOK, httpGetSecret, "(" + ex.getMessage() + ")");
266 }
267 }
268 }
269
270 }