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 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.DEFAULT;
99 if (proxy != null && proxyCreds != null) {
100 this.credentialsProvider.setCredentials(new AuthScope(proxy), proxyCreds);
101 }
102 final SSLContext sslContext = SSLContexts.custom()
103 .loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build();
104 this.connManager = PoolingHttpClientConnectionManagerBuilder.create()
105 .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext))
106 .build();
107 this.client = HttpClients.custom()
108 .setConnectionManager(this.connManager)
109 .setProxy(this.proxy)
110 .setDefaultRequestConfig(requestConfig)
111 .build();
112 }
113
114 void shutdown() throws Exception {
115 client.close();
116 }
117
118 enum TestResult {OK, NOK}
119
120 private void logResult(final TestResult result, final HttpRequest request, final String message) {
121 final StringBuilder buf = new StringBuilder();
122 buf.append(result);
123 if (buf.length() == 2) {
124 buf.append(" ");
125 }
126 buf.append(": ").append(target);
127 if (proxy != null) {
128 buf.append(" via ").append(proxy);
129 }
130 buf.append(": ");
131 buf.append(request.getMethod()).append(" ").append(request.getRequestUri());
132 if (message != null && !TextUtils.isBlank(message)) {
133 buf.append(" -> ").append(message);
134 }
135 System.out.println(buf);
136 }
137
138 void execute() {
139
140
141 {
142 final HttpClientContext context = HttpClientContext.create();
143 context.setCredentialsProvider(credentialsProvider);
144 final HttpOptions options = new HttpOptions("*");
145 try (ClassicHttpResponse response = client.executeOpen(target, options, context)) {
146 final int code = response.getCode();
147 EntityUtils.consume(response.getEntity());
148 if (code == HttpStatus.SC_OK) {
149 logResult(TestResult.OK, options, Objects.toString(response.getFirstHeader("server")));
150 } else {
151 logResult(TestResult.NOK, options, "(status " + code + ")");
152 }
153 } catch (final Exception ex) {
154 logResult(TestResult.NOK, options, "(" + ex.getMessage() + ")");
155 }
156 }
157
158 {
159 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
160 final HttpClientContext context = HttpClientContext.create();
161 context.setCredentialsProvider(credentialsProvider);
162 final String[] requestUris = new String[] {"/", "/news.html", "/status.html"};
163 for (final String requestUri: requestUris) {
164 final HttpGet httpGet = new HttpGet(requestUri);
165 try (ClassicHttpResponse response = client.executeOpen(target, httpGet, context)) {
166 final int code = response.getCode();
167 EntityUtils.consume(response.getEntity());
168 if (code == HttpStatus.SC_OK) {
169 logResult(TestResult.OK, httpGet, "200");
170 } else {
171 logResult(TestResult.NOK, httpGet, "(status " + code + ")");
172 }
173 } catch (final Exception ex) {
174 logResult(TestResult.NOK, httpGet, "(" + ex.getMessage() + ")");
175 }
176 }
177 }
178
179 {
180 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
181 credentialsProvider.setCredentials(
182 new AuthScope("http", "otherhost", -1, "Restricted Files", null),
183 new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
184 final HttpClientContext context = HttpClientContext.create();
185 context.setCredentialsProvider(credentialsProvider);
186
187 final HttpGet httpGetSecret = new HttpGet("/private/big-secret.txt");
188 try (ClassicHttpResponse response = client.executeOpen(target, httpGetSecret, context)) {
189 final int code = response.getCode();
190 EntityUtils.consume(response.getEntity());
191 if (code == HttpStatus.SC_UNAUTHORIZED) {
192 logResult(TestResult.OK, httpGetSecret, "401 (wrong target auth scope)");
193 } else {
194 logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
195 }
196 } catch (final Exception ex) {
197 logResult(TestResult.NOK, httpGetSecret, "(" + ex.getMessage() + ")");
198 }
199 }
200
201 {
202 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
203 credentialsProvider.setCredentials(
204 new AuthScope(target),
205 new UsernamePasswordCredentials("testuser", "wrong password".toCharArray()));
206 final HttpClientContext context = HttpClientContext.create();
207 context.setCredentialsProvider(credentialsProvider);
208
209 final HttpGet httpGetSecret = new HttpGet("/private/big-secret.txt");
210 try (ClassicHttpResponse response = client.executeOpen(target, httpGetSecret, context)) {
211 final int code = response.getCode();
212 EntityUtils.consume(response.getEntity());
213 if (code == HttpStatus.SC_UNAUTHORIZED) {
214 logResult(TestResult.OK, httpGetSecret, "401 (wrong target creds)");
215 } else {
216 logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
217 }
218 } catch (final Exception ex) {
219 logResult(TestResult.NOK, httpGetSecret, "(" + ex.getMessage() + ")");
220 }
221 }
222
223 {
224 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
225 credentialsProvider.setCredentials(
226 new AuthScope(target),
227 new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
228 final HttpClientContext context = HttpClientContext.create();
229 context.setCredentialsProvider(credentialsProvider);
230
231 final HttpGet httpGetSecret = new HttpGet("/private/big-secret.txt");
232 try (ClassicHttpResponse response = client.executeOpen(target, httpGetSecret, context)) {
233 final int code = response.getCode();
234 EntityUtils.consume(response.getEntity());
235 if (code == HttpStatus.SC_OK) {
236 logResult(TestResult.OK, httpGetSecret, "200 (correct target creds)");
237 } else {
238 logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
239 }
240 } catch (final Exception ex) {
241 logResult(TestResult.NOK, httpGetSecret, "(" + ex.getMessage() + ")");
242 }
243 }
244
245 {
246 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
247 credentialsProvider.setCredentials(
248 new AuthScope(target),
249 new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
250 final HttpClientContext context = HttpClientContext.create();
251 context.setCredentialsProvider(credentialsProvider);
252
253 final HttpGet httpGetSecret = new HttpGet("/private/big-secret.txt");
254 httpGetSecret.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
255 try (ClassicHttpResponse response = client.executeOpen(target, httpGetSecret, context)) {
256 final int code = response.getCode();
257 EntityUtils.consume(response.getEntity());
258 if (code == HttpStatus.SC_OK) {
259 logResult(TestResult.OK, httpGetSecret, "200 (correct target creds / no keep-alive)");
260 } else {
261 logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
262 }
263 } catch (final Exception ex) {
264 logResult(TestResult.NOK, httpGetSecret, "(" + ex.getMessage() + ")");
265 }
266 }
267 }
268
269 }