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.cache.CacheResponseStatus;
34 import org.apache.hc.client5.http.cache.HttpCacheContext;
35 import org.apache.hc.client5.http.classic.methods.HttpGet;
36 import org.apache.hc.client5.http.classic.methods.HttpOptions;
37 import org.apache.hc.client5.http.impl.cache.CacheConfig;
38 import org.apache.hc.client5.http.impl.cache.CachingHttpClients;
39 import org.apache.hc.client5.http.impl.cache.HeapResourceFactory;
40 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
41 import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
42 import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
43 import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
44 import org.apache.hc.core5.http.ClassicHttpResponse;
45 import org.apache.hc.core5.http.HttpHeaders;
46 import org.apache.hc.core5.http.HttpHost;
47 import org.apache.hc.core5.http.HttpRequest;
48 import org.apache.hc.core5.http.HttpStatus;
49 import org.apache.hc.core5.http.io.entity.EntityUtils;
50 import org.apache.hc.core5.ssl.SSLContexts;
51 import org.apache.hc.core5.util.TextUtils;
52 import org.apache.hc.core5.util.TimeValue;
53
54 public class CachingHttpClientCompatibilityTest {
55
56 public static void main(final String... args) throws Exception {
57 final CachingHttpClientCompatibilityTest[] tests = new CachingHttpClientCompatibilityTest[] {
58 new CachingHttpClientCompatibilityTest(
59 new HttpHost("http", "localhost", 8080))
60 };
61 for (final CachingHttpClientCompatibilityTest test: tests) {
62 try {
63 test.execute();
64 } finally {
65 test.shutdown();
66 }
67 }
68 }
69
70 private final HttpHost target;
71 private final PoolingHttpClientConnectionManager connManager;
72 private final CloseableHttpClient client;
73
74 CachingHttpClientCompatibilityTest(final HttpHost target) throws Exception {
75 this.target = target;
76 final SSLContext sslContext = SSLContexts.custom()
77 .loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build();
78 this.connManager = PoolingHttpClientConnectionManagerBuilder.create()
79 .setTlsSocketStrategy(new DefaultClientTlsStrategy(sslContext))
80 .build();
81 this.client = CachingHttpClients.custom()
82 .setCacheConfig(CacheConfig.custom()
83 .setMaxObjectSize(20480)
84 .setHeuristicCachingEnabled(true)
85 .build())
86 .setResourceFactory(HeapResourceFactory.INSTANCE)
87 .setConnectionManager(this.connManager)
88 .build();
89 }
90
91 void shutdown() throws Exception {
92 client.close();
93 }
94
95 enum TestResult {OK, NOK}
96
97 private void logResult(final TestResult result, final HttpRequest request, final String message) {
98 final StringBuilder buf = new StringBuilder();
99 buf.append(result);
100 if (buf.length() == 2) {
101 buf.append(" ");
102 }
103 buf.append(": ").append(target);
104 buf.append(": ");
105 buf.append(request.getMethod()).append(" ").append(request.getRequestUri());
106 if (message != null && !TextUtils.isBlank(message)) {
107 buf.append(" -> ").append(message);
108 }
109 System.out.println(buf);
110 }
111
112 void execute() throws InterruptedException {
113
114
115 {
116 final HttpCacheContext context = HttpCacheContext.create();
117 final HttpOptions options = new HttpOptions("*");
118 try (final ClassicHttpResponse response = client.executeOpen(target, options, context)) {
119 final int code = response.getCode();
120 EntityUtils.consume(response.getEntity());
121 if (code == HttpStatus.SC_OK) {
122 logResult(TestResult.OK, options, Objects.toString(response.getFirstHeader("server")));
123 } else {
124 logResult(TestResult.NOK, options, "(status " + code + ")");
125 }
126 } catch (final Exception ex) {
127 logResult(TestResult.NOK, options, "(" + ex.getMessage() + ")");
128 }
129 }
130
131 {
132 connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND);
133
134 final String[] links = {"/", "/css/hc-maven.css", "/images/logos/httpcomponents.png"};
135
136 final HttpCacheContext context = HttpCacheContext.create();
137 for (final String link: links) {
138 final HttpGet httpGet1 = new HttpGet(link);
139 try (ClassicHttpResponse response = client.executeOpen(target, httpGet1, context)) {
140 final int code = response.getCode();
141 final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
142 EntityUtils.consume(response.getEntity());
143 if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) {
144 logResult(TestResult.OK, httpGet1, "200, " + cacheResponseStatus);
145 } else {
146 logResult(TestResult.NOK, httpGet1, "(status " + code + ", " + cacheResponseStatus + ")");
147 }
148 } catch (final Exception ex) {
149 logResult(TestResult.NOK, httpGet1, "(" + ex.getMessage() + ")");
150 }
151 final HttpGet httpGet2 = new HttpGet(link);
152 try (ClassicHttpResponse response = client.executeOpen(target, httpGet2, context)) {
153 final int code = response.getCode();
154 final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
155 EntityUtils.consume(response.getEntity());
156 if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_HIT) {
157 logResult(TestResult.OK, httpGet2, "200, " + cacheResponseStatus);
158 } else {
159 logResult(TestResult.NOK, httpGet2, "(status " + code + ", " + cacheResponseStatus + ")");
160 }
161 } catch (final Exception ex) {
162 logResult(TestResult.NOK, httpGet2, "(" + ex.getMessage() + ")");
163 }
164
165 Thread.sleep(2000);
166
167 final HttpGet httpGet3 = new HttpGet(link);
168 httpGet3.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=0");
169 try (ClassicHttpResponse response = client.executeOpen(target, httpGet3, context)) {
170 final int code = response.getCode();
171 final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus();
172 EntityUtils.consume(response.getEntity());
173 if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) {
174 logResult(TestResult.OK, httpGet3, "200, " + cacheResponseStatus);
175 } else {
176 logResult(TestResult.NOK, httpGet3, "(status " + code + ", " + cacheResponseStatus + ")");
177 }
178 } catch (final Exception ex) {
179 logResult(TestResult.NOK, httpGet3, "(" + ex.getMessage() + ")");
180 }
181 }
182 }
183 }
184
185 }