From b25c7481e0791fedaead6bda15e4833f6f6287d2 Mon Sep 17 00:00:00 2001 From: Arturo Bernal Date: Tue, 23 Nov 2021 06:27:33 +0100 Subject: [PATCH] HTTPCLIENT-2189 - Use Time APIs for date internal class and Cookie. --- .../hc/client5/http/cache/HttpCacheEntry.java | 98 +++++++++- .../http/impl/cache/AsyncCachingExec.java | 36 ++-- .../http/impl/cache/BasicHttpAsyncCache.java | 14 +- .../http/impl/cache/BasicHttpCache.java | 14 +- .../cache/ByteArrayCacheEntrySerializer.java | 1 + .../http/impl/cache/CacheUpdateHandler.java | 16 +- .../http/impl/cache/CacheValidityPolicy.java | 49 ++--- .../cache/CachedHttpResponseGenerator.java | 3 +- .../CachedResponseSuitabilityChecker.java | 10 +- .../client5/http/impl/cache/CachingExec.java | 24 +-- .../http/impl/cache/CachingExecBase.java | 16 +- .../http/impl/cache/HttpAsyncCache.java | 14 +- .../HttpByteArrayCacheEntrySerializer.java | 16 +- .../hc/client5/http/impl/cache/HttpCache.java | 14 +- .../cache/ResponseProtocolCompliance.java | 5 +- .../client5/http/impl/cache/WarningValue.java | 12 +- .../http/cache/TestHttpCacheEntry.java | 78 ++++---- ...yteArrayCacheEntrySerializerTestUtils.java | 15 +- .../impl/cache/HttpCacheEntryMatcher.java | 15 +- .../http/impl/cache/HttpTestUtils.java | 54 +++--- .../http/impl/cache/TestBasicHttpCache.java | 9 +- .../TestByteArrayCacheEntrySerializer.java | 38 +++- .../impl/cache/TestCacheUpdateHandler.java | 33 ++-- .../impl/cache/TestCacheValidityPolicy.java | 41 ++-- .../TestCachedHttpResponseGenerator.java | 10 +- .../TestCachedResponseSuitabilityChecker.java | 40 ++-- .../http/impl/cache/TestCachingExecChain.java | 10 +- ...TestHttpByteArrayCacheEntrySerializer.java | 181 +++++++++--------- .../http/impl/cache/TestWarningValue.java | 6 +- .../hc/client5/http/fluent/Request.java | 28 +++ .../hc/client5/http/config/RequestConfig.java | 2 +- .../client5/http/cookie/BasicCookieStore.java | 32 +++- .../apache/hc/client5/http/cookie/Cookie.java | 39 ++++ .../http/cookie/CookiePriorityComparator.java | 8 +- .../hc/client5/http/cookie/CookieStore.java | 14 ++ .../hc/client5/http/cookie/SetCookie.java | 21 +- .../impl/async/HttpAsyncClientBuilder.java | 2 +- .../http/impl/cookie/BasicClientCookie.java | 65 ++++++- .../http/impl/cookie/BasicExpiresHandler.java | 2 +- .../http/impl/cookie/BasicMaxAgeHandler.java | 4 +- .../http/impl/cookie/LaxExpiresHandler.java | 3 +- .../http/impl/cookie/LaxMaxAgeHandler.java | 6 +- .../http/impl/cookie/RFC6265CookieSpec.java | 4 +- .../io/BasicHttpClientConnectionManager.java | 4 +- .../http/protocol/RequestAddCookies.java | 4 +- .../http/protocol/ResponseProcessCookies.java | 2 +- .../http/ssl/DefaultClientTlsStrategy.java | 1 + .../cookie/TestCookiePriorityComparator.java | 6 +- .../cookie/TestBasicCookieAttribHandlers.java | 4 +- .../impl/cookie/TestBasicCookieStore.java | 8 +- .../cookie/TestLaxCookieAttribHandlers.java | 118 ++++++++++-- .../http/protocol/TestRequestAddCookies.java | 6 +- 52 files changed, 821 insertions(+), 434 deletions(-) diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java index 578a7227e4..11432ac170 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java @@ -27,6 +27,7 @@ package org.apache.hc.client5.http.cache; import java.io.Serializable; +import java.time.Instant; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -59,13 +60,13 @@ public class HttpCacheEntry implements MessageHeaders, Serializable { private static final long serialVersionUID = -6300496422359477413L; private static final String REQUEST_METHOD_HEADER_NAME = "Hc-Request-Method"; - private final Date requestDate; - private final Date responseDate; + private final Instant requestDate; + private final Instant responseDate; private final int status; private final HeaderGroup responseHeaders; private final Resource resource; private final Map variantMap; - private final Date date; + private final Instant date; /** * Create a new {@link HttpCacheEntry} with variants. @@ -84,7 +85,9 @@ public class HttpCacheEntry implements MessageHeaders, Serializable { * of this parent entry; this maps a "variant key" (derived * from the varying request headers) to a "cache key" (where * in the cache storage the particular variant is located) + * @deprecated Use {{@link #HttpCacheEntry(Instant, Instant, int, Header[], Resource, Map)}} */ + @Deprecated public HttpCacheEntry( final Date requestDate, final Date responseDate, @@ -97,6 +100,42 @@ public HttpCacheEntry( Args.notNull(responseDate, "Response date"); Args.check(status >= HttpStatus.SC_SUCCESS, "Status code"); Args.notNull(responseHeaders, "Response headers"); + this.requestDate = DateUtils.toInstant(requestDate); + this.responseDate = DateUtils.toInstant(responseDate); + this.status = status; + this.responseHeaders = new HeaderGroup(); + this.responseHeaders.setHeaders(responseHeaders); + this.resource = resource; + this.variantMap = variantMap != null ? new HashMap<>(variantMap) : null; + this.date = parseDate(); + } + + /** + * Create a new {@link HttpCacheEntry} with variants. + * + * @param requestDate Date/time when the request was made (Used for age calculations) + * @param responseDate Date/time that the response came back (Used for age calculations) + * @param status HTTP status from origin response + * @param responseHeaders Header[] from original HTTP Response + * @param resource representing origin response body + * @param variantMap describing cache entries that are variants of this parent entry; this + * maps a "variant key" (derived from the varying request headers) to a + * "cache key" (where in the cache storage the particular variant is + * located) + * @since 5.2 + */ + public HttpCacheEntry( + final Instant requestDate, + final Instant responseDate, + final int status, + final Header[] responseHeaders, + final Resource resource, + final Map variantMap) { + super(); + Args.notNull(requestDate, "Request date"); + Args.notNull(responseDate, "Response date"); + Args.check(status >= HttpStatus.SC_SUCCESS, "Status code"); + Args.notNull(responseHeaders, "Response headers"); this.requestDate = requestDate; this.responseDate = responseDate; this.status = status; @@ -107,6 +146,21 @@ public HttpCacheEntry( this.date = parseDate(); } + /** + * Create a new {@link HttpCacheEntry}. + * + * @param requestDate Date/time when the request was made (Used for age calculations) + * @param responseDate Date/time that the response came back (Used for age calculations) + * @param status HTTP status from origin response + * @param responseHeaders Header[] from original HTTP Response + * @param resource representing origin response body + * @deprecated {{@link #HttpCacheEntry(Instant, Instant, int, Header[], Resource)}} + */ + @Deprecated + public HttpCacheEntry(final Date requestDate, final Date responseDate, final int status, + final Header[] responseHeaders, final Resource resource) { + this(requestDate, responseDate, status, responseHeaders, resource, new HashMap<>()); + } /** * Create a new {@link HttpCacheEntry}. * @@ -122,17 +176,17 @@ public HttpCacheEntry( * Header[] from original HTTP Response * @param resource representing origin response body */ - public HttpCacheEntry(final Date requestDate, final Date responseDate, final int status, - final Header[] responseHeaders, final Resource resource) { + public HttpCacheEntry(final Instant requestDate, final Instant responseDate, final int status, + final Header[] responseHeaders, final Resource resource) { this(requestDate, responseDate, status, responseHeaders, resource, new HashMap<>()); } /** - * Find the "Date" response header and parse it into a java.util.Date + * Find the "Date" response header and parse it into a {@link Instant} * @return the Date value of the header or null if the header is not present */ - private Date parseDate() { - return DateUtils.toDate(DateUtils.parseStandardDate(this, HttpHeaders.DATE)); + private Instant parseDate() { + return DateUtils.parseStandardDate(this, HttpHeaders.DATE); } /** @@ -146,16 +200,40 @@ public int getStatus() { * Returns the time the associated origin request was initiated by the * caching module. * @return {@link Date} + * @deprecated USe {@link #getRequestInstant()} */ + @Deprecated public Date getRequestDate() { + return DateUtils.toDate(requestDate); + } + + /** + * Returns the time the associated origin request was initiated by the + * caching module. + * @return {@link Instant} + * @since 5.2 + */ + public Instant getRequestInstant() { return requestDate; } /** * Returns the time the origin response was received by the caching module. * @return {@link Date} + * @deprecated Use {@link #getResponseInstant()} */ + @Deprecated public Date getResponseDate() { + return DateUtils.toDate(responseDate); + } + + /** + * Returns the time the origin response was received by the caching module. + * + * @return {@link Instant} + * @since 5.2 + */ + public Instant getResponseInstant() { return responseDate; } @@ -253,6 +331,10 @@ public Iterator
headerIterator(final String name) { * @since 4.3 */ public Date getDate() { + return DateUtils.toDate(date); + } + + public Instant getInstant() { return date; } diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java index 6cc9832231..ad7704d692 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java @@ -29,7 +29,7 @@ import java.io.IOException; import java.io.InterruptedIOException; import java.nio.ByteBuffer; -import java.util.Date; +import java.time.Instant; import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; @@ -309,7 +309,7 @@ void callBackend( final AsyncExecChain chain, final AsyncExecCallback asyncExecCallback) { LOG.debug("Calling the backend"); - final Date requestDate = getCurrentDate(); + final Instant requestDate = getCurrentDate(); final AtomicReference callbackRef = new AtomicReference<>(); chainProceed(request, entityProducer, scope, chain, new AsyncExecCallback() { @@ -317,7 +317,7 @@ void callBackend( public AsyncDataConsumer handleResponse( final HttpResponse backendResponse, final EntityDetails entityDetails) throws HttpException, IOException { - final Date responseDate = getCurrentDate(); + final Instant responseDate = getCurrentDate(); backendResponse.addHeader("Via", generateViaHeader(backendResponse)); final AsyncExecCallback callback = new BackendResponseHandler(target, request, requestDate, responseDate, scope, asyncExecCallback); @@ -446,8 +446,8 @@ class BackendResponseHandler implements AsyncExecCallback { private final HttpHost target; private final HttpRequest request; - private final Date requestDate; - private final Date responseDate; + private final Instant requestDate; + private final Instant responseDate; private final AsyncExecChain.Scope scope; private final AsyncExecCallback asyncExecCallback; private final AtomicReference cachingConsumerRef; @@ -455,8 +455,8 @@ class BackendResponseHandler implements AsyncExecCallback { BackendResponseHandler( final HttpHost target, final HttpRequest request, - final Date requestDate, - final Date responseDate, + final Instant requestDate, + final Instant responseDate, final AsyncExecChain.Scope scope, final AsyncExecCallback asyncExecCallback) { this.target = target; @@ -525,7 +525,7 @@ public void handleInformationResponse(final HttpResponse response) throws HttpEx asyncExecCallback.handleInformationResponse(response); } - void triggerNewCacheEntryResponse(final HttpResponse backendResponse, final Date responseDate, final ByteArrayBuffer buffer) { + void triggerNewCacheEntryResponse(final HttpResponse backendResponse, final Instant responseDate, final ByteArrayBuffer buffer) { final CancellableDependency operation = scope.cancellableDependency; operation.setDependency(responseCache.createCacheEntry( target, @@ -622,7 +622,7 @@ private void handleCacheHit( final HttpCacheEntry entry) { final HttpClientContext context = scope.clientContext; recordCacheHit(target, request); - final Date now = getCurrentDate(); + final Instant now = getCurrentDate(); if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) { LOG.debug("Cache hit"); try { @@ -690,7 +690,7 @@ void revalidateCacheEntry( final AsyncExecChain chain, final AsyncExecCallback asyncExecCallback, final HttpCacheEntry cacheEntry) { - final Date requestDate = getCurrentDate(); + final Instant requestDate = getCurrentDate(); final HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest( BasicRequestBuilder.copy(scope.originalRequest).build(), cacheEntry); @@ -698,7 +698,7 @@ void revalidateCacheEntry( final AtomicReference callbackRef = new AtomicReference<>(); - void triggerUpdatedCacheEntryResponse(final HttpResponse backendResponse, final Date responseDate) { + void triggerUpdatedCacheEntryResponse(final HttpResponse backendResponse, final Instant responseDate) { final CancellableDependency operation = scope.cancellableDependency; recordCacheUpdate(scope.clientContext); operation.setDependency(responseCache.updateCacheEntry( @@ -713,7 +713,7 @@ void triggerUpdatedCacheEntryResponse(final HttpResponse backendResponse, final @Override public void completed(final HttpCacheEntry updatedEntry) { if (suitabilityChecker.isConditional(request) - && suitabilityChecker.allConditionalsMatch(request, updatedEntry, new Date())) { + && suitabilityChecker.allConditionalsMatch(request, updatedEntry, Instant.now())) { final SimpleHttpResponse cacheResponse = responseGenerator.generateNotModifiedResponse(updatedEntry); triggerResponse(cacheResponse, scope, asyncExecCallback); } else { @@ -749,7 +749,7 @@ void triggerResponseStaleCacheEntry() { } } - AsyncExecCallback evaluateResponse(final HttpResponse backendResponse, final Date responseDate) { + AsyncExecCallback evaluateResponse(final HttpResponse backendResponse, final Instant responseDate) { backendResponse.addHeader(HeaderConstants.VIA, generateViaHeader(backendResponse)); final int statusCode = backendResponse.getCode(); @@ -772,7 +772,7 @@ public AsyncDataConsumer handleResponse( final HttpResponse backendResponse1, final EntityDetails entityDetails) throws HttpException, IOException { - final Date responseDate1 = getCurrentDate(); + final Instant responseDate1 = getCurrentDate(); final AsyncExecCallback callback1; if (revalidationResponseIsTooOld(backendResponse1, cacheEntry) @@ -787,7 +787,7 @@ public AsyncDataConsumer handleResponse( public AsyncDataConsumer handleResponse( final HttpResponse backendResponse2, final EntityDetails entityDetails1) throws HttpException, IOException { - final Date responseDate2 = getCurrentDate(); + final Instant responseDate2 = getCurrentDate(); final AsyncExecCallback callback2 = evaluateResponse(backendResponse2, responseDate2); callbackRef.set(callback2); return callback2.handleResponse(backendResponse2, entityDetails1); @@ -920,12 +920,12 @@ void negotiateResponseFromVariants( BasicRequestBuilder.copy(request).build(), variants); - final Date requestDate = getCurrentDate(); + final Instant requestDate = getCurrentDate(); chainProceed(conditionalRequest, entityProducer, scope, chain, new AsyncExecCallback() { final AtomicReference callbackRef = new AtomicReference<>(); - void updateVariantCacheEntry(final HttpResponse backendResponse, final Date responseDate, final Variant matchingVariant) { + void updateVariantCacheEntry(final HttpResponse backendResponse, final Instant responseDate, final Variant matchingVariant) { recordCacheUpdate(scope.clientContext); operation.setDependency(responseCache.updateVariantCacheEntry( target, @@ -989,7 +989,7 @@ public void cancelled() { public AsyncDataConsumer handleResponse( final HttpResponse backendResponse, final EntityDetails entityDetails) throws HttpException, IOException { - final Date responseDate = getCurrentDate(); + final Instant responseDate = getCurrentDate(); backendResponse.addHeader("Via", generateViaHeader(backendResponse)); final AsyncExecCallback callback; diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java index 508c814289..d89def8a54 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java @@ -26,7 +26,7 @@ */ package org.apache.hc.client5.http.impl.cache; -import java.util.Date; +import java.time.Instant; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -309,8 +309,8 @@ public Cancellable updateCacheEntry( final HttpRequest request, final HttpCacheEntry stale, final HttpResponse originResponse, - final Date requestSent, - final Date responseReceived, + final Instant requestSent, + final Instant responseReceived, final FutureCallback callback) { if (LOG.isDebugEnabled()) { LOG.debug("Update cache entry: {}; {}", host, new RequestLine(request)); @@ -356,8 +356,8 @@ public Cancellable updateVariantCacheEntry( final HttpRequest request, final HttpResponse originResponse, final Variant variant, - final Date requestSent, - final Date responseReceived, + final Instant requestSent, + final Instant responseReceived, final FutureCallback callback) { if (LOG.isDebugEnabled()) { LOG.debug("Update variant cache entry: {}; {} / {}", host, new RequestLine(request), variant); @@ -404,8 +404,8 @@ public Cancellable createCacheEntry( final HttpRequest request, final HttpResponse originResponse, final ByteArrayBuffer content, - final Date requestSent, - final Date responseReceived, + final Instant requestSent, + final Instant responseReceived, final FutureCallback callback) { if (LOG.isDebugEnabled()) { LOG.debug("Create cache entry: {}; {}", host, new RequestLine(request)); diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java index e6a7c1dd10..0dd4089a00 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java @@ -26,7 +26,7 @@ */ package org.apache.hc.client5.http.impl.cache; -import java.util.Date; +import java.time.Instant; import java.util.HashMap; import java.util.Map; @@ -204,8 +204,8 @@ public HttpCacheEntry updateCacheEntry( final HttpRequest request, final HttpCacheEntry stale, final HttpResponse originResponse, - final Date requestSent, - final Date responseReceived) { + final Instant requestSent, + final Instant responseReceived) { if (LOG.isDebugEnabled()) { LOG.debug("Update cache entry: {}; {}", host, new RequestLine(request)); } @@ -233,8 +233,8 @@ public HttpCacheEntry updateVariantCacheEntry( final HttpRequest request, final HttpResponse originResponse, final Variant variant, - final Date requestSent, - final Date responseReceived) { + final Instant requestSent, + final Instant responseReceived) { if (LOG.isDebugEnabled()) { LOG.debug("Update variant cache entry: {}; {} / {}", host, new RequestLine(request), variant); } @@ -263,8 +263,8 @@ public HttpCacheEntry createCacheEntry( final HttpRequest request, final HttpResponse originResponse, final ByteArrayBuffer content, - final Date requestSent, - final Date responseReceived) { + final Instant requestSent, + final Instant responseReceived) { if (LOG.isDebugEnabled()) { LOG.debug("Create cache entry: {}; {}", host, new RequestLine(request)); } diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ByteArrayCacheEntrySerializer.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ByteArrayCacheEntrySerializer.java index edef0535b2..1bebc95a0e 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ByteArrayCacheEntrySerializer.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ByteArrayCacheEntrySerializer.java @@ -90,6 +90,7 @@ static class RestrictedObjectInputStream extends ObjectInputStream { Pattern.compile("^(\\[L)?org\\.apache\\.hc\\.(.*)"), Pattern.compile("^(?:\\[+L)?java\\.util\\..*$"), Pattern.compile("^(?:\\[+L)?java\\.lang\\..*$"), + Pattern.compile("^(?:\\[+L)?java\\.time\\..*$"), // java 8 time Pattern.compile("^\\[+Z$"), // boolean Pattern.compile("^\\[+B$"), // byte Pattern.compile("^\\[+C$"), // char diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheUpdateHandler.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheUpdateHandler.java index bdb0d32bab..29ef51e090 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheUpdateHandler.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheUpdateHandler.java @@ -26,7 +26,7 @@ */ package org.apache.hc.client5.http.impl.cache; -import java.util.Date; +import java.time.Instant; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -69,8 +69,8 @@ public HttpCacheEntry createCacheEntry( final HttpRequest request, final HttpResponse originResponse, final ByteArrayBuffer content, - final Date requestSent, - final Date responseReceived) throws ResourceIOException { + final Instant requestSent, + final Instant responseReceived) throws ResourceIOException { return new HttpCacheEntry( requestSent, responseReceived, @@ -86,8 +86,8 @@ public HttpCacheEntry createCacheEntry( public HttpCacheEntry updateCacheEntry( final String requestId, final HttpCacheEntry entry, - final Date requestDate, - final Date responseDate, + final Instant requestDate, + final Instant responseDate, final HttpResponse response) throws ResourceIOException { Args.check(response.getCode() == HttpStatus.SC_NOT_MODIFIED, "Response must have 304 status code"); @@ -103,7 +103,7 @@ public HttpCacheEntry updateCacheEntry( mergedHeaders, resource); } - + @SuppressWarnings("deprecation") public HttpCacheEntry updateParentCacheEntry( final String requestId, final HttpCacheEntry existing, @@ -122,8 +122,8 @@ public HttpCacheEntry updateParentCacheEntry( final Map variantMap = new HashMap<>(src.getVariantMap()); variantMap.put(variantKey, variantCacheKey); return new HttpCacheEntry( - src.getRequestDate(), - src.getResponseDate(), + src.getRequestInstant(), + src.getResponseInstant(), src.getStatus(), src.getHeaders(), resource, diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheValidityPolicy.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheValidityPolicy.java index f29159a859..b657e60102 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheValidityPolicy.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CacheValidityPolicy.java @@ -26,8 +26,8 @@ */ package org.apache.hc.client5.http.impl.cache; +import java.time.Duration; import java.time.Instant; -import java.util.Date; import java.util.Iterator; import org.apache.hc.client5.http.cache.HeaderConstants; @@ -50,7 +50,8 @@ class CacheValidityPolicy { super(); } - public TimeValue getCurrentAge(final HttpCacheEntry entry, final Date now) { + + public TimeValue getCurrentAge(final HttpCacheEntry entry, final Instant now) { return TimeValue.ofSeconds(getCorrectedInitialAge(entry).toSeconds() + getResidentTime(entry, now).toSeconds()); } @@ -60,7 +61,7 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry entry) { return TimeValue.ofSeconds(maxAge); } - final Date dateValue = entry.getDate(); + final Instant dateValue = entry.getInstant(); if (dateValue == null) { return TimeValue.ZERO_MILLISECONDS; } @@ -69,11 +70,11 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry entry) { if (expiry == null) { return TimeValue.ZERO_MILLISECONDS; } - final long diff = expiry.toEpochMilli() - dateValue.getTime(); - return TimeValue.ofSeconds(diff / 1000); + final Duration diff = Duration.between(dateValue, expiry); + return TimeValue.ofSeconds(diff.getSeconds()); } - public boolean isResponseFresh(final HttpCacheEntry entry, final Date now) { + public boolean isResponseFresh(final HttpCacheEntry entry, final Instant now) { return getCurrentAge(entry, now).compareTo(getFreshnessLifetime(entry)) == -1; } @@ -92,21 +93,22 @@ public boolean isResponseFresh(final HttpCacheEntry entry, final Date now) { * @return {@code true} if the response is fresh */ public boolean isResponseHeuristicallyFresh(final HttpCacheEntry entry, - final Date now, final float coefficient, final TimeValue defaultLifetime) { + final Instant now, final float coefficient, final TimeValue defaultLifetime) { return getCurrentAge(entry, now).compareTo(getHeuristicFreshnessLifetime(entry, coefficient, defaultLifetime)) == -1; } public TimeValue getHeuristicFreshnessLifetime(final HttpCacheEntry entry, final float coefficient, final TimeValue defaultLifetime) { - final Date dateValue = entry.getDate(); + final Instant dateValue = entry.getInstant(); final Instant lastModifiedValue = DateUtils.parseStandardDate(entry, HeaderConstants.LAST_MODIFIED); if (dateValue != null && lastModifiedValue != null) { - final long diff = dateValue.getTime() - lastModifiedValue.toEpochMilli(); - if (diff < 0) { + final Duration diff = Duration.between(lastModifiedValue, dateValue); + + if (diff.isNegative()) { return TimeValue.ZERO_MILLISECONDS; } - return TimeValue.ofSeconds((long) (coefficient * diff / 1000)); + return TimeValue.ofSeconds((long) (coefficient * diff.getSeconds())); } return defaultLifetime; @@ -125,7 +127,7 @@ public boolean proxyRevalidate(final HttpCacheEntry entry) { return hasCacheControlDirective(entry, HeaderConstants.CACHE_CONTROL_PROXY_REVALIDATE); } - public boolean mayReturnStaleWhileRevalidating(final HttpCacheEntry entry, final Date now) { + public boolean mayReturnStaleWhileRevalidating(final HttpCacheEntry entry, final Instant now) { final Iterator it = MessageSupport.iterate(entry, HeaderConstants.CACHE_CONTROL); while (it.hasNext()) { final HeaderElement elt = it.next(); @@ -145,7 +147,7 @@ public boolean mayReturnStaleWhileRevalidating(final HttpCacheEntry entry, final return false; } - public boolean mayReturnStaleIfError(final HttpRequest request, final HttpCacheEntry entry, final Date now) { + public boolean mayReturnStaleIfError(final HttpRequest request, final HttpCacheEntry entry, final Instant now) { final TimeValue staleness = getStaleness(entry, now); return mayReturnStaleIfError(request, HeaderConstants.CACHE_CONTROL, staleness) || mayReturnStaleIfError(entry, HeaderConstants.CACHE_CONTROL, staleness); @@ -198,15 +200,15 @@ protected boolean contentLengthHeaderMatchesActualLength(final HttpCacheEntry en } protected TimeValue getApparentAge(final HttpCacheEntry entry) { - final Date dateValue = entry.getDate(); + final Instant dateValue = entry.getInstant(); if (dateValue == null) { return MAX_AGE; } - final long diff = entry.getResponseDate().getTime() - dateValue.getTime(); - if (diff < 0L) { + final Duration diff = Duration.between(dateValue, entry.getResponseInstant()); + if (diff.isNegative()) { return TimeValue.ZERO_MILLISECONDS; } - return TimeValue.ofSeconds(diff / 1000); + return TimeValue.ofSeconds(diff.getSeconds()); } protected long getAgeValue(final HttpCacheEntry entry) { @@ -234,19 +236,20 @@ protected TimeValue getCorrectedReceivedAge(final HttpCacheEntry entry) { } protected TimeValue getResponseDelay(final HttpCacheEntry entry) { - final long diff = entry.getResponseDate().getTime() - entry.getRequestDate().getTime(); - return TimeValue.ofSeconds(diff / 1000); + final Duration diff = Duration.between(entry.getRequestInstant(), entry.getResponseInstant()); + return TimeValue.ofSeconds(diff.getSeconds()); } protected TimeValue getCorrectedInitialAge(final HttpCacheEntry entry) { return TimeValue.ofSeconds(getCorrectedReceivedAge(entry).toSeconds() + getResponseDelay(entry).toSeconds()); } - protected TimeValue getResidentTime(final HttpCacheEntry entry, final Date now) { - final long diff = now.getTime() - entry.getResponseDate().getTime(); - return TimeValue.ofSeconds(diff / 1000); + protected TimeValue getResidentTime(final HttpCacheEntry entry, final Instant now) { + final Duration diff = Duration.between(entry.getResponseInstant(), now); + return TimeValue.ofSeconds(diff.getSeconds()); } + protected long getMaxAge(final HttpCacheEntry entry) { // This is a header value, we leave as-is long maxAge = -1; @@ -279,7 +282,7 @@ public boolean hasCacheControlDirective(final HttpCacheEntry entry, final String return false; } - public TimeValue getStaleness(final HttpCacheEntry entry, final Date now) { + public TimeValue getStaleness(final HttpCacheEntry entry, final Instant now) { final TimeValue age = getCurrentAge(entry, now); final TimeValue freshness = getFreshnessLifetime(entry); if (age.compareTo(freshness) <= 0) { diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java index fab60b66b0..968330e7a4 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedHttpResponseGenerator.java @@ -27,7 +27,6 @@ package org.apache.hc.client5.http.impl.cache; import java.time.Instant; -import java.util.Date; import org.apache.hc.client5.http.async.methods.SimpleHttpResponse; import org.apache.hc.client5.http.cache.HeaderConstants; @@ -65,7 +64,7 @@ class CachedHttpResponseGenerator { * @return {@link SimpleHttpResponse} constructed response */ SimpleHttpResponse generateResponse(final HttpRequest request, final HttpCacheEntry entry) throws ResourceIOException { - final Date now = new Date(); + final Instant now =Instant.now(); final SimpleHttpResponse response = new SimpleHttpResponse(entry.getStatus()); response.setVersion(HttpVersion.DEFAULT); diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedResponseSuitabilityChecker.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedResponseSuitabilityChecker.java index 7e1200a9ba..2653f87aa1 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedResponseSuitabilityChecker.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachedResponseSuitabilityChecker.java @@ -27,7 +27,6 @@ package org.apache.hc.client5.http.impl.cache; import java.time.Instant; -import java.util.Date; import java.util.Iterator; import org.apache.hc.client5.http.cache.HeaderConstants; @@ -71,7 +70,7 @@ class CachedResponseSuitabilityChecker { this(new CacheValidityPolicy(), config); } - private boolean isFreshEnough(final HttpCacheEntry entry, final HttpRequest request, final Date now) { + private boolean isFreshEnough(final HttpCacheEntry entry, final HttpRequest request, final Instant now) { if (validityStrategy.isResponseFresh(entry, now)) { return true; } @@ -142,7 +141,7 @@ private long getMaxStale(final HttpRequest request) { * Right now in time * @return boolean yes/no answer */ - public boolean canCachedResponseBeUsed(final HttpHost host, final HttpRequest request, final HttpCacheEntry entry, final Date now) { + public boolean canCachedResponseBeUsed(final HttpHost host, final HttpRequest request, final HttpCacheEntry entry, final Instant now) { if (!isFreshEnough(entry, request, now)) { LOG.debug("Cache entry is not fresh enough"); return false; @@ -274,13 +273,12 @@ public boolean isConditional(final HttpRequest request) { * @param now right NOW in time * @return {@code true} if the request matches all conditionals */ - public boolean allConditionalsMatch(final HttpRequest request, final HttpCacheEntry entry, final Date now) { + public boolean allConditionalsMatch(final HttpRequest request, final HttpCacheEntry entry, final Instant now) { final boolean hasEtagValidator = hasSupportedEtagValidator(request); final boolean hasLastModifiedValidator = hasSupportedLastModifiedValidator(request); final boolean etagValidatorMatches = (hasEtagValidator) && etagValidatorMatches(request, entry); - final boolean lastModifiedValidatorMatches = (hasLastModifiedValidator) && lastModifiedValidatorMatches(request, entry, - DateUtils.toInstant(now)); + final boolean lastModifiedValidatorMatches = (hasLastModifiedValidator) && lastModifiedValidatorMatches(request, entry, now); if ((hasEtagValidator && hasLastModifiedValidator) && !(etagValidatorMatches && lastModifiedValidatorMatches)) { diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java index f72ebeba42..dcfd705481 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java @@ -28,7 +28,7 @@ import java.io.IOException; import java.io.InputStream; -import java.util.Date; +import java.time.Instant; import java.util.Iterator; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; @@ -231,7 +231,7 @@ ClassicHttpResponse callBackend( final ExecChain.Scope scope, final ExecChain chain) throws IOException, HttpException { - final Date requestDate = getCurrentDate(); + final Instant requestDate = getCurrentDate(); LOG.debug("Calling the backend"); final ClassicHttpResponse backendResponse = chain.proceed(request, scope); @@ -253,7 +253,7 @@ private ClassicHttpResponse handleCacheHit( final HttpClientContext context = scope.clientContext; context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); recordCacheHit(target, request); - final Date now = getCurrentDate(); + final Instant now = getCurrentDate(); if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) { LOG.debug("Cache hit"); try { @@ -306,13 +306,13 @@ ClassicHttpResponse revalidateCacheEntry( final ExecChain.Scope scope, final ExecChain chain, final HttpCacheEntry cacheEntry) throws IOException, HttpException { - Date requestDate = getCurrentDate(); + Instant requestDate = getCurrentDate(); final ClassicHttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest( scope.originalRequest, cacheEntry); ClassicHttpResponse backendResponse = chain.proceed(conditionalRequest, scope); try { - Date responseDate = getCurrentDate(); + Instant responseDate = getCurrentDate(); if (revalidationResponseIsTooOld(backendResponse, cacheEntry)) { backendResponse.close(); @@ -334,7 +334,7 @@ ClassicHttpResponse revalidateCacheEntry( final HttpCacheEntry updatedEntry = responseCache.updateCacheEntry( target, request, cacheEntry, backendResponse, requestDate, responseDate); if (suitabilityChecker.isConditional(request) - && suitabilityChecker.allConditionalsMatch(request, updatedEntry, new Date())) { + && suitabilityChecker.allConditionalsMatch(request, updatedEntry, Instant.now())) { return convert(responseGenerator.generateNotModifiedResponse(updatedEntry), scope); } return convert(responseGenerator.generateResponse(request, updatedEntry), scope); @@ -362,8 +362,8 @@ ClassicHttpResponse handleBackendResponse( final HttpHost target, final ClassicHttpRequest request, final ExecChain.Scope scope, - final Date requestDate, - final Date responseDate, + final Instant requestDate, + final Instant responseDate, final ClassicHttpResponse backendResponse) throws IOException { responseCompliance.ensureProtocolCompliance(scope.originalRequest, request, backendResponse); @@ -384,8 +384,8 @@ ClassicHttpResponse cacheAndReturnResponse( final HttpRequest request, final ClassicHttpResponse backendResponse, final ExecChain.Scope scope, - final Date requestSent, - final Date responseReceived) throws IOException { + final Instant requestSent, + final Instant responseReceived) throws IOException { LOG.debug("Caching backend response"); final ByteArrayBuffer buf; final HttpEntity entity = backendResponse.getEntity(); @@ -453,10 +453,10 @@ ClassicHttpResponse negotiateResponseFromVariants( final Map variants) throws IOException, HttpException { final ClassicHttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequestFromVariants(request, variants); - final Date requestDate = getCurrentDate(); + final Instant requestDate = getCurrentDate(); final ClassicHttpResponse backendResponse = chain.proceed(conditionalRequest, scope); try { - final Date responseDate = getCurrentDate(); + final Instant responseDate = getCurrentDate(); backendResponse.addHeader("Via", generateViaHeader(backendResponse)); diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExecBase.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExecBase.java index cec75bf710..f9c55758da 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExecBase.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExecBase.java @@ -27,7 +27,7 @@ package org.apache.hc.client5.http.impl.cache; import java.io.IOException; -import java.util.Date; +import java.time.Instant; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -183,7 +183,7 @@ SimpleHttpResponse generateCachedResponse( final HttpRequest request, final HttpContext context, final HttpCacheEntry entry, - final Date now) throws ResourceIOException { + final Instant now) throws ResourceIOException { final SimpleHttpResponse cachedResponse; if (request.containsHeader(HeaderConstants.IF_NONE_MATCH) || request.containsHeader(HeaderConstants.IF_MODIFIED_SINCE)) { @@ -202,7 +202,7 @@ SimpleHttpResponse handleRevalidationFailure( final HttpRequest request, final HttpContext context, final HttpCacheEntry entry, - final Date now) throws IOException { + final Instant now) throws IOException { if (staleResponseNotAllowed(request, entry, now)) { return generateGatewayTimeout(context); } else { @@ -226,7 +226,7 @@ SimpleHttpResponse unvalidatedCacheHit( return cachedResponse; } - boolean staleResponseNotAllowed(final HttpRequest request, final HttpCacheEntry entry, final Date now) { + boolean staleResponseNotAllowed(final HttpRequest request, final HttpCacheEntry entry, final Instant now) { return validityPolicy.mustRevalidate(entry) || (cacheConfig.isSharedCache() && validityPolicy.proxyRevalidate(entry)) || explicitFreshnessRequest(request, entry, now); @@ -244,7 +244,7 @@ boolean mayCallBackend(final HttpRequest request) { return true; } - boolean explicitFreshnessRequest(final HttpRequest request, final HttpCacheEntry entry, final Date now) { + boolean explicitFreshnessRequest(final HttpRequest request, final HttpCacheEntry entry, final Instant now) { final Iterator it = MessageSupport.iterate(request, HeaderConstants.CACHE_CONTROL); while (it.hasNext()) { final HeaderElement elt = it.next(); @@ -313,8 +313,8 @@ boolean supportsRangeAndContentRangeHeaders() { return SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS; } - Date getCurrentDate() { - return new Date(); + Instant getCurrentDate() { + return Instant.now(); } boolean clientRequestsOurOptions(final HttpRequest request) { @@ -340,7 +340,7 @@ boolean revalidationResponseIsTooOld(final HttpResponse backendResponse, final H boolean shouldSendNotModifiedResponse(final HttpRequest request, final HttpCacheEntry responseEntry) { return (suitabilityChecker.isConditional(request) - && suitabilityChecker.allConditionalsMatch(request, responseEntry, new Date())); + && suitabilityChecker.allConditionalsMatch(request, responseEntry, Instant.now())); } boolean staleIfErrorAppliesTo(final int statusCode) { diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpAsyncCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpAsyncCache.java index 6ba926283f..2ad5767099 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpAsyncCache.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpAsyncCache.java @@ -26,7 +26,7 @@ */ package org.apache.hc.client5.http.impl.cache; -import java.util.Date; +import java.time.Instant; import java.util.Map; import org.apache.hc.client5.http.cache.HttpCacheEntry; @@ -79,8 +79,8 @@ Cancellable createCacheEntry( HttpRequest request, HttpResponse originResponse, ByteArrayBuffer content, - Date requestSent, - Date responseReceived, + Instant requestSent, + Instant responseReceived, FutureCallback callback); /** @@ -91,8 +91,8 @@ Cancellable updateCacheEntry( HttpRequest request, HttpCacheEntry stale, HttpResponse originResponse, - Date requestSent, - Date responseReceived, + Instant requestSent, + Instant responseReceived, FutureCallback callback); /** @@ -104,8 +104,8 @@ Cancellable updateVariantCacheEntry( HttpRequest request, HttpResponse originResponse, Variant variant, - Date requestSent, - Date responseReceived, + Instant requestSent, + Instant responseReceived, FutureCallback callback); /** diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpByteArrayCacheEntrySerializer.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpByteArrayCacheEntrySerializer.java index a2aa75d275..ce82e73f13 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpByteArrayCacheEntrySerializer.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpByteArrayCacheEntrySerializer.java @@ -32,7 +32,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.Date; +import java.time.Instant; import java.util.HashMap; import java.util.Map; @@ -150,8 +150,8 @@ public HttpCacheStorageEntry deserialize(final byte[] serializedObject) throws R // Extract metadata pseudo-headers final String storageKey = getCachePseudoHeaderAndRemove(response, SC_HEADER_NAME_STORAGE_KEY); - final Date requestDate = getCachePseudoHeaderDateAndRemove(response, SC_HEADER_NAME_REQUEST_DATE); - final Date responseDate = getCachePseudoHeaderDateAndRemove(response, SC_HEADER_NAME_RESPONSE_DATE); + final Instant requestDate = getCachePseudoHeaderDateAndRemove(response, SC_HEADER_NAME_REQUEST_DATE); + final Instant responseDate = getCachePseudoHeaderDateAndRemove(response, SC_HEADER_NAME_RESPONSE_DATE); final boolean noBody = getCachePseudoHeaderBooleanAndRemove(response, SC_HEADER_NAME_NO_CONTENT); final Map variantMap = getVariantMapPseudoHeadersAndRemove(response); unescapeHeaders(response); @@ -255,8 +255,8 @@ private void unescapeHeaders(final HttpResponse httpResponse) { */ private void addMetadataPseudoHeaders(final HttpResponse httpResponse, final HttpCacheStorageEntry httpCacheEntry) { httpResponse.addHeader(SC_HEADER_NAME_STORAGE_KEY, httpCacheEntry.getKey()); - httpResponse.addHeader(SC_HEADER_NAME_RESPONSE_DATE, Long.toString(httpCacheEntry.getContent().getResponseDate().getTime())); - httpResponse.addHeader(SC_HEADER_NAME_REQUEST_DATE, Long.toString(httpCacheEntry.getContent().getRequestDate().getTime())); + httpResponse.addHeader(SC_HEADER_NAME_RESPONSE_DATE, Long.toString(httpCacheEntry.getContent().getResponseInstant().toEpochMilli())); + httpResponse.addHeader(SC_HEADER_NAME_REQUEST_DATE, Long.toString(httpCacheEntry.getContent().getRequestInstant().toEpochMilli())); // Encode these so map entries are stored in a pair of headers, one for key and one for value. // Header keys look like: {Accept-Encoding=gzip} @@ -308,12 +308,12 @@ private static String getOptionalCachePseudoHeaderAndRemove(final HttpResponse r * @return Value for metadata pseudo-header * @throws ResourceIOException if the given pseudo-header is not found, or contains invalid data */ - private static Date getCachePseudoHeaderDateAndRemove(final HttpResponse response, final String name) throws ResourceIOException{ + private static Instant getCachePseudoHeaderDateAndRemove(final HttpResponse response, final String name) throws ResourceIOException{ final String value = getCachePseudoHeaderAndRemove(response, name); response.removeHeaders(name); try { final long timestamp = Long.parseLong(value); - return new Date(timestamp); + return Instant.ofEpochMilli(timestamp); } catch (final NumberFormatException e) { throw new ResourceIOException("Invalid value for header '" + name + "'", e); } @@ -410,7 +410,7 @@ protected void writeHeadLine( */ private static class NoAgeCacheValidityPolicy extends CacheValidityPolicy { @Override - public TimeValue getCurrentAge(final HttpCacheEntry entry, final Date now) { + public TimeValue getCurrentAge(final HttpCacheEntry entry, final Instant now) { return TimeValue.ZERO_MILLISECONDS; } } diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpCache.java index 66f4af9597..a26005fefe 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpCache.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/HttpCache.java @@ -26,7 +26,7 @@ */ package org.apache.hc.client5.http.impl.cache; -import java.util.Date; +import java.time.Instant; import java.util.Map; import org.apache.hc.client5.http.cache.HttpCacheEntry; @@ -73,8 +73,8 @@ HttpCacheEntry createCacheEntry( HttpRequest request, HttpResponse originResponse, ByteArrayBuffer content, - Date requestSent, - Date responseReceived); + Instant requestSent, + Instant responseReceived); /** * Update a {@link HttpCacheEntry} using a 304 {@link HttpResponse}. @@ -84,8 +84,8 @@ HttpCacheEntry updateCacheEntry( HttpRequest request, HttpCacheEntry stale, HttpResponse originResponse, - Date requestSent, - Date responseReceived); + Instant requestSent, + Instant responseReceived); /** * Update a specific {@link HttpCacheEntry} representing a cached variant @@ -96,8 +96,8 @@ HttpCacheEntry updateVariantCacheEntry( HttpRequest request, HttpResponse originResponse, Variant variant, - Date requestSent, - Date responseReceived); + Instant requestSent, + Instant responseReceived); /** * Specifies cache should reuse the given cached variant to satisfy diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseProtocolCompliance.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseProtocolCompliance.java index 31dec99bd5..cd051afc50 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseProtocolCompliance.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ResponseProtocolCompliance.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.time.Instant; import java.util.ArrayList; -import java.util.Date; import java.util.List; import org.apache.hc.client5.http.ClientProtocolException; @@ -101,8 +100,8 @@ private void warningsWithNonMatchingWarnDatesAreRemoved( boolean modified = false; for(final Header h : warningHeaders) { for(final WarningValue wv : WarningValue.getWarningValues(h)) { - final Date warnDate = wv.getWarnDate(); - if (warnDate == null || warnDate.equals(responseDate)) { + final Instant warnInstant = wv.getWarnDate(); + if (warnInstant == null || warnInstant.equals(responseDate)) { newWarningHeaders.add(new BasicHeader(HeaderConstants.WARNING,wv.toString())); } else { modified = true; diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java index ed76872964..6969e6fea2 100644 --- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java +++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java @@ -26,8 +26,8 @@ */ package org.apache.hc.client5.http.impl.cache; +import java.time.Instant; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -48,7 +48,7 @@ class WarningValue { private int warnCode; private String warnAgent; private String warnText; - private Date warnDate; + private Instant warnDate; WarningValue(final String s) { this(s, 0); @@ -265,7 +265,7 @@ protected void consumeWarnDate() { parseError(); } offs += m.end(); - warnDate = DateUtils.toDate(DateUtils.parseStandardDate(src.substring(curr+1,offs-1))); + warnDate = DateUtils.parseStandardDate(src.substring(curr+1,offs-1)); } /* @@ -342,9 +342,9 @@ private void parseError() { /** Returns the date and time when this warning was added, or * {@code null} if a warning date was not supplied in the * header. - * @return {@link Date} + * @return {@link Instant} */ - public Date getWarnDate() { return warnDate; } + public Instant getWarnDate() { return warnDate; } /** Formats a {@code WarningValue} as a {@link String} * suitable for including in a header. For example, you can: @@ -359,7 +359,7 @@ private void parseError() { public String toString() { if (warnDate != null) { return String.format("%d %s %s \"%s\"", warnCode, - warnAgent, warnText, DateUtils.formatStandardDate(DateUtils.toInstant(warnDate))); + warnAgent, warnText, DateUtils.formatStandardDate(warnDate)); } else { return String.format("%d %s %s", warnCode, warnAgent, warnText); } diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java index 437e2961d9..ef94bfa826 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java @@ -27,7 +27,6 @@ package org.apache.hc.client5.http.cache; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; @@ -66,7 +65,7 @@ public void setUp() { } private HttpCacheEntry makeEntry(final Header[] headers) { - return new HttpCacheEntry(DateUtils.toDate(elevenSecondsAgo), DateUtils.toDate(nineSecondsAgo), + return new HttpCacheEntry(elevenSecondsAgo, nineSecondsAgo, HttpStatus.SC_OK, headers, mockResource); } @@ -110,13 +109,6 @@ public void testGetFirstHeaderReturnsNullIfNoneMatch() { assertNull(entry.getFirstHeader("quux")); } - @Test - public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() { - final Header[] headers = new Header[0]; - entry = makeEntry(headers); - assertFalse(entry.hasVariants()); - } - @Test public void testCacheEntryWithOneVaryHeaderHasVariants() { final Header[] headers = { new BasicHeader("Vary", "User-Agent") }; @@ -140,11 +132,24 @@ public void testCacheEntryWithVaryStarHasVariants(){ assertTrue(entry.hasVariants()); } + + @Test + public void testGetMethodReturnsCorrectRequestMethod() { + final Header[] headers = { new BasicHeader("foo", "fooValue"), + new BasicHeader("bar", "barValue1"), + new BasicHeader("bar", "barValue2") + }; + entry = makeEntry(headers); + assertEquals(HeaderConstants.GET_METHOD, entry.getRequestMethod()); + } + + + @SuppressWarnings("unused") @Test public void mustProvideRequestDate() { try { - new HttpCacheEntry(null, new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource); + new HttpCacheEntry(null, Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource); fail("Should have thrown exception"); } catch (final NullPointerException expected) { } @@ -154,7 +159,7 @@ public void mustProvideRequestDate() { @Test public void mustProvideResponseDate() { try { - new HttpCacheEntry(new Date(), null, HttpStatus.SC_OK, new Header[]{}, mockResource); + new HttpCacheEntry(Instant.now(), null, HttpStatus.SC_OK, new Header[]{}, mockResource); fail("Should have thrown exception"); } catch (final NullPointerException expected) { } @@ -164,7 +169,7 @@ public void mustProvideResponseDate() { @Test public void mustProvideResponseHeaders() { try { - new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, null, mockResource); + new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, null, mockResource); fail("Should have thrown exception"); } catch (final NullPointerException expected) { } @@ -172,27 +177,27 @@ public void mustProvideResponseHeaders() { @Test public void statusCodeComesFromOriginalStatusLine() { - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource); + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource); assertEquals(HttpStatus.SC_OK, entry.getStatus()); } @Test public void canGetOriginalRequestDate() { - final Date requestDate = new Date(); - entry = new HttpCacheEntry(requestDate, new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource); - assertSame(requestDate, entry.getRequestDate()); + final Instant requestDate = Instant.now(); + entry = new HttpCacheEntry(requestDate, Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource); + assertEquals(requestDate, entry.getRequestInstant()); } @Test public void canGetOriginalResponseDate() { - final Date responseDate = new Date(); - entry = new HttpCacheEntry(new Date(), responseDate, HttpStatus.SC_OK, new Header[]{}, mockResource); - assertSame(responseDate, entry.getResponseDate()); + final Instant responseDate = Instant.now(); + entry = new HttpCacheEntry(Instant.now(), responseDate, HttpStatus.SC_OK, new Header[]{}, mockResource); + assertEquals(responseDate, entry.getResponseInstant()); } @Test public void canGetOriginalResource() { - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource); + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource); assertSame(mockResource, entry.getResource()); } @@ -202,7 +207,7 @@ public void canGetOriginalHeaders() { new BasicHeader("Server", "MockServer/1.0"), new BasicHeader("Date", DateUtils.formatStandardDate(now)) }; - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, headers, mockResource); + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, headers, mockResource); final Header[] result = entry.getHeaders(); assertEquals(headers.length, result.length); for(int i=0; i()); } @@ -229,7 +234,7 @@ public void canRetrieveOriginalVariantMap() { final Map variantMap = new HashMap<>(); variantMap.put("A","B"); variantMap.put("C","D"); - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource, variantMap); final Map result = entry.getVariantMap(); @@ -243,7 +248,7 @@ public void retrievedVariantMapIsNotModifiable() { final Map variantMap = new HashMap<>(); variantMap.put("A","B"); variantMap.put("C","D"); - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource, variantMap); final Map result = entry.getVariantMap(); @@ -261,7 +266,7 @@ public void retrievedVariantMapIsNotModifiable() { @Test public void canConvertToString() { - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource); assertNotNull(entry.toString()); assertNotEquals("", entry.toString()); @@ -270,16 +275,16 @@ public void canConvertToString() { @Test public void testMissingDateHeaderIsIgnored() { final Header[] headers = new Header[] {}; - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, - headers, mockResource); + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, + headers, mockResource); assertNull(entry.getDate()); } @Test public void testMalformedDateHeaderIsIgnored() { final Header[] headers = new Header[] { new BasicHeader("Date", "asdf") }; - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, - headers, mockResource); + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, + headers, mockResource); assertNull(entry.getDate()); } @@ -287,20 +292,11 @@ public void testMalformedDateHeaderIsIgnored() { public void testValidDateHeaderIsParsed() { final Instant date = Instant.now().with(ChronoField.MILLI_OF_SECOND, 0); final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatStandardDate(date)) }; - entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, - headers, mockResource); + entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, + headers, mockResource); final Date dateHeaderValue = entry.getDate(); assertNotNull(dateHeaderValue); assertEquals(DateUtils.toDate(date), dateHeaderValue); } - @Test - public void testGetMethodReturnsCorrectRequestMethod() { - final Header[] headers = { new BasicHeader("foo", "fooValue"), - new BasicHeader("bar", "barValue1"), - new BasicHeader("bar", "barValue2") - }; - entry = makeEntry(headers); - assertEquals(HeaderConstants.GET_METHOD, entry.getRequestMethod()); - } } diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpByteArrayCacheEntrySerializerTestUtils.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpByteArrayCacheEntrySerializerTestUtils.java index 2a202592e7..950585f17f 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpByteArrayCacheEntrySerializerTestUtils.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpByteArrayCacheEntrySerializerTestUtils.java @@ -34,8 +34,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.time.Instant; import java.util.Collections; -import java.util.Date; import java.util.Map; import org.apache.hc.client5.http.cache.HttpCacheEntry; @@ -59,8 +59,8 @@ class HttpByteArrayCacheEntrySerializerTestUtils { */ static class HttpCacheStorageEntryTestTemplate { Resource resource; - Date requestDate; - Date responseDate; + Instant requestDate; + Instant responseDate; int responseCode; Header[] responseHeaders; Map variantMap; @@ -120,8 +120,8 @@ private HttpCacheStorageEntryTestTemplate(final HttpCacheStorageEntryTestTemplat private static final HttpCacheStorageEntryTestTemplate DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE = new HttpCacheStorageEntryTestTemplate(); static { DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.resource = new HeapResource("Hello World".getBytes(StandardCharsets.UTF_8)); - DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.requestDate = new Date(165214800000L); - DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.responseDate = new Date(2611108800000L); + DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.requestDate = Instant.ofEpochMilli(165214800000L); + DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.responseDate = Instant.ofEpochMilli(2611108800000L); DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.responseCode = 200; DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.responseHeaders = new Header[]{ new BasicHeader("Content-type", "text/html"), @@ -220,8 +220,9 @@ static void assertCacheEntriesEqual(final HttpCacheStorageEntry expected, final final HttpCacheEntry expectedContent = expected.getContent(); final HttpCacheEntry actualContent = actual.getContent(); - assertEquals(expectedContent.getRequestDate(), actualContent.getRequestDate()); - assertEquals(expectedContent.getResponseDate(), actualContent.getResponseDate()); + assertEquals(expectedContent.getRequestInstant(), actualContent.getRequestInstant()); + assertEquals(expectedContent.getResponseInstant(), actualContent.getResponseInstant()); + assertEquals(expectedContent.getStatus(), actualContent.getStatus()); assertArrayEquals(expectedContent.getVariantMap().keySet().toArray(), actualContent.getVariantMap().keySet().toArray()); diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java index 157abe5014..ec4b742428 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpCacheEntryMatcher.java @@ -26,8 +26,8 @@ */ package org.apache.hc.client5.http.impl.cache; +import java.time.Instant; import java.util.Arrays; -import java.util.Date; import org.apache.hc.client5.http.cache.HttpCacheEntry; import org.apache.hc.client5.http.cache.Resource; @@ -57,16 +57,17 @@ public boolean matches(final Object item) { if (expectedStatus != otherStatus) { return false; } - final Date expectedRequestDate = expectedValue.getRequestDate(); - final Date otherRequestDate = otherValue.getRequestDate(); - if (!LangUtils.equals(expectedRequestDate, otherRequestDate)) { + final Instant expectedRequestInstant = expectedValue.getRequestInstant(); + final Instant otherRequestInstant = otherValue.getRequestInstant(); + if (!LangUtils.equals(expectedRequestInstant, otherRequestInstant)) { return false; } - final Date expectedResponseDate = expectedValue.getResponseDate(); - final Date otherResponseDate = otherValue.getResponseDate(); - if (!LangUtils.equals(expectedResponseDate, otherResponseDate)) { + final Instant expectedResponseInstant = expectedValue.getResponseInstant(); + final Instant otherResponseInstant = otherValue.getResponseInstant(); + if (!LangUtils.equals(expectedResponseInstant, otherResponseInstant)) { return false; } + final Header[] expectedHeaders = expectedValue.getHeaders(); final Header[] otherHeaders = otherValue.getHeaders(); if (expectedHeaders.length != otherHeaders.length) { diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java index 65e5849437..d0703e4e07 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/HttpTestUtils.java @@ -29,7 +29,6 @@ import java.io.InputStream; import java.time.Duration; import java.time.Instant; -import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -268,7 +267,7 @@ public static HttpCacheEntry makeCacheEntry(final Map variantMap) return makeCacheEntry(now, now, getStockHeaders(now), getRandomBytes(128), variantMap); } - + @SuppressWarnings("deprecation") public static HttpCacheEntry makeCacheEntry(final Instant requestDate, final Instant responseDate, final Header[] headers, final byte[] bytes, final Map variantMap) { @@ -295,31 +294,6 @@ public static HttpCacheEntry makeCacheEntry() { return makeCacheEntry(now, now); } - public static HttpCacheEntry makeCacheEntryWithNoRequestMethodOrEntity(final Header... headers) { - final Date now = new Date(); - return new HttpCacheEntry(now, now, HttpStatus.SC_OK, headers, null, null); - } - - public static HttpCacheEntry makeCacheEntryWithNoRequestMethod(final Header... headers) { - final Date now = new Date(); - return new HttpCacheEntry(now, now, HttpStatus.SC_OK, headers, new HeapResource(getRandomBytes(128)), null); - } - - public static HttpCacheEntry make204CacheEntryWithNoRequestMethod(final Header... headers) { - final Date now = new Date(); - return new HttpCacheEntry(now, now, HttpStatus.SC_NO_CONTENT, headers, null, null); - } - - public static HttpCacheEntry makeHeadCacheEntry(final Header... headers) { - final Date now = new Date(); - return new HttpCacheEntry(now, now, HttpStatus.SC_OK, headers, null, null); - } - - public static HttpCacheEntry makeHeadCacheEntryWithNoRequestMethod(final Header... headers) { - final Date now = new Date(); - return new HttpCacheEntry(now, now, HttpStatus.SC_OK, headers, null, null); - } - public static ClassicHttpResponse make200Response() { final ClassicHttpResponse out = new BasicClassicHttpResponse(HttpStatus.SC_OK, "OK"); out.setHeader("Date", DateUtils.formatStandardDate(Instant.now())); @@ -373,4 +347,30 @@ public static Map makeDefaultVariantMap(final String key, final return variants; } + + + public static HttpCacheEntry makeCacheEntryWithNoRequestMethodOrEntity(final Header... headers) { + final Instant now = Instant.now(); + return new HttpCacheEntry(now, now, HttpStatus.SC_OK, headers, null, null); + } + + public static HttpCacheEntry makeCacheEntryWithNoRequestMethod(final Header... headers) { + final Instant now = Instant.now(); + return new HttpCacheEntry(now, now, HttpStatus.SC_OK, headers, new HeapResource(getRandomBytes(128)), null); + } + + public static HttpCacheEntry make204CacheEntryWithNoRequestMethod(final Header... headers) { + final Instant now = Instant.now(); + return new HttpCacheEntry(now, now, HttpStatus.SC_NO_CONTENT, headers, null, null); + } + + public static HttpCacheEntry makeHeadCacheEntry(final Header... headers) { + final Instant now = Instant.now(); + return new HttpCacheEntry(now, now, HttpStatus.SC_OK, headers, null, null); + } + + public static HttpCacheEntry makeHeadCacheEntryWithNoRequestMethod(final Header... headers) { + final Instant now = Instant.now(); + return new HttpCacheEntry(now, now, HttpStatus.SC_OK, headers, null, null); + } } diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java index 5023324903..0322b08755 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestBasicHttpCache.java @@ -34,7 +34,6 @@ import static org.junit.jupiter.api.Assertions.assertSame; import java.time.Instant; -import java.util.Date; import java.util.Map; import org.apache.hc.client5.http.cache.HeaderConstants; @@ -231,7 +230,7 @@ public void testGetCacheEntryReturnsNullIfNoVariantInCache() throws Exception { origResponse.setHeader("Vary", "Accept-Encoding"); origResponse.setHeader("Content-Encoding","gzip"); - impl.createCacheEntry(host, origRequest, origResponse, buf, new Date(), new Date()); + impl.createCacheEntry(host, origRequest, origResponse, buf, Instant.now(), Instant.now()); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); final HttpCacheEntry result = impl.getCacheEntry(host, request); @@ -253,7 +252,7 @@ public void testGetCacheEntryReturnsVariantIfPresentInCache() throws Exception { origResponse.setHeader("Vary", "Accept-Encoding"); origResponse.setHeader("Content-Encoding","gzip"); - impl.createCacheEntry(host, origRequest, origResponse, buf, new Date(), new Date()); + impl.createCacheEntry(host, origRequest, origResponse, buf, Instant.now(), Instant.now()); final HttpRequest request = new HttpGet("http://foo.example.com/bar"); request.setHeader("Accept-Encoding","gzip"); @@ -297,8 +296,8 @@ public void testGetVariantCacheEntriesReturnsAllVariants() throws Exception { resp2.setHeader("Content-Encoding","gzip"); resp2.setHeader("Vary", "Accept-Encoding"); - impl.createCacheEntry(host, req1, resp1, null, new Date(), new Date()); - impl.createCacheEntry(host, req2, resp2, null, new Date(), new Date()); + impl.createCacheEntry(host, req1, resp1, null, Instant.now(), Instant.now()); + impl.createCacheEntry(host, req2, resp2, null, Instant.now(), Instant.now()); final Map variants = impl.getVariantCacheEntriesWithEtags(host, req1); diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestByteArrayCacheEntrySerializer.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestByteArrayCacheEntrySerializer.java index e2a3a25a4f..81cb9b37e3 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestByteArrayCacheEntrySerializer.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestByteArrayCacheEntrySerializer.java @@ -37,6 +37,7 @@ import java.io.ObjectOutputStream; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; +import java.time.Instant; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -61,7 +62,12 @@ public void setUp() { } @Test - public void canSerializeEntriesWithVariantMaps() throws Exception { + public void canSerializeEntriesWithVariantMapsDeprecatedConstructor() throws Exception { + readWriteVerify(makeCacheEntryDeprecatedConstructorWithVariantMap("somekey")); + } + + @Test + public void canSerializeEntriesWithVariantMapsAndInstant() throws Exception { readWriteVerify(makeCacheEntryWithVariantMap("somekey")); } @@ -85,6 +91,11 @@ public void isAllowedClassNameDataTrue() { assertIsAllowedClassNameTrue(Date.class.getName()); } + @Test + public void isAllowedClassNameInstantTrue() { + assertIsAllowedClassNameTrue(Instant.class.getName()); + } + @Test public void isAllowedClassNameStatusLineTrue() { assertIsAllowedClassNameTrue(StatusLine.class.getName()); @@ -257,6 +268,27 @@ public void readWriteVerify(final HttpCacheStorageEntry writeEntry) throws Excep assertThat(readEntry.getContent(), HttpCacheEntryMatcher.equivalent(writeEntry.getContent())); } + + private HttpCacheStorageEntry makeCacheEntryDeprecatedConstructorWithVariantMap(final String key) { + final Header[] headers = new Header[5]; + for (int i = 0; i < headers.length; i++) { + headers[i] = new BasicHeader("header" + i, "value" + i); + } + final String body = "Lorem ipsum dolor sit amet"; + + final Map variantMap = new HashMap<>(); + variantMap.put("test variant 1","true"); + variantMap.put("test variant 2","true"); + final HttpCacheEntry cacheEntry = new HttpCacheEntry( + Instant.now(), + Instant.now(), + HttpStatus.SC_OK, + headers, + new HeapResource(body.getBytes(StandardCharsets.UTF_8)), variantMap); + + return new HttpCacheStorageEntry(key, cacheEntry); + } + private HttpCacheStorageEntry makeCacheEntryWithVariantMap(final String key) { final Header[] headers = new Header[5]; for (int i = 0; i < headers.length; i++) { @@ -268,8 +300,8 @@ private HttpCacheStorageEntry makeCacheEntryWithVariantMap(final String key) { variantMap.put("test variant 1","true"); variantMap.put("test variant 2","true"); final HttpCacheEntry cacheEntry = new HttpCacheEntry( - new Date(), - new Date(), + Instant.now(), + Instant.now(), HttpStatus.SC_OK, headers, new HeapResource(body.getBytes(StandardCharsets.UTF_8)), variantMap); diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheUpdateHandler.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheUpdateHandler.java index 24702886dc..cb72d9e40b 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheUpdateHandler.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheUpdateHandler.java @@ -34,7 +34,6 @@ import java.io.IOException; import java.time.Instant; -import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -83,7 +82,7 @@ public void testUpdateCacheEntryReturnsDifferentEntryInstance() throws IOException { entry = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry, - DateUtils.toDate(requestDate), DateUtils.toDate(responseDate), response); + requestDate, responseDate, response); assertNotSame(newEntry, entry); } @@ -96,7 +95,7 @@ public void testHeadersAreMergedCorrectly() throws IOException { response.setHeaders(); final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, - new Date(), new Date(), response); + Instant.now(), Instant.now(), response); assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatStandardDate(responseDate))); assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\"")); @@ -116,7 +115,7 @@ public void testNewerHeadersReplaceExistingHeaders() throws IOException { new BasicHeader("Cache-Control", "public")); final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, - new Date(), new Date(), response); + Instant.now(), Instant.now(), response); assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatStandardDate(requestDate))); assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\"")); @@ -136,7 +135,7 @@ public void testNewHeadersAreAddedByMerge() throws IOException { new BasicHeader("Cache-Control", "public")); final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, - new Date(), new Date(), response); + Instant.now(), Instant.now(), response); assertThat(updatedEntry, ContainsHeaderMatcher.contains("Date", DateUtils.formatStandardDate(requestDate))); assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\"")); @@ -154,8 +153,8 @@ public void oldHeadersRetainedIfResponseOlderThanEntry() entry = HttpTestUtils.makeCacheEntry(twoSecondsAgo, now, headers); response.setHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)); response.setHeader("ETag", "\"old-etag\""); - final HttpCacheEntry result = impl.updateCacheEntry("A", entry, new Date(), - new Date(), response); + final HttpCacheEntry result = impl.updateCacheEntry("A", entry, Instant.now(), + Instant.now(), response); assertThat(result, ContainsHeaderMatcher.contains("Date", DateUtils.formatStandardDate(oneSecondAgo))); assertThat(result, ContainsHeaderMatcher.contains("ETag", "\"new-etag\"")); } @@ -165,10 +164,10 @@ public void testUpdatedEntryHasLatestRequestAndResponseDates() throws IOException { entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo); final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, - DateUtils.toDate(twoSecondsAgo), DateUtils.toDate(oneSecondAgo), response); + twoSecondsAgo, oneSecondAgo, response); - assertEquals(DateUtils.toDate(twoSecondsAgo), updated.getRequestDate()); - assertEquals(DateUtils.toDate(oneSecondAgo), updated.getResponseDate()); + assertEquals(twoSecondsAgo, updated.getRequestInstant()); + assertEquals(oneSecondAgo, updated.getResponseInstant()); } @Test @@ -182,7 +181,7 @@ public void entry1xxWarningsAreRemovedOnUpdate() throws Exception { response.setHeader("ETag", "\"new\""); response.setHeader("Date", DateUtils.formatStandardDate(twoSecondsAgo)); final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, - DateUtils.toDate(twoSecondsAgo), DateUtils.toDate(oneSecondAgo), response); + twoSecondsAgo, oneSecondAgo, response); assertEquals(0, updated.getHeaders("Warning").length); } @@ -197,7 +196,7 @@ public void entryWithMalformedDateIsStillUpdated() throws Exception { response.setHeader("ETag", "\"new\""); response.setHeader("Date", DateUtils.formatStandardDate(twoSecondsAgo)); final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, - DateUtils.toDate(twoSecondsAgo), DateUtils.toDate(oneSecondAgo), response); + twoSecondsAgo, oneSecondAgo, response); assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue()); } @@ -211,8 +210,8 @@ public void entryIsStillUpdatedByResponseWithMalformedDate() throws Exception { entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers); response.setHeader("ETag", "\"new\""); response.setHeader("Date", "bad-date"); - final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, - DateUtils.toDate(twoSecondsAgo), DateUtils.toDate(oneSecondAgo), response); + final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, twoSecondsAgo, + oneSecondAgo, response); assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue()); } @@ -222,7 +221,7 @@ public void cannotUpdateFromANon304OriginResponse() throws Exception { entry = HttpTestUtils.makeCacheEntry(); response = new BasicHttpResponse(HttpStatus.SC_OK, "OK"); try { - impl.updateCacheEntry("A", entry, new Date(), new Date(), + impl.updateCacheEntry("A", entry, Instant.now(), Instant.now(), response); fail("should have thrown exception"); } catch (final IllegalArgumentException expected) { @@ -261,7 +260,7 @@ public void testContentEncodingHeaderIsNotUpdatedByMerge() throws IOException { new BasicHeader("Content-Encoding", "gzip")); final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, - new Date(), new Date(), response); + Instant.now(), Instant.now(), response); final Header[] updatedHeaders = updatedEntry.getHeaders(); headersContain(updatedHeaders, "Content-Encoding", "identity"); @@ -281,7 +280,7 @@ public void testContentLengthIsNotAddedWhenTransferEncodingIsPresent() throws IO new BasicHeader("Content-Length", "0")); final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, - new Date(), new Date(), response); + Instant.now(), Instant.now(), response); final Header[] updatedHeaders = updatedEntry.getHeaders(); headersContain(updatedHeaders, "Transfer-Encoding", "chunked"); diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheValidityPolicy.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheValidityPolicy.java index 63722228ac..60dc0f7d6b 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheValidityPolicy.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCacheValidityPolicy.java @@ -33,7 +33,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.time.Instant; -import java.util.Date; import org.apache.hc.client5.http.cache.HttpCacheEntry; import org.apache.hc.client5.http.utils.DateUtils; @@ -141,7 +140,7 @@ protected TimeValue getResponseDelay(final HttpCacheEntry ent) { @Test public void testResidentTimeSecondsIsTimeSinceResponseTime() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, sixSecondsAgo); - assertEquals(TimeValue.ofSeconds(6), impl.getResidentTime(entry, DateUtils.toDate(now))); + assertEquals(TimeValue.ofSeconds(6), impl.getResidentTime(entry, now)); } @Test @@ -153,11 +152,11 @@ protected TimeValue getCorrectedInitialAge(final HttpCacheEntry ent) { return TimeValue.ofSeconds(11); } @Override - protected TimeValue getResidentTime(final HttpCacheEntry ent, final Date d) { + protected TimeValue getResidentTime(final HttpCacheEntry ent, final Instant d) { return TimeValue.ofSeconds(17); } }; - assertEquals(TimeValue.ofSeconds(28), impl.getCurrentAge(entry, new Date())); + assertEquals(TimeValue.ofSeconds(28), impl.getCurrentAge(entry, Instant.now())); } @Test @@ -250,9 +249,9 @@ public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); impl = new CacheValidityPolicy() { @Override - public TimeValue getCurrentAge(final HttpCacheEntry e, final Date d) { + public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) { assertSame(entry, e); - assertEquals(DateUtils.toDate(now), d); + assertEquals(now, d); return TimeValue.ofSeconds(6); } @Override @@ -261,7 +260,7 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry e) { return TimeValue.ofSeconds(10); } }; - assertTrue(impl.isResponseFresh(entry, DateUtils.toDate(now))); + assertTrue(impl.isResponseFresh(entry, now)); } @Test @@ -269,8 +268,8 @@ public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); impl = new CacheValidityPolicy() { @Override - public TimeValue getCurrentAge(final HttpCacheEntry e, final Date d) { - assertEquals(DateUtils.toDate(now), d); + public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) { + assertEquals(now, d); assertSame(entry, e); return TimeValue.ofSeconds(6); } @@ -280,7 +279,7 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry e) { return TimeValue.ofSeconds(6); } }; - assertFalse(impl.isResponseFresh(entry, DateUtils.toDate(now))); + assertFalse(impl.isResponseFresh(entry, now)); } @Test @@ -288,8 +287,8 @@ public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() { final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); impl = new CacheValidityPolicy() { @Override - public TimeValue getCurrentAge(final HttpCacheEntry e, final Date d) { - assertEquals(DateUtils.toDate(now), d); + public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) { + assertEquals(now, d); assertSame(entry, e); return TimeValue.ofSeconds(10); } @@ -299,7 +298,7 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry e) { return TimeValue.ofSeconds(6); } }; - assertFalse(impl.isResponseFresh(entry, DateUtils.toDate(now))); + assertFalse(impl.isResponseFresh(entry, now)); } @Test @@ -421,7 +420,7 @@ public void testMayReturnStaleIfErrorInResponseIsTrueWithinStaleness(){ }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpRequest req = new BasicHttpRequest("GET","/"); - assertTrue(impl.mayReturnStaleIfError(req, entry, DateUtils.toDate(now))); + assertTrue(impl.mayReturnStaleIfError(req, entry, now)); } @Test @@ -433,7 +432,7 @@ public void testMayReturnStaleIfErrorInRequestIsTrueWithinStaleness(){ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpRequest req = new BasicHttpRequest("GET","/"); req.setHeader("Cache-Control","stale-if-error=15"); - assertTrue(impl.mayReturnStaleIfError(req, entry, DateUtils.toDate(now))); + assertTrue(impl.mayReturnStaleIfError(req, entry, now)); } @Test @@ -444,7 +443,7 @@ public void testMayNotReturnStaleIfErrorInResponseAndAfterResponseWindow(){ }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpRequest req = new BasicHttpRequest("GET","/"); - assertFalse(impl.mayReturnStaleIfError(req, entry, DateUtils.toDate(now))); + assertFalse(impl.mayReturnStaleIfError(req, entry, now)); } @Test @@ -456,7 +455,7 @@ public void testMayNotReturnStaleIfErrorInResponseAndAfterRequestWindow(){ final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpRequest req = new BasicHttpRequest("GET","/"); req.setHeader("Cache-Control","stale-if-error=1"); - assertFalse(impl.mayReturnStaleIfError(req, entry, DateUtils.toDate(now))); + assertFalse(impl.mayReturnStaleIfError(req, entry, now)); } @Test @@ -464,7 +463,7 @@ public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveIsAbsent() { final Header[] headers = new Header[] { new BasicHeader("Cache-control", "public") }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); - assertFalse(impl.mayReturnStaleWhileRevalidating(entry, DateUtils.toDate(now))); + assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now)); } @Test @@ -475,7 +474,7 @@ public void testMayReturnStaleWhileRevalidatingIsTrueWhenWithinStaleness() { }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); - assertTrue(impl.mayReturnStaleWhileRevalidating(entry, DateUtils.toDate(now))); + assertTrue(impl.mayReturnStaleWhileRevalidating(entry, now)); } @Test @@ -487,7 +486,7 @@ public void testMayReturnStaleWhileRevalidatingIsFalseWhenPastStaleness() { }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); - assertFalse(impl.mayReturnStaleWhileRevalidating(entry, DateUtils.toDate(now))); + assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now)); } @Test @@ -498,6 +497,6 @@ public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveEmpty() { }; final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); - assertFalse(impl.mayReturnStaleWhileRevalidating(entry, DateUtils.toDate(now))); + assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now)); } } diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java index fec7719621..7f4396f2fc 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java @@ -32,7 +32,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Date; +import java.time.Instant; import java.util.HashMap; import org.apache.hc.client5.http.async.methods.SimpleHttpResponse; @@ -112,7 +112,7 @@ public void testAgeHeaderIsPopulatedWithCurrentAgeOfCacheEntryIfNonZero() throws final SimpleHttpResponse response = impl.generateResponse(request, entry); - verify(mockValidityPolicy).getCurrentAge(same(entry), isA(Date.class)); + verify(mockValidityPolicy).getCurrentAge(same(entry), isA(Instant.class)); final Header ageHdr = response.getFirstHeader("Age"); Assertions.assertNotNull(ageHdr); @@ -125,7 +125,7 @@ public void testAgeHeaderIsNotPopulatedIfCurrentAgeOfCacheEntryIsZero() throws E final SimpleHttpResponse response = impl.generateResponse(request, entry); - verify(mockValidityPolicy).getCurrentAge(same(entry), isA(Date.class)); + verify(mockValidityPolicy).getCurrentAge(same(entry), isA(Instant.class)); final Header ageHdr = response.getFirstHeader("Age"); Assertions.assertNull(ageHdr); @@ -137,7 +137,7 @@ public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() throws Except final SimpleHttpResponse response = impl.generateResponse(request, entry); - verify(mockValidityPolicy).getCurrentAge(same(entry), isA(Date.class)); + verify(mockValidityPolicy).getCurrentAge(same(entry), isA(Instant.class)); final Header ageHdr = response.getFirstHeader("Age"); Assertions.assertNotNull(ageHdr); @@ -147,7 +147,7 @@ public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() throws Except private void currentAge(final TimeValue age) { when( mockValidityPolicy.getCurrentAge(same(entry), - isA(Date.class))).thenReturn(age); + isA(Instant.class))).thenReturn(age); } @Test diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedResponseSuitabilityChecker.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedResponseSuitabilityChecker.java index 32cc5fe3fb..ab1ee84737 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedResponseSuitabilityChecker.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedResponseSuitabilityChecker.java @@ -78,7 +78,7 @@ public void testNotSuitableIfContentLengthHeaderIsWrong() { new BasicHeader("Content-Length","1") }; entry = getEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -89,7 +89,7 @@ public void testSuitableIfCacheEntryIsFresh() { new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -100,7 +100,7 @@ public void testNotSuitableIfCacheEntryIsNotFresh() { new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -112,7 +112,7 @@ public void testNotSuitableIfRequestHasNoCache() { new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -124,7 +124,7 @@ public void testNotSuitableIfAgeExceedsRequestMaxAge() { new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -136,7 +136,7 @@ public void testSuitableIfFreshAndAgeIsUnderRequestMaxAge() { new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -148,7 +148,7 @@ public void testSuitableIfFreshAndFreshnessLifetimeGreaterThanRequestMinFresh() new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -160,7 +160,7 @@ public void testNotSuitableIfFreshnessLifetimeLessThanRequestMinFresh() { new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -172,7 +172,7 @@ public void testSuitableEvenIfStaleButPermittedByRequestMaxStale() { new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -184,7 +184,7 @@ public void testNotSuitableIfStaleButTooStaleForRequestMaxStale() { new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @@ -197,7 +197,7 @@ public void testMalformedCacheControlMaxAgeRequestHeaderCausesUnsuitableEntry() new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -209,7 +209,7 @@ public void testMalformedCacheControlMinFreshRequestHeaderCausesUnsuitableEntry( new BasicHeader("Content-Length","128") }; entry = getEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -230,7 +230,7 @@ public void testSuitableIfCacheEntryIsHeuristicallyFreshEnough() { .setHeuristicCoefficient(0.1f).build(); impl = new CachedResponseSuitabilityChecker(config); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -248,7 +248,7 @@ public void testSuitableIfCacheEntryIsHeuristicallyFreshEnoughByDefault() { .build(); impl = new CachedResponseSuitabilityChecker(config); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -261,7 +261,7 @@ public void testSuitableIfRequestMethodisHEAD() { }; entry = getEntry(headers); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, headRequest, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, headRequest, entry, now)); } @Test @@ -273,7 +273,7 @@ public void testNotSuitableIfRequestMethodIsGETAndEntryResourceIsNull() { }; entry = HttpTestUtils.makeHeadCacheEntry(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -286,7 +286,7 @@ public void testNotSuitableForGETIfEntryDoesNotSpecifyARequestMethodOrEntity() { }; entry = HttpTestUtils.makeCacheEntryWithNoRequestMethodOrEntity(headers); - Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -299,7 +299,7 @@ public void testSuitableForGETIfEntryDoesNotSpecifyARequestMethodButContainsEnti }; entry = HttpTestUtils.makeCacheEntryWithNoRequestMethod(headers); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -311,7 +311,7 @@ public void testSuitableForGETIfHeadResponseCachingEnabledAndEntryDoesNotSpecify }; entry = HttpTestUtils.make204CacheEntryWithNoRequestMethod(headers); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now)); } @Test @@ -325,6 +325,6 @@ public void testSuitableForHEADIfHeadResponseCachingEnabledAndEntryDoesNotSpecif }; entry = HttpTestUtils.makeHeadCacheEntryWithNoRequestMethod(headers); - Assertions.assertTrue(impl.canCachedResponseBeUsed(host, headRequest, entry, DateUtils.toDate(now))); + Assertions.assertTrue(impl.canCachedResponseBeUsed(host, headRequest, entry, now)); } } diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java index 53630fc54c..0a3db1636b 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java @@ -1009,8 +1009,7 @@ public void testTooLargeResponsesAreNotCached() throws Exception { originResponse.setHeader("ETag", "\"etag\""); final ExecChain.Scope scope = new ExecChain.Scope("test", route, request, mockExecRuntime, context); - impl.cacheAndReturnResponse(host, request, originResponse, scope, - DateUtils.toDate(requestSent), DateUtils.toDate(responseReceived)); + impl.cacheAndReturnResponse(host, request, originResponse, scope, requestSent, responseReceived); Mockito.verify(cache, Mockito.never()).createCacheEntry( Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); @@ -1043,12 +1042,11 @@ public void testSmallEnoughResponsesAreCached() throws Exception { RequestEquivalent.eq(request), ResponseEquivalent.eq(response), Mockito.any(), - Mockito.eq(DateUtils.toDate(requestSent)), - Mockito.eq(DateUtils.toDate(responseReceived)))).thenReturn(httpCacheEntry); + Mockito.eq(requestSent), + Mockito.eq(responseReceived))).thenReturn(httpCacheEntry); final ExecChain.Scope scope = new ExecChain.Scope("test", route, request, mockExecRuntime, context); - impl.cacheAndReturnResponse(host, request, originResponse, scope, - DateUtils.toDate(requestSent), DateUtils.toDate(responseReceived)); + impl.cacheAndReturnResponse(host, request, originResponse, scope, requestSent, responseReceived); Mockito.verify(mockCache).createCacheEntry( Mockito.any(), diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpByteArrayCacheEntrySerializer.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpByteArrayCacheEntrySerializer.java index 613e19d5b1..19f3cb508a 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpByteArrayCacheEntrySerializer.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestHttpByteArrayCacheEntrySerializer.java @@ -82,6 +82,98 @@ public void before() { serializer = HttpByteArrayCacheEntrySerializer.INSTANCE; } + /** + * Deserialize a cache entry in a bad format, expecting an exception. + * + * @throws Exception is expected + */ + @Test + public void testInvalidCacheEntry() throws Exception { + // This file is a JPEG not a cache entry, so should fail to deserialize + final byte[] bytes = readTestFileBytes(TEST_CONTENT_FILE_NAME); + Assertions.assertThrows(ResourceIOException.class, () -> + httpCacheStorageEntryFromBytes(serializer, bytes)); + } + + /** + * Deserialize a cache entry with a missing header, from a previously saved file. + * + * @throws Exception is expected + */ + @Test + public void testMissingHeaderCacheEntry() throws Exception { + // This file hand-edited to be missing a necessary header + final byte[] bytes = readTestFileBytes(MISSING_HEADER_TEST_SERIALIZED_NAME); + Assertions.assertThrows(ResourceIOException.class, () -> + httpCacheStorageEntryFromBytes(serializer, bytes)); + } + + /** + * Deserialize a cache entry with an invalid header value, from a previously saved file. + * + * @throws Exception is expected + */ + @Test + public void testInvalidHeaderCacheEntry() throws Exception { + // This file hand-edited to have an invalid header + final byte[] bytes = readTestFileBytes(INVALID_HEADER_TEST_SERIALIZED_NAME); + Assertions.assertThrows(ResourceIOException.class, () -> + httpCacheStorageEntryFromBytes(serializer, bytes)); + } + + /** + * Deserialize a cache entry with a missing variant map key, from a previously saved file. + * + * @throws Exception is expected + */ + @Test + public void testVariantMapMissingKeyCacheEntry() throws Exception { + // This file hand-edited to be missing a VariantCache key + final byte[] bytes = readTestFileBytes(VARIANTMAP_MISSING_KEY_TEST_SERIALIZED_NAME); + Assertions.assertThrows(ResourceIOException.class, () -> + httpCacheStorageEntryFromBytes(serializer, bytes)); + } + + /** + * Deserialize a cache entry with a missing variant map value, from a previously saved file. + * + * @throws Exception is expected + */ + @Test + public void testVariantMapMissingValueCacheEntry() throws Exception { + // This file hand-edited to be missing a VariantCache value + final byte[] bytes = readTestFileBytes(VARIANTMAP_MISSING_VALUE_TEST_SERIALIZED_NAME); + Assertions.assertThrows(ResourceIOException.class, () -> + httpCacheStorageEntryFromBytes(serializer, bytes)); + } + + /** + * Test an IOException being thrown while deserializing. + * + * @throws Exception is expected + */ + @Test + public void testDeserializeWithIOException() throws Exception { + final AbstractMessageParser throwyParser = Mockito.mock(AbstractMessageParser.class); + Mockito. + doThrow(new IOException("Test Exception")). + when(throwyParser). + parse(Mockito.any(SessionInputBuffer.class), Mockito.any(InputStream.class)); + + final HttpByteArrayCacheEntrySerializer testSerializer = new HttpByteArrayCacheEntrySerializer() { + @Override + protected AbstractMessageParser makeHttpResponseParser() { + return throwyParser; + } + }; + Assertions.assertThrows(ResourceIOException.class, () -> + testSerializer.deserialize(new byte[0])); + } + + + ////////////// Using new Constructor with Instant ////////////// + + /** * Serialize and deserialize a simple object with a tiny body. * @@ -194,10 +286,9 @@ public void testEscapedHeaders() throws Exception { /** * Attempt to store a cache entry with a null storage key. * - * @throws Exception is expected */ @Test - public void testNullStorageKey() throws Exception { + public void testNullStorageKey() { final HttpCacheStorageEntryTestTemplate cacheObjectValues = HttpCacheStorageEntryTestTemplate.makeDefault(); cacheObjectValues.storageKey = null; @@ -291,71 +382,6 @@ public void noBodyTestFromPreviouslySerialized() throws Exception { verifyHttpCacheEntryFromTestFile(serializer, testEntry, NO_BODY_TEST_SERIALIZED_NAME, reserializeFiles); } - /** - * Deserialize a cache entry in a bad format, expecting an exception. - * - * @throws Exception is expected - */ - @Test - public void testInvalidCacheEntry() throws Exception { - // This file is a JPEG not a cache entry, so should fail to deserialize - final byte[] bytes = readTestFileBytes(TEST_CONTENT_FILE_NAME); - Assertions.assertThrows(ResourceIOException.class, () -> - httpCacheStorageEntryFromBytes(serializer, bytes)); - } - - /** - * Deserialize a cache entry with a missing header, from a previously saved file. - * - * @throws Exception is expected - */ - @Test - public void testMissingHeaderCacheEntry() throws Exception { - // This file hand-edited to be missing a necessary header - final byte[] bytes = readTestFileBytes(MISSING_HEADER_TEST_SERIALIZED_NAME); - Assertions.assertThrows(ResourceIOException.class, () -> - httpCacheStorageEntryFromBytes(serializer, bytes)); - } - - /** - * Deserialize a cache entry with an invalid header value, from a previously saved file. - * - * @throws Exception is expected - */ - @Test - public void testInvalidHeaderCacheEntry() throws Exception { - // This file hand-edited to have an invalid header - final byte[] bytes = readTestFileBytes(INVALID_HEADER_TEST_SERIALIZED_NAME); - Assertions.assertThrows(ResourceIOException.class, () -> - httpCacheStorageEntryFromBytes(serializer, bytes)); - } - - /** - * Deserialize a cache entry with a missing variant map key, from a previously saved file. - * - * @throws Exception is expected - */ - @Test - public void testVariantMapMissingKeyCacheEntry() throws Exception { - // This file hand-edited to be missing a VariantCache key - final byte[] bytes = readTestFileBytes(VARIANTMAP_MISSING_KEY_TEST_SERIALIZED_NAME); - Assertions.assertThrows(ResourceIOException.class, () -> - httpCacheStorageEntryFromBytes(serializer, bytes)); - } - - /** - * Deserialize a cache entry with a missing variant map value, from a previously saved file. - * - * @throws Exception is expected - */ - @Test - public void testVariantMapMissingValueCacheEntry() throws Exception { - // This file hand-edited to be missing a VariantCache value - final byte[] bytes = readTestFileBytes(VARIANTMAP_MISSING_VALUE_TEST_SERIALIZED_NAME); - Assertions.assertThrows(ResourceIOException.class, () -> - httpCacheStorageEntryFromBytes(serializer, bytes)); - } - /** * Test an HttpException being thrown while serializing. * @@ -382,26 +408,5 @@ protected AbstractMessageWriter makeHttpResponseWriter(final testSerializer.serialize(testEntry)); } - /** - * Test an IOException being thrown while deserializing. - * - * @throws Exception is expected - */ - @Test - public void testDeserializeWithIOException() throws Exception { - final AbstractMessageParser throwyParser = Mockito.mock(AbstractMessageParser.class); - Mockito. - doThrow(new IOException("Test Exception")). - when(throwyParser). - parse(Mockito.any(SessionInputBuffer.class), Mockito.any(InputStream.class)); - final HttpByteArrayCacheEntrySerializer testSerializer = new HttpByteArrayCacheEntrySerializer() { - @Override - protected AbstractMessageParser makeHttpResponseParser() { - return throwyParser; - } - }; - Assertions.assertThrows(ResourceIOException.class, () -> - testSerializer.deserialize(new byte[0])); - } } diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestWarningValue.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestWarningValue.java index bab22f163d..e9b661ff79 100644 --- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestWarningValue.java +++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestWarningValue.java @@ -204,7 +204,7 @@ public void testConstructWarnValueWithAscTimeWarnDate() throws Exception { Assertions.assertEquals("fred", impl.getWarnAgent()); Assertions.assertEquals("\"stale\"", impl.getWarnText()); final Instant target = DateUtils.parseStandardDate("Sun Nov 6 08:49:37 1994"); - Assertions.assertEquals(target, DateUtils.toInstant(impl.getWarnDate())); + Assertions.assertEquals(target, impl.getWarnDate()); } @Test @@ -214,7 +214,7 @@ public void testConstructWarnValueWithRFC850WarnDate() throws Exception { Assertions.assertEquals("fred", impl.getWarnAgent()); Assertions.assertEquals("\"stale\"", impl.getWarnText()); final Instant target = DateUtils.parseStandardDate("Sunday, 06-Nov-94 08:49:37 GMT"); - Assertions.assertEquals(target, DateUtils.toInstant(impl.getWarnDate())); + Assertions.assertEquals(target, impl.getWarnDate()); } @Test @@ -224,7 +224,7 @@ public void testConstructWarnValueWithRFC1123WarnDate() throws Exception { Assertions.assertEquals("fred", impl.getWarnAgent()); Assertions.assertEquals("\"stale\"", impl.getWarnText()); final Instant target = DateUtils.parseStandardDate("Sun, 06 Nov 1994 08:49:37 GMT"); - Assertions.assertEquals(target, DateUtils.toInstant(impl.getWarnDate())); + Assertions.assertEquals(target, impl.getWarnDate()); } } diff --git a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java index ea4b09461e..8e2bbf1778 100644 --- a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java +++ b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java @@ -33,6 +33,7 @@ import java.net.URISyntaxException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; @@ -260,21 +261,48 @@ ClassicHttpRequest getRequest() { return request; } + /** + * @deprecated Use {@link #setDate(Instant)} + */ + @Deprecated public Request setDate(final Date date) { this.request.setHeader(HttpHeader.DATE, DateUtils.formatStandardDate(DateUtils.toInstant(date))); return this; } + /** + * @deprecated Use {@link #setIfModifiedSince(Instant)} + */ + @Deprecated public Request setIfModifiedSince(final Date date) { this.request.setHeader(HttpHeader.IF_MODIFIED_SINCE, DateUtils.formatStandardDate(DateUtils.toInstant(date))); return this; } + /** + * @deprecated Use {@link #setIfUnmodifiedSince(Instant)} + */ + @Deprecated public Request setIfUnmodifiedSince(final Date date) { this.request.setHeader(HttpHeader.IF_UNMODIFIED_SINCE, DateUtils.formatStandardDate(DateUtils.toInstant(date))); return this; } + public Request setDate(final Instant instant) { + this.request.setHeader(HttpHeader.DATE, DateUtils.formatStandardDate(instant)); + return this; + } + + public Request setIfModifiedSince(final Instant instant) { + this.request.setHeader(HttpHeader.IF_MODIFIED_SINCE, DateUtils.formatStandardDate(instant)); + return this; + } + + public Request setIfUnmodifiedSince(final Instant instant) { + this.request.setHeader(HttpHeader.IF_UNMODIFIED_SINCE, DateUtils.formatStandardDate(instant)); + return this; + } + //// HTTP protocol parameter operations public Request version(final HttpVersion version) { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java b/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java index b3a78605a9..7696a28368 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java @@ -248,7 +248,7 @@ public String toString() { public static RequestConfig.Builder custom() { return new Builder(); } - + @SuppressWarnings("deprecation") public static RequestConfig.Builder copy(final RequestConfig config) { return new Builder() .setExpectContinueEnabled(config.isExpectContinueEnabled()) diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/BasicCookieStore.java b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/BasicCookieStore.java index a3d6e2b961..3f1001361f 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/BasicCookieStore.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/BasicCookieStore.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; +import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; @@ -83,7 +84,7 @@ public void addCookie(final Cookie cookie) { try { // first remove any old cookie that is equivalent cookies.remove(cookie); - if (!cookie.isExpired(new Date())) { + if (!cookie.isExpired(Instant.now())) { cookies.add(cookie); } } finally { @@ -136,6 +137,7 @@ public List getCookies() { * @see Cookie#isExpired(Date) */ @Override + @SuppressWarnings("deprecation") public boolean clearExpired(final Date date) { if (date == null) { return false; @@ -155,6 +157,34 @@ public boolean clearExpired(final Date date) { } } + /** + * Removes all of {@link Cookie cookies} in this HTTP state that have expired by the specified + * {@link Instant date}. + * + * @return true if any cookies were purged. + * @see Cookie#isExpired(Instant) + * @since 5.2 + */ + @Override + public boolean clearExpired(final Instant instant) { + if (instant == null) { + return false; + } + lock.writeLock().lock(); + try { + boolean removed = false; + for (final Iterator it = cookies.iterator(); it.hasNext(); ) { + if (it.next().isExpired(instant)) { + it.remove(); + removed = true; + } + } + return removed; + } finally { + lock.writeLock().unlock(); + } + } + /** * Clears all cookies. */ diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/Cookie.java b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/Cookie.java index e2ee347a07..2eae943643 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/Cookie.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/Cookie.java @@ -27,6 +27,7 @@ package org.apache.hc.client5.http.cookie; +import java.time.Instant; import java.util.Date; /** @@ -77,9 +78,26 @@ public interface Cookie { * considered immutable. Changing it (e.g. using setTime()) could result * in undefined behaviour. Do so at your peril.

* @return Expiration {@link Date}, or {@code null}. + * @deprecated Use {{@link #getExpiryInstant()}} */ + @Deprecated Date getExpiryDate(); + /** + * Returns the expiration {@link Instant} of the cookie, or {@code null} if none exists. + *

Note: the object returned by this method is + * considered immutable. Changing it (e.g. using setTime()) could result in undefined behaviour. + * Do so at your peril.

+ * + * @return Expiration {@link Instant}, or {@code null}. + * @since 5.2 + */ + @SuppressWarnings("deprecated") + default Instant getExpiryInstant() { + final Date date = getExpiryDate(); + return date != null ? Instant.ofEpochMilli(date.getTime()) : null; + } + /** * Returns {@code false} if the cookie should be discarded at the end * of the "session"; {@code true} otherwise. @@ -119,14 +137,35 @@ public interface Cookie { * @param date Current time * * @return {@code true} if the cookie has expired. + * @deprecated Use {{@link #isExpired(Instant)}} */ + @Deprecated boolean isExpired(final Date date); + /** + * Returns true if this cookie has expired. + * + * @param date Current time + * @return {@code true} if the cookie has expired. + * @since 5.2 + */ + @SuppressWarnings("deprecation") + default boolean isExpired(final Instant date) { + return isExpired(date != null ? new Date(date.toEpochMilli()) : null); + } + /** * Returns creation time of the cookie. + * @deprecated Use {@link #getCreationInstant()} */ + @Deprecated Date getCreationDate(); + /** + * Returns creation time of the cookie. + */ + default Instant getCreationInstant() { return null; } + /** * Checks whether this Cookie has been marked as {@code httpOnly}. *

The default implementation returns {@code false}. diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/CookiePriorityComparator.java b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/CookiePriorityComparator.java index f33f80b228..2a80783652 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/CookiePriorityComparator.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/CookiePriorityComparator.java @@ -27,8 +27,8 @@ package org.apache.hc.client5.http.cookie; +import java.time.Instant; import java.util.Comparator; -import java.util.Date; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.ThreadingBehavior; @@ -56,10 +56,10 @@ public int compare(final Cookie c1, final Cookie c2) { final int l2 = getPathLength(c2); final int result = l2 - l1; if (result == 0) { - final Date d1 = c1.getCreationDate(); - final Date d2 = c2.getCreationDate(); + final Instant d1 = c1.getCreationInstant(); + final Instant d2 = c2.getCreationInstant(); if (d1 != null && d2 != null) { - return (int) (d1.getTime() - d2.getTime()); + return (int) (d1.toEpochMilli() - d2.toEpochMilli()); } } return result; diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/CookieStore.java b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/CookieStore.java index 19e209b951..543e6c5b79 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/CookieStore.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/CookieStore.java @@ -26,6 +26,7 @@ */ package org.apache.hc.client5.http.cookie; +import java.time.Instant; import java.util.Date; import java.util.List; @@ -58,9 +59,22 @@ public interface CookieStore { * the specified {@link java.util.Date}. * * @return true if any cookies were purged. + * @deprecated Use {@link #clearExpired(Instant)} */ + @Deprecated boolean clearExpired(Date date); + /** + * Removes all of {@link Cookie}s in this store that have expired by + * the specified {@link Instant}. + * + * @return true if any cookies were purged. + */ + @SuppressWarnings("deprecation") + default boolean clearExpired(Instant date) { + return clearExpired(date != null ? new Date(date.toEpochMilli()) : null); + } + /** * Clears all cookies. */ diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/SetCookie.java b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/SetCookie.java index 546476ac9e..39ccefe097 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/SetCookie.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/cookie/SetCookie.java @@ -27,8 +27,11 @@ package org.apache.hc.client5.http.cookie; +import java.time.Instant; import java.util.Date; +import org.apache.hc.client5.http.utils.DateUtils; + /** * This interface represents a {@code Set-Cookie} response header sent by the * origin server to the HTTP agent in order to maintain a conversational state. @@ -48,10 +51,26 @@ public interface SetCookie extends Cookie { * @param expiryDate the {@link Date} after which this cookie is no longer valid. * * @see Cookie#getExpiryDate - * + * @deprecated Use {{@link #setExpiryDate(Instant)}} */ + @Deprecated void setExpiryDate (Date expiryDate); + /** + * Sets expiration date. + *

Note: the object returned by this method is considered + * immutable. Changing it (e.g. using setTime()) could result in undefined behaviour. Do so at + * your peril.

+ * + * @param expiryDate the {@link Instant} after which this cookie is no longer valid. + * @see Cookie#getExpiryInstant() + * @since 5.2 + */ + @SuppressWarnings("deprecated") + default void setExpiryDate(Instant expiryDate) { + setExpiryDate(DateUtils.toDate(expiryDate)); + } + /** * Sets the domain attribute. * diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java index 16db56e8ce..20a1a374ee 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java @@ -749,7 +749,7 @@ protected void addCloseable(final Closeable closeable) { } closeables.add(closeable); } - + @SuppressWarnings("deprecated") public CloseableHttpAsyncClient build() { AsyncClientConnectionManager connManagerCopy = this.connManager; if (connManagerCopy == null) { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicClientCookie.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicClientCookie.java index e2cf88fd07..e7a0ce0846 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicClientCookie.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicClientCookie.java @@ -28,12 +28,14 @@ package org.apache.hc.client5.http.impl.cookie; import java.io.Serializable; +import java.time.Instant; import java.util.Date; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.hc.client5.http.cookie.SetCookie; +import org.apache.hc.client5.http.utils.DateUtils; import org.apache.hc.core5.util.Args; /** @@ -102,6 +104,14 @@ public void setValue(final String value) { */ @Override public Date getExpiryDate() { + return DateUtils.toDate(cookieExpiryDate); + } + + /** + * {@inheritDoc} + */ + @Override + public Instant getExpiryInstant() { return cookieExpiryDate; } @@ -118,7 +128,22 @@ public Date getExpiryDate() { */ @Override public void setExpiryDate (final Date expiryDate) { - cookieExpiryDate = expiryDate; + cookieExpiryDate = DateUtils.toInstant(expiryDate); + } + + /** + * Sets expiration date. + *

Note: the object returned by this method is considered + * immutable. Changing it (e.g. using setTime()) could result in undefined behaviour. Do so at + * your peril.

+ * + * @param expiryInstant the {@link Instant} after which this cookie is no longer valid. + * @see #getExpiryInstant() + * @since 5.2 + */ + @Override + public void setExpiryDate (final Instant expiryInstant) { + cookieExpiryDate = expiryInstant; } @@ -238,7 +263,20 @@ public void setHttpOnly(final boolean httpOnly) { public boolean isExpired(final Date date) { Args.notNull(date, "Date"); return (cookieExpiryDate != null - && cookieExpiryDate.getTime() <= date.getTime()); + && cookieExpiryDate.toEpochMilli() <= DateUtils.toInstant(date).toEpochMilli()); + } + + /** + * Returns true if this cookie has expired. + * @param instant Current time + * + * @return {@code true} if the cookie has expired. + */ + @Override + public boolean isExpired(final Instant instant) { + Args.notNull(instant, "Instant"); + return (cookieExpiryDate != null + && cookieExpiryDate.toEpochMilli() <= instant.toEpochMilli()); } /** @@ -246,6 +284,14 @@ public boolean isExpired(final Date date) { */ @Override public Date getCreationDate() { + return DateUtils.toDate(creationDate); + } + + /** + * @since 5.2 + */ + @Override + public Instant getCreationInstant() { return creationDate; } @@ -261,8 +307,17 @@ public boolean isHttpOnly() { /** * @since 4.4 + * @deprecated Use {@link #setCreationDate(Instant)} */ + @Deprecated public void setCreationDate(final Date creationDate) { + this.creationDate = DateUtils.toInstant(creationDate); + } + + /** + * @since 5.2 + */ + public void setCreationDate(final Instant creationDate) { this.creationDate = creationDate; } @@ -329,8 +384,8 @@ public String toString() { /** Domain attribute. */ private String cookieDomain; - /** Expiration {@link Date}. */ - private Date cookieExpiryDate; + /** Expiration {@link Instant}. */ + private Instant cookieExpiryDate; /** Path attribute. */ private String cookiePath; @@ -338,7 +393,7 @@ public String toString() { /** My secure flag. */ private boolean isSecure; - private Date creationDate; + private Instant creationDate; /** The {@code httpOnly} flag. */ private boolean httpOnly; diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicExpiresHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicExpiresHandler.java index a3c2028059..af67fb90c2 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicExpiresHandler.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicExpiresHandler.java @@ -86,7 +86,7 @@ public void parse(final SetCookie cookie, final String value) throw new MalformedCookieException("Invalid 'expires' attribute: " + value); } - cookie.setExpiryDate(DateUtils.toDate(expiry)); + cookie.setExpiryDate(expiry); } @Override diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicMaxAgeHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicMaxAgeHandler.java index 599ad2c404..07445a6f07 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicMaxAgeHandler.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/BasicMaxAgeHandler.java @@ -26,7 +26,7 @@ */ package org.apache.hc.client5.http.impl.cookie; -import java.util.Date; +import java.time.Instant; import org.apache.hc.client5.http.cookie.CommonCookieAttributeHandler; import org.apache.hc.client5.http.cookie.Cookie; @@ -66,7 +66,7 @@ public void parse(final SetCookie cookie, final String value) throw new MalformedCookieException ("Negative 'max-age' attribute: " + value); } - cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L)); + cookie.setExpiryDate(Instant.now().plusSeconds(age)); } @Override diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxExpiresHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxExpiresHandler.java index fcca1c3f07..a81d61ee0a 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxExpiresHandler.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxExpiresHandler.java @@ -41,7 +41,6 @@ import org.apache.hc.client5.http.cookie.Cookie; import org.apache.hc.client5.http.cookie.MalformedCookieException; import org.apache.hc.client5.http.cookie.SetCookie; -import org.apache.hc.client5.http.utils.DateUtils; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.util.Args; @@ -180,7 +179,7 @@ public void parse(final SetCookie cookie, final String value) throws MalformedCo final Instant expiryDate = ZonedDateTime.of(year, month.getValue(), day, hour, minute, second, 0, ZoneId.of("UTC")).toInstant(); - cookie.setExpiryDate(DateUtils.toDate(expiryDate)); + cookie.setExpiryDate(expiryDate); } private void skipDelims(final CharSequence buf, final Tokenizer.Cursor cursor) { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxMaxAgeHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxMaxAgeHandler.java index a1d2f7fe33..7bf9a21311 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxMaxAgeHandler.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxMaxAgeHandler.java @@ -26,7 +26,7 @@ */ package org.apache.hc.client5.http.impl.cookie; -import java.util.Date; +import java.time.Instant; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -68,8 +68,8 @@ public void parse(final SetCookie cookie, final String value) throws MalformedCo } catch (final NumberFormatException e) { return; } - final Date expiryDate = age >= 0 ? new Date(System.currentTimeMillis() + age * 1000L) : - new Date(Long.MIN_VALUE); + final Instant expiryDate = age >= 0 ? Instant.now().plusSeconds(age) : + Instant.EPOCH; cookie.setExpiryDate(expiryDate); } } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/RFC6265CookieSpec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/RFC6265CookieSpec.java index 8b2c08dd6b..d87e8669ee 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/RFC6265CookieSpec.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/RFC6265CookieSpec.java @@ -27,10 +27,10 @@ package org.apache.hc.client5.http.impl.cookie; +import java.time.Instant; import java.util.ArrayList; import java.util.BitSet; import java.util.Collections; -import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; @@ -146,7 +146,7 @@ public final List parse(final Header header, final CookieOrigin origin) final BasicClientCookie cookie = new BasicClientCookie(name, value); cookie.setPath(getDefaultPath(origin)); cookie.setDomain(getDefaultDomain(origin)); - cookie.setCreationDate(new Date()); + cookie.setCreationDate(Instant.now()); final Map attribMap = new LinkedHashMap<>(); while (!cursor.atEnd()) { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java index cfa82dc763..05d8ac4e96 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/BasicHttpClientConnectionManager.java @@ -28,7 +28,7 @@ package org.apache.hc.client5.http.impl.io; import java.io.IOException; -import java.util.Date; +import java.time.Instant; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; @@ -259,7 +259,7 @@ private synchronized void closeConnection(final CloseMode closeMode) { private void checkExpiry() { if (this.conn != null && System.currentTimeMillis() >= this.expiry) { if (LOG.isDebugEnabled()) { - LOG.debug("{} Connection expired @ {}", id, new Date(this.expiry)); + LOG.debug("{} Connection expired @ {}", id, Instant.ofEpochMilli(this.expiry)); } closeConnection(CloseMode.GRACEFUL); } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/protocol/RequestAddCookies.java b/httpclient5/src/main/java/org/apache/hc/client5/http/protocol/RequestAddCookies.java index 7bd5199411..68e9ba6b08 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/protocol/RequestAddCookies.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/protocol/RequestAddCookies.java @@ -28,8 +28,8 @@ package org.apache.hc.client5.http.protocol; import java.io.IOException; +import java.time.Instant; import java.util.ArrayList; -import java.util.Date; import java.util.List; import org.apache.hc.client5.http.RouteInfo; @@ -150,7 +150,7 @@ public void process(final HttpRequest request, final EntityDetails entity, final final List cookies = cookieStore.getCookies(); // Find cookies matching the given origin final List matchedCookies = new ArrayList<>(); - final Date now = new Date(); + final Instant now = Instant.now(); boolean expired = false; for (final Cookie cookie : cookies) { if (!cookie.isExpired(now)) { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/protocol/ResponseProcessCookies.java b/httpclient5/src/main/java/org/apache/hc/client5/http/protocol/ResponseProcessCookies.java index a2d84595de..2bb802aff9 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/protocol/ResponseProcessCookies.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/protocol/ResponseProcessCookies.java @@ -149,7 +149,7 @@ private static String formatCookie(final Cookie cookie) { buf.append(", path:"); buf.append(cookie.getPath()); buf.append(", expiry:"); - buf.append(cookie.getExpiryDate()); + buf.append(cookie.getExpiryInstant()); return buf.toString(); } diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultClientTlsStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultClientTlsStrategy.java index dfa2664ff1..bad25e4ede 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultClientTlsStrategy.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/DefaultClientTlsStrategy.java @@ -110,6 +110,7 @@ void applyParameters(final SSLEngine sslEngine, final SSLParameters sslParameter } @Override + @SuppressWarnings("deprecated") TlsDetails createTlsDetails(final SSLEngine sslEngine) { return tlsDetailsFactory != null ? tlsDetailsFactory.create(sslEngine) : null; } diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/cookie/TestCookiePriorityComparator.java b/httpclient5/src/test/java/org/apache/hc/client5/http/cookie/TestCookiePriorityComparator.java index 9cb76cce6c..f980f0443d 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/cookie/TestCookiePriorityComparator.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/cookie/TestCookiePriorityComparator.java @@ -27,8 +27,8 @@ package org.apache.hc.client5.http.cookie; +import java.time.Instant; import java.util.Comparator; -import java.util.Date; import org.apache.hc.client5.http.impl.cookie.BasicClientCookie; import org.junit.jupiter.api.Assertions; @@ -101,10 +101,10 @@ public void testEqualitySameLength() { public void testUnequalityCreationDate() { final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value"); cookie1.setPath("/blah"); - cookie1.setCreationDate(new Date(System.currentTimeMillis() - 200000)); + cookie1.setCreationDate(Instant.now().minusMillis(200000)); final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value"); cookie2.setPath("/blah"); - cookie2.setCreationDate(new Date(System.currentTimeMillis())); + cookie2.setCreationDate(Instant.now()); Assertions.assertTrue(comparator.compare(cookie1, cookie2) < 0); Assertions.assertTrue(comparator.compare(cookie2, cookie1) > 0); } diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestBasicCookieAttribHandlers.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestBasicCookieAttribHandlers.java index 19da947ee6..e5b62cf562 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestBasicCookieAttribHandlers.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestBasicCookieAttribHandlers.java @@ -267,7 +267,7 @@ public void testBasicMaxAgeParse() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new BasicMaxAgeHandler(); h.parse(cookie, "2000"); - Assertions.assertNotNull(cookie.getExpiryDate()); + Assertions.assertNotNull(cookie.getExpiryInstant()); } @Test @@ -327,7 +327,7 @@ public void testBasicExpiresParse() throws Exception { final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123); h.parse(cookie, DateUtils.formatStandardDate(Instant.now())); - Assertions.assertNotNull(cookie.getExpiryDate()); + Assertions.assertNotNull(cookie.getExpiryInstant()); } @Test diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestBasicCookieStore.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestBasicCookieStore.java index fe2d9c4bd0..30675c4f1a 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestBasicCookieStore.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestBasicCookieStore.java @@ -31,7 +31,8 @@ import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.util.Calendar; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.List; import org.apache.hc.client5.http.cookie.BasicCookieStore; @@ -65,9 +66,8 @@ public void testExpiredCookie() throws Exception { final BasicCookieStore store = new BasicCookieStore(); final BasicClientCookie cookie = new BasicClientCookie("name1", "value1"); - final Calendar c = Calendar.getInstance(); - c.add(Calendar.DAY_OF_YEAR, -10); - cookie.setExpiryDate(c.getTime()); + final Instant minus_10_days = Instant.now().minus(10, ChronoUnit.DAYS); + cookie.setExpiryDate(minus_10_days); store.addCookie(cookie); final List list = store.getCookies(); Assertions.assertNotNull(list); diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestLaxCookieAttribHandlers.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestLaxCookieAttribHandlers.java index 30ca266058..21335129de 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestLaxCookieAttribHandlers.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/cookie/TestLaxCookieAttribHandlers.java @@ -43,7 +43,7 @@ public void testParseMaxAge() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new LaxMaxAgeHandler(); h.parse(cookie, "2000"); - Assertions.assertNotNull(cookie.getExpiryDate()); + Assertions.assertNotNull(cookie.getExpiryInstant()); } @Test @@ -51,7 +51,7 @@ public void testParseMaxNegative() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new LaxMaxAgeHandler(); h.parse(cookie, "-2000"); - Assertions.assertNotNull(cookie.getExpiryDate()); + Assertions.assertNotNull(cookie.getExpiryInstant()); } @Test @@ -59,7 +59,7 @@ public void testParseMaxZero() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new LaxMaxAgeHandler(); h.parse(cookie, "0000"); - Assertions.assertNotNull(cookie.getExpiryDate()); + Assertions.assertNotNull(cookie.getExpiryInstant()); } @Test @@ -67,7 +67,7 @@ public void testBasicMaxAgeParseEmpty() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new LaxMaxAgeHandler(); h.parse(cookie, " "); - Assertions.assertNull(cookie.getExpiryDate()); + Assertions.assertNull(cookie.getExpiryInstant()); } @Test @@ -75,7 +75,7 @@ public void testBasicMaxAgeParseInvalid() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new LaxMaxAgeHandler(); h.parse(cookie, "garbage"); - Assertions.assertNull(cookie.getExpiryDate()); + Assertions.assertNull(cookie.getExpiryInstant()); } @Test @@ -98,7 +98,25 @@ public void testParseExpiry() throws Exception { final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, "1:0:12 8-jan-2012"); - final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate()); + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); + Assertions.assertNotNull(expiryDate); + + Assertions.assertEquals(2012, expiryDate.get(ChronoField.YEAR)); + Assertions.assertEquals(1, expiryDate.get(ChronoField.MONTH_OF_YEAR)); + Assertions.assertEquals(8, expiryDate.get(ChronoField.DAY_OF_MONTH)); + Assertions.assertEquals(1, expiryDate.get(ChronoField.HOUR_OF_DAY)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.MINUTE_OF_HOUR)); + Assertions.assertEquals(12, expiryDate.get(ChronoField.SECOND_OF_MINUTE)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND)); + } + + @Test + public void testParseExpiryInstant() throws Exception { + final BasicClientCookie cookie = new BasicClientCookie("name", "value"); + final CookieAttributeHandler h = new LaxExpiresHandler(); + h.parse(cookie, "1:0:12 8-jan-2012"); + + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); Assertions.assertNotNull(expiryDate); Assertions.assertEquals(2012, expiryDate.get(ChronoField.YEAR)); @@ -115,7 +133,7 @@ public void testParseExpiryInvalidTime0() throws Exception { final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, null); - Assertions.assertNull(cookie.getExpiryDate()); + Assertions.assertNull(cookie.getExpiryInstant()); } @Test @@ -156,7 +174,25 @@ public void testParseExpiryFunnyTime() throws Exception { final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, "1:59:00blah; 8-feb-2000"); - final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate()); + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); + Assertions.assertNotNull(expiryDate); + + Assertions.assertEquals(2000, expiryDate.get(ChronoField.YEAR_OF_ERA)); + Assertions.assertEquals(2, expiryDate.get(ChronoField.MONTH_OF_YEAR)); + Assertions.assertEquals(8, expiryDate.get(ChronoField.DAY_OF_MONTH)); + Assertions.assertEquals(1, expiryDate.get(ChronoField.HOUR_OF_DAY)); + Assertions.assertEquals(59, expiryDate.get(ChronoField.MINUTE_OF_HOUR)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.SECOND_OF_MINUTE)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND)); + } + + @Test + public void testParseExpiryFunnyTimeInstant() throws Exception { + final BasicClientCookie cookie = new BasicClientCookie("name", "value"); + final CookieAttributeHandler h = new LaxExpiresHandler(); + h.parse(cookie, "1:59:00blah; 8-feb-2000"); + + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); Assertions.assertNotNull(expiryDate); Assertions.assertEquals(2000, expiryDate.get(ChronoField.YEAR_OF_ERA)); @@ -198,7 +234,25 @@ public void testParseExpiryFunnyDayOfMonth() throws Exception { final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, "12:00:00 8blah;mar;1880"); - final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate()); + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); + Assertions.assertNotNull(expiryDate); + + Assertions.assertEquals(1880, expiryDate.get(ChronoField.YEAR)); + Assertions.assertEquals(3, expiryDate.get(ChronoField.MONTH_OF_YEAR)); + Assertions.assertEquals(8, expiryDate.get(ChronoField.DAY_OF_MONTH)); + Assertions.assertEquals(12, expiryDate.get(ChronoField.HOUR_OF_DAY)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.MINUTE_OF_HOUR)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.SECOND_OF_MINUTE)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND)); + } + + @Test + public void testParseExpiryFunnyDayOfMonthInstant() throws Exception { + final BasicClientCookie cookie = new BasicClientCookie("name", "value"); + final CookieAttributeHandler h = new LaxExpiresHandler(); + h.parse(cookie, "12:00:00 8blah;mar;1880"); + + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); Assertions.assertNotNull(expiryDate); Assertions.assertEquals(1880, expiryDate.get(ChronoField.YEAR)); @@ -224,7 +278,25 @@ public void testParseExpiryFunnyMonth() throws Exception { final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, "23:59:59; 1-ApriLLLLL-2008"); - final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate()); + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); + Assertions.assertNotNull(expiryDate); + + Assertions.assertEquals(2008, expiryDate.get(ChronoField.YEAR)); + Assertions.assertEquals(4, expiryDate.get(ChronoField.MONTH_OF_YEAR)); + Assertions.assertEquals(1, expiryDate.get(ChronoField.DAY_OF_MONTH)); + Assertions.assertEquals(23, expiryDate.get(ChronoField.HOUR_OF_DAY)); + Assertions.assertEquals(59, expiryDate.get(ChronoField.MINUTE_OF_HOUR)); + Assertions.assertEquals(59, expiryDate.get(ChronoField.SECOND_OF_MINUTE)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND)); + } + + @Test + public void testParseExpiryFunnyMonthInstant() throws Exception { + final BasicClientCookie cookie = new BasicClientCookie("name", "value"); + final CookieAttributeHandler h = new LaxExpiresHandler(); + h.parse(cookie, "23:59:59; 1-ApriLLLLL-2008"); + + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); Assertions.assertNotNull(expiryDate); Assertions.assertEquals(2008, expiryDate.get(ChronoField.YEAR)); @@ -266,7 +338,25 @@ public void testParseExpiryFunnyYear() throws Exception { final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, "23:59:59; 1-Apr-2008blah"); - final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate()); + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); + Assertions.assertNotNull(expiryDate); + + Assertions.assertEquals(2008, expiryDate.get(ChronoField.YEAR)); + Assertions.assertEquals(4, expiryDate.get(ChronoField.MONTH_OF_YEAR)); + Assertions.assertEquals(1, expiryDate.get(ChronoField.DAY_OF_MONTH)); + Assertions.assertEquals(23, expiryDate.get(ChronoField.HOUR_OF_DAY)); + Assertions.assertEquals(59, expiryDate.get(ChronoField.MINUTE_OF_HOUR)); + Assertions.assertEquals(59, expiryDate.get(ChronoField.SECOND_OF_MINUTE)); + Assertions.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND)); + } + + @Test + public void testParseExpiryFunnyYearInstant() throws Exception { + final BasicClientCookie cookie = new BasicClientCookie("name", "value"); + final CookieAttributeHandler h = new LaxExpiresHandler(); + h.parse(cookie, "23:59:59; 1-Apr-2008blah"); + + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); Assertions.assertNotNull(expiryDate); Assertions.assertEquals(2008, expiryDate.get(ChronoField.YEAR)); @@ -284,7 +374,7 @@ public void testParseExpiryYearTwoDigit1() throws Exception { final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, "23:59:59; 1-Apr-70"); - final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate()); + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); Assertions.assertNotNull(expiryDate); Assertions.assertEquals(1970, expiryDate.get(ChronoField.YEAR)); @@ -296,7 +386,7 @@ public void testParseExpiryYearTwoDigit2() throws Exception { final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, "23:59:59; 1-Apr-99"); - final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate()); + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); Assertions.assertNotNull(expiryDate); Assertions.assertEquals(1999, expiryDate.get(ChronoField.YEAR)); @@ -308,7 +398,7 @@ public void testParseExpiryYearTwoDigit3() throws Exception { final CookieAttributeHandler h = new LaxExpiresHandler(); h.parse(cookie, "23:59:59; 1-Apr-00"); - final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate()); + final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryInstant()); Assertions.assertNotNull(expiryDate); Assertions.assertEquals(2000, expiryDate.get(ChronoField.YEAR)); diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/protocol/TestRequestAddCookies.java b/httpclient5/src/test/java/org/apache/hc/client5/http/protocol/TestRequestAddCookies.java index 99929a2519..bc1d52bcfe 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/protocol/TestRequestAddCookies.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/protocol/TestRequestAddCookies.java @@ -26,7 +26,7 @@ */ package org.apache.hc.client5.http.protocol; -import java.util.Date; +import java.time.Instant; import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.RouteInfo.LayerType; @@ -321,7 +321,7 @@ public void testExcludeExpiredCookies() throws Exception { final BasicClientCookie cookie3 = new BasicClientCookie("name3", "value3"); cookie3.setDomain("localhost.local"); cookie3.setPath("/"); - cookie3.setExpiryDate(new Date(System.currentTimeMillis() + 100)); + cookie3.setExpiryDate(Instant.now().plusMillis(100)); this.cookieStore.addCookie(cookie3); Assertions.assertEquals(3, this.cookieStore.getCookies().size()); @@ -346,7 +346,7 @@ public void testExcludeExpiredCookies() throws Exception { Assertions.assertEquals(1, headers.length); Assertions.assertEquals("name1=value1; name2=value2", headers[0].getValue()); - Mockito.verify(this.cookieStore, Mockito.times(1)).clearExpired(ArgumentMatchers.any()); + Mockito.verify(this.cookieStore, Mockito.times(1)).clearExpired(ArgumentMatchers.any(Instant.class)); } @Test