diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpAsyncClientCompatibilityTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpAsyncClientCompatibilityTest.java index c4f309027..68e0d151c 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpAsyncClientCompatibilityTest.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpAsyncClientCompatibilityTest.java @@ -26,14 +26,10 @@ */ package org.apache.hc.client5.testing.external; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.hc.client5.http.async.methods.SimpleHttpRequest; import org.apache.hc.client5.http.async.methods.SimpleHttpResponse; @@ -48,9 +44,10 @@ import org.apache.hc.client5.http.impl.cache.HeapResourceFactory; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder; import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; -import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpHeaders; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpRequest; +import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.HttpStatus; import org.apache.hc.core5.http.HttpVersion; import org.apache.hc.core5.http2.HttpVersionPolicy; @@ -99,26 +96,35 @@ public class CachingHttpAsyncClientCompatibilityTest { this.client = CachingHttpAsyncClients.custom() .setCacheConfig(CacheConfig.custom() .setMaxObjectSize(20480) + .setHeuristicCachingEnabled(true) .build()) .setResourceFactory(HeapResourceFactory.INSTANCE) .setConnectionManager(this.connManager) .build(); } - void shutdown() throws Exception { client.close(); } enum TestResult {OK, NOK} - private void logResult(final TestResult result, final HttpRequest request, final String message) { + private void logResult(final TestResult result, + final HttpRequest request, + final HttpResponse response, + final String message) { final StringBuilder buf = new StringBuilder(); buf.append(result); if (buf.length() == 2) { buf.append(" "); } - buf.append(": ").append(target); + buf.append(": "); + if (response != null && response.getVersion() != null) { + buf.append(response.getVersion()).append(" "); + } else { + buf.append(protocolVersion).append(" "); + } + buf.append(target); buf.append(": "); buf.append(request.getMethod()).append(" ").append(request.getRequestUri()); if (message != null && !TextUtils.isBlank(message)) { @@ -127,7 +133,7 @@ public class CachingHttpAsyncClientCompatibilityTest { System.out.println(buf); } - void execute() throws Exception { + void execute() throws InterruptedException { client.start(); // Initial ping @@ -142,113 +148,90 @@ public class CachingHttpAsyncClientCompatibilityTest { final SimpleHttpResponse response = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()); final int code = response.getCode(); if (code == HttpStatus.SC_OK) { - logResult(TestResult.OK, options, Objects.toString(response.getFirstHeader("server"))); + logResult(TestResult.OK, options, response, Objects.toString(response.getFirstHeader("server"))); } else { - logResult(TestResult.NOK, options, "(status " + code + ")"); + logResult(TestResult.NOK, options, response, "(status " + code + ")"); } } catch (final ExecutionException ex) { final Throwable cause = ex.getCause(); - logResult(TestResult.NOK, options, "(" + cause.getMessage() + ")"); + logResult(TestResult.NOK, options, null, "(" + cause.getMessage() + ")"); } catch (final TimeoutException ex) { - logResult(TestResult.NOK, options, "(time out)"); + logResult(TestResult.NOK, options, null, "(time out)"); } } - // GET with links + + // GET from cache { connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND); final HttpCacheContext context = HttpCacheContext.create(); - final Pattern linkPattern = Pattern.compile("^<(.*)>;rel=preload$"); - final List links = new ArrayList<>(); - final SimpleHttpRequest getRoot1 = SimpleRequestBuilder.get() - .setHttpHost(target) - .setPath("/") - .build(); - final Future future1 = client.execute(getRoot1, context, null); - try { - final SimpleHttpResponse response = future1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()); - final int code = response.getCode(); - final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); - if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) { - logResult(TestResult.OK, getRoot1, "200, " + cacheResponseStatus); - } else { - logResult(TestResult.NOK, getRoot1, "(status " + code + ", " + cacheResponseStatus + ")"); - } - for (final Header header: response.getHeaders("Link")) { - final Matcher matcher = linkPattern.matcher(header.getValue()); - if (matcher.matches()) { - links.add(matcher.group(1)); - } - } - } catch (final ExecutionException ex) { - final Throwable cause = ex.getCause(); - logResult(TestResult.NOK, getRoot1, "(" + cause.getMessage() + ")"); - } catch (final TimeoutException ex) { - logResult(TestResult.NOK, getRoot1, "(time out)"); - } + final String[] links = {"/", "/css/hc-maven.css", "/images/logos/httpcomponents.png"}; + for (final String link: links) { - final SimpleHttpRequest getLink = SimpleRequestBuilder.get() + final SimpleHttpRequest httpGet1 = SimpleRequestBuilder.get() .setHttpHost(target) .setPath(link) .build(); - final Future linkFuture = client.execute(getLink, context, null); + final Future linkFuture1 = client.execute(httpGet1, context, null); try { - final SimpleHttpResponse response = linkFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()); + final SimpleHttpResponse response = linkFuture1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()); final int code = response.getCode(); final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) { - logResult(TestResult.OK, getLink, "200, " + cacheResponseStatus); + logResult(TestResult.OK, httpGet1, response, "200, " + cacheResponseStatus); } else { - logResult(TestResult.NOK, getLink, "(status " + code + ", " + cacheResponseStatus + ")"); + logResult(TestResult.NOK, httpGet1, response, "(status " + code + ", " + cacheResponseStatus + ")"); } } catch (final ExecutionException ex) { final Throwable cause = ex.getCause(); - logResult(TestResult.NOK, getLink, "(" + cause.getMessage() + ")"); + logResult(TestResult.NOK, httpGet1, null, "(" + cause.getMessage() + ")"); } catch (final TimeoutException ex) { - logResult(TestResult.NOK, getLink, "(time out)"); + logResult(TestResult.NOK, httpGet1, null,"(time out)"); } - } - final SimpleHttpRequest getRoot2 = SimpleRequestBuilder.get() - .setHttpHost(target) - .setPath("/") - .build(); - final Future future2 = client.execute(getRoot2, context, null); - try { - final SimpleHttpResponse response = future2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()); - final int code = response.getCode(); - final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); - if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) { - logResult(TestResult.OK, getRoot2, "200, " + cacheResponseStatus); - } else { - logResult(TestResult.NOK, getRoot2, "(status " + code + ", " + cacheResponseStatus + ")"); - } - } catch (final ExecutionException ex) { - final Throwable cause = ex.getCause(); - logResult(TestResult.NOK, getRoot2, "(" + cause.getMessage() + ")"); - } catch (final TimeoutException ex) { - logResult(TestResult.NOK, getRoot2, "(time out)"); - } - for (final String link: links) { - final SimpleHttpRequest getLink = SimpleRequestBuilder.get() + final SimpleHttpRequest httpGet2 = SimpleRequestBuilder.get() .setHttpHost(target) .setPath(link) .build(); - final Future linkFuture = client.execute(getLink, context, null); + final Future linkFuture2 = client.execute(httpGet2, context, null); try { - final SimpleHttpResponse response = linkFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()); + final SimpleHttpResponse response = linkFuture2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()); final int code = response.getCode(); final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); - if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) { - logResult(TestResult.OK, getLink, "200, " + cacheResponseStatus); + if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_HIT) { + logResult(TestResult.OK, httpGet2, response, "200, " + cacheResponseStatus); } else { - logResult(TestResult.NOK, getLink, "(status " + code + ", " + cacheResponseStatus + ")"); + logResult(TestResult.NOK, httpGet2, response, "(status " + code + ", " + cacheResponseStatus + ")"); } } catch (final ExecutionException ex) { final Throwable cause = ex.getCause(); - logResult(TestResult.NOK, getLink, "(" + cause.getMessage() + ")"); + logResult(TestResult.NOK, httpGet2, null, "(" + cause.getMessage() + ")"); } catch (final TimeoutException ex) { - logResult(TestResult.NOK, getLink, "(time out)"); + logResult(TestResult.NOK, httpGet2, null,"(time out)"); + } + + Thread.sleep(2000); + + final SimpleHttpRequest httpGet3 = SimpleRequestBuilder.get() + .setHttpHost(target) + .setPath(link) + .setHeader(HttpHeaders.CACHE_CONTROL, "max-age=0") + .build(); + final Future linkFuture3 = client.execute(httpGet3, context, null); + try { + final SimpleHttpResponse response = linkFuture3.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()); + final int code = response.getCode(); + final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); + if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) { + logResult(TestResult.OK, httpGet3, response, "200, " + cacheResponseStatus); + } else { + logResult(TestResult.NOK, httpGet3, response, "(status " + code + ", " + cacheResponseStatus + ")"); + } + } catch (final ExecutionException ex) { + final Throwable cause = ex.getCause(); + logResult(TestResult.NOK, httpGet3, null, "(" + cause.getMessage() + ")"); + } catch (final TimeoutException ex) { + logResult(TestResult.NOK, httpGet3, null,"(time out)"); } } } diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpClientCompatibilityTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpClientCompatibilityTest.java index b49ab26d1..2c0eba70e 100644 --- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpClientCompatibilityTest.java +++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/CachingHttpClientCompatibilityTest.java @@ -26,11 +26,7 @@ */ package org.apache.hc.client5.testing.external; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.net.ssl.SSLContext; @@ -46,7 +42,7 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.core5.http.ClassicHttpResponse; -import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpHeaders; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpRequest; import org.apache.hc.core5.http.HttpStatus; @@ -85,6 +81,7 @@ public class CachingHttpClientCompatibilityTest { this.client = CachingHttpClients.custom() .setCacheConfig(CacheConfig.custom() .setMaxObjectSize(20480) + .setHeuristicCachingEnabled(true) .build()) .setResourceFactory(HeapResourceFactory.INSTANCE) .setConnectionManager(this.connManager) @@ -112,7 +109,7 @@ public class CachingHttpClientCompatibilityTest { System.out.println(buf); } - void execute() { + void execute() throws InterruptedException { // Initial ping { @@ -130,73 +127,56 @@ public class CachingHttpClientCompatibilityTest { logResult(TestResult.NOK, options, "(" + ex.getMessage() + ")"); } } - // GET with links + // GET from cache { connManager.closeIdle(TimeValue.NEG_ONE_MILLISECOND); - final HttpCacheContext context = HttpCacheContext.create(); - final Pattern linkPattern = Pattern.compile("^<(.*)>;rel=preload$"); - final List links = new ArrayList<>(); - final HttpGet getRoot1 = new HttpGet("/"); - try (ClassicHttpResponse response = client.executeOpen(target, getRoot1, context)) { - final int code = response.getCode(); - final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); - EntityUtils.consume(response.getEntity()); - if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) { - logResult(TestResult.OK, getRoot1, "200, " + cacheResponseStatus); - } else { - logResult(TestResult.NOK, getRoot1, "(status " + code + ", " + cacheResponseStatus + ")"); - } - for (final Header header: response.getHeaders("Link")) { - final Matcher matcher = linkPattern.matcher(header.getValue()); - if (matcher.matches()) { - links.add(matcher.group(1)); - } - } - } catch (final Exception ex) { - logResult(TestResult.NOK, getRoot1, "(" + ex.getMessage() + ")"); - } + final String[] links = {"/", "/css/hc-maven.css", "/images/logos/httpcomponents.png"}; + + final HttpCacheContext context = HttpCacheContext.create(); for (final String link: links) { - final HttpGet getLink = new HttpGet(link); - try (ClassicHttpResponse response = client.executeOpen(target, getLink, context)) { + final HttpGet httpGet1 = new HttpGet(link); + try (ClassicHttpResponse response = client.executeOpen(target, httpGet1, context)) { final int code = response.getCode(); final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); EntityUtils.consume(response.getEntity()); if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_MISS) { - logResult(TestResult.OK, getRoot1, "200, " + cacheResponseStatus); + logResult(TestResult.OK, httpGet1, "200, " + cacheResponseStatus); } else { - logResult(TestResult.NOK, getRoot1, "(status " + code + ", " + cacheResponseStatus + ")"); + logResult(TestResult.NOK, httpGet1, "(status " + code + ", " + cacheResponseStatus + ")"); } } catch (final Exception ex) { - logResult(TestResult.NOK, getLink, "(" + ex.getMessage() + ")"); + logResult(TestResult.NOK, httpGet1, "(" + ex.getMessage() + ")"); } - } - final HttpGet getRoot2 = new HttpGet("/"); - try (ClassicHttpResponse response = client.executeOpen(target, getRoot2, context)) { - final int code = response.getCode(); - final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); - EntityUtils.consume(response.getEntity()); - if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) { - logResult(TestResult.OK, getRoot2, "200, " + cacheResponseStatus); - } else { - logResult(TestResult.NOK, getRoot2, "(status " + code + ", " + cacheResponseStatus + ")"); + final HttpGet httpGet2 = new HttpGet(link); + try (ClassicHttpResponse response = client.executeOpen(target, httpGet2, context)) { + final int code = response.getCode(); + final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); + EntityUtils.consume(response.getEntity()); + if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.CACHE_HIT) { + logResult(TestResult.OK, httpGet2, "200, " + cacheResponseStatus); + } else { + logResult(TestResult.NOK, httpGet2, "(status " + code + ", " + cacheResponseStatus + ")"); + } + } catch (final Exception ex) { + logResult(TestResult.NOK, httpGet2, "(" + ex.getMessage() + ")"); } - } catch (final Exception ex) { - logResult(TestResult.NOK, getRoot2, "(" + ex.getMessage() + ")"); - } - for (final String link: links) { - final HttpGet getLink = new HttpGet(link); - try (ClassicHttpResponse response = client.executeOpen(target, getLink, context)) { + + Thread.sleep(2000); + + final HttpGet httpGet3 = new HttpGet(link); + httpGet3.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=0"); + try (ClassicHttpResponse response = client.executeOpen(target, httpGet3, context)) { final int code = response.getCode(); final CacheResponseStatus cacheResponseStatus = context.getCacheResponseStatus(); EntityUtils.consume(response.getEntity()); if (code == HttpStatus.SC_OK && cacheResponseStatus == CacheResponseStatus.VALIDATED) { - logResult(TestResult.OK, getRoot2, "200, " + cacheResponseStatus); + logResult(TestResult.OK, httpGet3, "200, " + cacheResponseStatus); } else { - logResult(TestResult.NOK, getRoot2, "(status " + code + ", " + cacheResponseStatus + ")"); + logResult(TestResult.NOK, httpGet3, "(status " + code + ", " + cacheResponseStatus + ")"); } } catch (final Exception ex) { - logResult(TestResult.NOK, getLink, "(" + ex.getMessage() + ")"); + logResult(TestResult.NOK, httpGet3, "(" + ex.getMessage() + ")"); } } }