HTTPCLIENT-2189 - Cookie and Cache APIs to use Java time primitives

This commit is contained in:
Arturo Bernal 2021-11-23 06:27:33 +01:00 committed by Oleg Kalnichevski
parent 0a42d173ef
commit d323e0d684
52 changed files with 832 additions and 436 deletions

View File

@ -27,6 +27,7 @@
package org.apache.hc.client5.http.cache; package org.apache.hc.client5.http.cache;
import java.io.Serializable; import java.io.Serializable;
import java.time.Instant;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@ -59,13 +60,13 @@ public class HttpCacheEntry implements MessageHeaders, Serializable {
private static final long serialVersionUID = -6300496422359477413L; private static final long serialVersionUID = -6300496422359477413L;
private static final String REQUEST_METHOD_HEADER_NAME = "Hc-Request-Method"; private static final String REQUEST_METHOD_HEADER_NAME = "Hc-Request-Method";
private final Date requestDate; private final Instant requestDate;
private final Date responseDate; private final Instant responseDate;
private final int status; private final int status;
private final HeaderGroup responseHeaders; private final HeaderGroup responseHeaders;
private final Resource resource; private final Resource resource;
private final Map<String, String> variantMap; private final Map<String, String> variantMap;
private final Date date; private final Instant date;
/** /**
* Create a new {@link HttpCacheEntry} with variants. * 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 * of this parent entry; this maps a "variant key" (derived
* from the varying request headers) to a "cache key" (where * from the varying request headers) to a "cache key" (where
* in the cache storage the particular variant is located) * in the cache storage the particular variant is located)
* @deprecated Use {{@link #HttpCacheEntry(Instant, Instant, int, Header[], Resource, Map)}}
*/ */
@Deprecated
public HttpCacheEntry( public HttpCacheEntry(
final Date requestDate, final Date requestDate,
final Date responseDate, final Date responseDate,
@ -97,6 +100,42 @@ public HttpCacheEntry(
Args.notNull(responseDate, "Response date"); Args.notNull(responseDate, "Response date");
Args.check(status >= HttpStatus.SC_SUCCESS, "Status code"); Args.check(status >= HttpStatus.SC_SUCCESS, "Status code");
Args.notNull(responseHeaders, "Response headers"); 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<String, String> 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.requestDate = requestDate;
this.responseDate = responseDate; this.responseDate = responseDate;
this.status = status; this.status = status;
@ -107,6 +146,21 @@ public HttpCacheEntry(
this.date = parseDate(); 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}. * Create a new {@link HttpCacheEntry}.
* *
@ -122,17 +176,17 @@ public HttpCacheEntry(
* Header[] from original HTTP Response * Header[] from original HTTP Response
* @param resource representing origin response body * @param resource representing origin response body
*/ */
public HttpCacheEntry(final Date requestDate, final Date responseDate, final int status, public HttpCacheEntry(final Instant requestDate, final Instant responseDate, final int status,
final Header[] responseHeaders, final Resource resource) { final Header[] responseHeaders, final Resource resource) {
this(requestDate, responseDate, status, responseHeaders, resource, new HashMap<>()); 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 * @return the Date value of the header or null if the header is not present
*/ */
private Date parseDate() { private Instant parseDate() {
return DateUtils.toDate(DateUtils.parseStandardDate(this, HttpHeaders.DATE)); return DateUtils.parseStandardDate(this, HttpHeaders.DATE);
} }
/** /**
@ -146,16 +200,40 @@ public int getStatus() {
* Returns the time the associated origin request was initiated by the * Returns the time the associated origin request was initiated by the
* caching module. * caching module.
* @return {@link Date} * @return {@link Date}
* @deprecated USe {@link #getRequestInstant()}
*/ */
@Deprecated
public Date getRequestDate() { 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; return requestDate;
} }
/** /**
* Returns the time the origin response was received by the caching module. * Returns the time the origin response was received by the caching module.
* @return {@link Date} * @return {@link Date}
* @deprecated Use {@link #getResponseInstant()}
*/ */
@Deprecated
public Date getResponseDate() { 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; return responseDate;
} }
@ -253,6 +331,10 @@ public Iterator<Header> headerIterator(final String name) {
* @since 4.3 * @since 4.3
*/ */
public Date getDate() { public Date getDate() {
return DateUtils.toDate(date);
}
public Instant getInstant() {
return date; return date;
} }

View File

@ -29,7 +29,7 @@
import java.io.IOException; import java.io.IOException;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Date; import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
@ -309,7 +309,7 @@ void callBackend(
final AsyncExecChain chain, final AsyncExecChain chain,
final AsyncExecCallback asyncExecCallback) { final AsyncExecCallback asyncExecCallback) {
LOG.debug("Calling the backend"); LOG.debug("Calling the backend");
final Date requestDate = getCurrentDate(); final Instant requestDate = getCurrentDate();
final AtomicReference<AsyncExecCallback> callbackRef = new AtomicReference<>(); final AtomicReference<AsyncExecCallback> callbackRef = new AtomicReference<>();
chainProceed(request, entityProducer, scope, chain, new AsyncExecCallback() { chainProceed(request, entityProducer, scope, chain, new AsyncExecCallback() {
@ -317,7 +317,7 @@ void callBackend(
public AsyncDataConsumer handleResponse( public AsyncDataConsumer handleResponse(
final HttpResponse backendResponse, final HttpResponse backendResponse,
final EntityDetails entityDetails) throws HttpException, IOException { final EntityDetails entityDetails) throws HttpException, IOException {
final Date responseDate = getCurrentDate(); final Instant responseDate = getCurrentDate();
backendResponse.addHeader("Via", generateViaHeader(backendResponse)); backendResponse.addHeader("Via", generateViaHeader(backendResponse));
final AsyncExecCallback callback = new BackendResponseHandler(target, request, requestDate, responseDate, scope, asyncExecCallback); 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 HttpHost target;
private final HttpRequest request; private final HttpRequest request;
private final Date requestDate; private final Instant requestDate;
private final Date responseDate; private final Instant responseDate;
private final AsyncExecChain.Scope scope; private final AsyncExecChain.Scope scope;
private final AsyncExecCallback asyncExecCallback; private final AsyncExecCallback asyncExecCallback;
private final AtomicReference<CachingAsyncDataConsumer> cachingConsumerRef; private final AtomicReference<CachingAsyncDataConsumer> cachingConsumerRef;
@ -455,8 +455,8 @@ class BackendResponseHandler implements AsyncExecCallback {
BackendResponseHandler( BackendResponseHandler(
final HttpHost target, final HttpHost target,
final HttpRequest request, final HttpRequest request,
final Date requestDate, final Instant requestDate,
final Date responseDate, final Instant responseDate,
final AsyncExecChain.Scope scope, final AsyncExecChain.Scope scope,
final AsyncExecCallback asyncExecCallback) { final AsyncExecCallback asyncExecCallback) {
this.target = target; this.target = target;
@ -525,7 +525,7 @@ public void handleInformationResponse(final HttpResponse response) throws HttpEx
asyncExecCallback.handleInformationResponse(response); 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; final CancellableDependency operation = scope.cancellableDependency;
operation.setDependency(responseCache.createCacheEntry( operation.setDependency(responseCache.createCacheEntry(
target, target,
@ -622,7 +622,7 @@ private void handleCacheHit(
final HttpCacheEntry entry) { final HttpCacheEntry entry) {
final HttpClientContext context = scope.clientContext; final HttpClientContext context = scope.clientContext;
recordCacheHit(target, request); recordCacheHit(target, request);
final Date now = getCurrentDate(); final Instant now = getCurrentDate();
if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) { if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) {
LOG.debug("Cache hit"); LOG.debug("Cache hit");
try { try {
@ -690,7 +690,7 @@ void revalidateCacheEntry(
final AsyncExecChain chain, final AsyncExecChain chain,
final AsyncExecCallback asyncExecCallback, final AsyncExecCallback asyncExecCallback,
final HttpCacheEntry cacheEntry) { final HttpCacheEntry cacheEntry) {
final Date requestDate = getCurrentDate(); final Instant requestDate = getCurrentDate();
final HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest( final HttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(
BasicRequestBuilder.copy(scope.originalRequest).build(), BasicRequestBuilder.copy(scope.originalRequest).build(),
cacheEntry); cacheEntry);
@ -698,7 +698,7 @@ void revalidateCacheEntry(
final AtomicReference<AsyncExecCallback> callbackRef = new AtomicReference<>(); final AtomicReference<AsyncExecCallback> callbackRef = new AtomicReference<>();
void triggerUpdatedCacheEntryResponse(final HttpResponse backendResponse, final Date responseDate) { void triggerUpdatedCacheEntryResponse(final HttpResponse backendResponse, final Instant responseDate) {
final CancellableDependency operation = scope.cancellableDependency; final CancellableDependency operation = scope.cancellableDependency;
recordCacheUpdate(scope.clientContext); recordCacheUpdate(scope.clientContext);
operation.setDependency(responseCache.updateCacheEntry( operation.setDependency(responseCache.updateCacheEntry(
@ -713,7 +713,7 @@ void triggerUpdatedCacheEntryResponse(final HttpResponse backendResponse, final
@Override @Override
public void completed(final HttpCacheEntry updatedEntry) { public void completed(final HttpCacheEntry updatedEntry) {
if (suitabilityChecker.isConditional(request) if (suitabilityChecker.isConditional(request)
&& suitabilityChecker.allConditionalsMatch(request, updatedEntry, new Date())) { && suitabilityChecker.allConditionalsMatch(request, updatedEntry, Instant.now())) {
final SimpleHttpResponse cacheResponse = responseGenerator.generateNotModifiedResponse(updatedEntry); final SimpleHttpResponse cacheResponse = responseGenerator.generateNotModifiedResponse(updatedEntry);
triggerResponse(cacheResponse, scope, asyncExecCallback); triggerResponse(cacheResponse, scope, asyncExecCallback);
} else { } 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)); backendResponse.addHeader(HeaderConstants.VIA, generateViaHeader(backendResponse));
final int statusCode = backendResponse.getCode(); final int statusCode = backendResponse.getCode();
@ -772,7 +772,7 @@ public AsyncDataConsumer handleResponse(
final HttpResponse backendResponse1, final HttpResponse backendResponse1,
final EntityDetails entityDetails) throws HttpException, IOException { final EntityDetails entityDetails) throws HttpException, IOException {
final Date responseDate1 = getCurrentDate(); final Instant responseDate1 = getCurrentDate();
final AsyncExecCallback callback1; final AsyncExecCallback callback1;
if (revalidationResponseIsTooOld(backendResponse1, cacheEntry) if (revalidationResponseIsTooOld(backendResponse1, cacheEntry)
@ -787,7 +787,7 @@ public AsyncDataConsumer handleResponse(
public AsyncDataConsumer handleResponse( public AsyncDataConsumer handleResponse(
final HttpResponse backendResponse2, final HttpResponse backendResponse2,
final EntityDetails entityDetails1) throws HttpException, IOException { final EntityDetails entityDetails1) throws HttpException, IOException {
final Date responseDate2 = getCurrentDate(); final Instant responseDate2 = getCurrentDate();
final AsyncExecCallback callback2 = evaluateResponse(backendResponse2, responseDate2); final AsyncExecCallback callback2 = evaluateResponse(backendResponse2, responseDate2);
callbackRef.set(callback2); callbackRef.set(callback2);
return callback2.handleResponse(backendResponse2, entityDetails1); return callback2.handleResponse(backendResponse2, entityDetails1);
@ -920,12 +920,12 @@ void negotiateResponseFromVariants(
BasicRequestBuilder.copy(request).build(), BasicRequestBuilder.copy(request).build(),
variants); variants);
final Date requestDate = getCurrentDate(); final Instant requestDate = getCurrentDate();
chainProceed(conditionalRequest, entityProducer, scope, chain, new AsyncExecCallback() { chainProceed(conditionalRequest, entityProducer, scope, chain, new AsyncExecCallback() {
final AtomicReference<AsyncExecCallback> callbackRef = new AtomicReference<>(); final AtomicReference<AsyncExecCallback> 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); recordCacheUpdate(scope.clientContext);
operation.setDependency(responseCache.updateVariantCacheEntry( operation.setDependency(responseCache.updateVariantCacheEntry(
target, target,
@ -989,7 +989,7 @@ public void cancelled() {
public AsyncDataConsumer handleResponse( public AsyncDataConsumer handleResponse(
final HttpResponse backendResponse, final HttpResponse backendResponse,
final EntityDetails entityDetails) throws HttpException, IOException { final EntityDetails entityDetails) throws HttpException, IOException {
final Date responseDate = getCurrentDate(); final Instant responseDate = getCurrentDate();
backendResponse.addHeader("Via", generateViaHeader(backendResponse)); backendResponse.addHeader("Via", generateViaHeader(backendResponse));
final AsyncExecCallback callback; final AsyncExecCallback callback;

View File

@ -26,7 +26,7 @@
*/ */
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.util.Date; import java.time.Instant;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -309,8 +309,8 @@ public Cancellable updateCacheEntry(
final HttpRequest request, final HttpRequest request,
final HttpCacheEntry stale, final HttpCacheEntry stale,
final HttpResponse originResponse, final HttpResponse originResponse,
final Date requestSent, final Instant requestSent,
final Date responseReceived, final Instant responseReceived,
final FutureCallback<HttpCacheEntry> callback) { final FutureCallback<HttpCacheEntry> callback) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Update cache entry: {}; {}", host, new RequestLine(request)); LOG.debug("Update cache entry: {}; {}", host, new RequestLine(request));
@ -356,8 +356,8 @@ public Cancellable updateVariantCacheEntry(
final HttpRequest request, final HttpRequest request,
final HttpResponse originResponse, final HttpResponse originResponse,
final Variant variant, final Variant variant,
final Date requestSent, final Instant requestSent,
final Date responseReceived, final Instant responseReceived,
final FutureCallback<HttpCacheEntry> callback) { final FutureCallback<HttpCacheEntry> callback) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Update variant cache entry: {}; {} / {}", host, new RequestLine(request), variant); LOG.debug("Update variant cache entry: {}; {} / {}", host, new RequestLine(request), variant);
@ -404,8 +404,8 @@ public Cancellable createCacheEntry(
final HttpRequest request, final HttpRequest request,
final HttpResponse originResponse, final HttpResponse originResponse,
final ByteArrayBuffer content, final ByteArrayBuffer content,
final Date requestSent, final Instant requestSent,
final Date responseReceived, final Instant responseReceived,
final FutureCallback<HttpCacheEntry> callback) { final FutureCallback<HttpCacheEntry> callback) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Create cache entry: {}; {}", host, new RequestLine(request)); LOG.debug("Create cache entry: {}; {}", host, new RequestLine(request));

View File

@ -26,7 +26,7 @@
*/ */
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.util.Date; import java.time.Instant;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -204,8 +204,8 @@ public HttpCacheEntry updateCacheEntry(
final HttpRequest request, final HttpRequest request,
final HttpCacheEntry stale, final HttpCacheEntry stale,
final HttpResponse originResponse, final HttpResponse originResponse,
final Date requestSent, final Instant requestSent,
final Date responseReceived) { final Instant responseReceived) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Update cache entry: {}; {}", host, new RequestLine(request)); LOG.debug("Update cache entry: {}; {}", host, new RequestLine(request));
} }
@ -233,8 +233,8 @@ public HttpCacheEntry updateVariantCacheEntry(
final HttpRequest request, final HttpRequest request,
final HttpResponse originResponse, final HttpResponse originResponse,
final Variant variant, final Variant variant,
final Date requestSent, final Instant requestSent,
final Date responseReceived) { final Instant responseReceived) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Update variant cache entry: {}; {} / {}", host, new RequestLine(request), variant); LOG.debug("Update variant cache entry: {}; {} / {}", host, new RequestLine(request), variant);
} }
@ -263,8 +263,8 @@ public HttpCacheEntry createCacheEntry(
final HttpRequest request, final HttpRequest request,
final HttpResponse originResponse, final HttpResponse originResponse,
final ByteArrayBuffer content, final ByteArrayBuffer content,
final Date requestSent, final Instant requestSent,
final Date responseReceived) { final Instant responseReceived) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Create cache entry: {}; {}", host, new RequestLine(request)); LOG.debug("Create cache entry: {}; {}", host, new RequestLine(request));
} }

View File

@ -90,6 +90,7 @@ static class RestrictedObjectInputStream extends ObjectInputStream {
Pattern.compile("^(\\[L)?org\\.apache\\.hc\\.(.*)"), Pattern.compile("^(\\[L)?org\\.apache\\.hc\\.(.*)"),
Pattern.compile("^(?:\\[+L)?java\\.util\\..*$"), Pattern.compile("^(?:\\[+L)?java\\.util\\..*$"),
Pattern.compile("^(?:\\[+L)?java\\.lang\\..*$"), Pattern.compile("^(?:\\[+L)?java\\.lang\\..*$"),
Pattern.compile("^(?:\\[+L)?java\\.time\\..*$"), // java 8 time
Pattern.compile("^\\[+Z$"), // boolean Pattern.compile("^\\[+Z$"), // boolean
Pattern.compile("^\\[+B$"), // byte Pattern.compile("^\\[+B$"), // byte
Pattern.compile("^\\[+C$"), // char Pattern.compile("^\\[+C$"), // char

View File

@ -26,7 +26,7 @@
*/ */
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.util.Date; import java.time.Instant;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -69,8 +69,8 @@ public HttpCacheEntry createCacheEntry(
final HttpRequest request, final HttpRequest request,
final HttpResponse originResponse, final HttpResponse originResponse,
final ByteArrayBuffer content, final ByteArrayBuffer content,
final Date requestSent, final Instant requestSent,
final Date responseReceived) throws ResourceIOException { final Instant responseReceived) throws ResourceIOException {
return new HttpCacheEntry( return new HttpCacheEntry(
requestSent, requestSent,
responseReceived, responseReceived,
@ -86,8 +86,8 @@ public HttpCacheEntry createCacheEntry(
public HttpCacheEntry updateCacheEntry( public HttpCacheEntry updateCacheEntry(
final String requestId, final String requestId,
final HttpCacheEntry entry, final HttpCacheEntry entry,
final Date requestDate, final Instant requestDate,
final Date responseDate, final Instant responseDate,
final HttpResponse response) throws ResourceIOException { final HttpResponse response) throws ResourceIOException {
Args.check(response.getCode() == HttpStatus.SC_NOT_MODIFIED, Args.check(response.getCode() == HttpStatus.SC_NOT_MODIFIED,
"Response must have 304 status code"); "Response must have 304 status code");
@ -103,7 +103,7 @@ public HttpCacheEntry updateCacheEntry(
mergedHeaders, mergedHeaders,
resource); resource);
} }
@SuppressWarnings("deprecation")
public HttpCacheEntry updateParentCacheEntry( public HttpCacheEntry updateParentCacheEntry(
final String requestId, final String requestId,
final HttpCacheEntry existing, final HttpCacheEntry existing,
@ -122,8 +122,8 @@ public HttpCacheEntry updateParentCacheEntry(
final Map<String,String> variantMap = new HashMap<>(src.getVariantMap()); final Map<String,String> variantMap = new HashMap<>(src.getVariantMap());
variantMap.put(variantKey, variantCacheKey); variantMap.put(variantKey, variantCacheKey);
return new HttpCacheEntry( return new HttpCacheEntry(
src.getRequestDate(), src.getRequestInstant(),
src.getResponseDate(), src.getResponseInstant(),
src.getStatus(), src.getStatus(),
src.getHeaders(), src.getHeaders(),
resource, resource,

View File

@ -26,8 +26,8 @@
*/ */
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import org.apache.hc.client5.http.cache.HeaderConstants; import org.apache.hc.client5.http.cache.HeaderConstants;
@ -50,7 +50,8 @@ class CacheValidityPolicy {
super(); 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()); return TimeValue.ofSeconds(getCorrectedInitialAge(entry).toSeconds() + getResidentTime(entry, now).toSeconds());
} }
@ -60,7 +61,7 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry entry) {
return TimeValue.ofSeconds(maxAge); return TimeValue.ofSeconds(maxAge);
} }
final Date dateValue = entry.getDate(); final Instant dateValue = entry.getInstant();
if (dateValue == null) { if (dateValue == null) {
return TimeValue.ZERO_MILLISECONDS; return TimeValue.ZERO_MILLISECONDS;
} }
@ -69,11 +70,11 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry entry) {
if (expiry == null) { if (expiry == null) {
return TimeValue.ZERO_MILLISECONDS; return TimeValue.ZERO_MILLISECONDS;
} }
final long diff = expiry.toEpochMilli() - dateValue.getTime(); final Duration diff = Duration.between(dateValue, expiry);
return TimeValue.ofSeconds(diff / 1000); 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; 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 * @return {@code true} if the response is fresh
*/ */
public boolean isResponseHeuristicallyFresh(final HttpCacheEntry entry, 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; return getCurrentAge(entry, now).compareTo(getHeuristicFreshnessLifetime(entry, coefficient, defaultLifetime)) == -1;
} }
public TimeValue getHeuristicFreshnessLifetime(final HttpCacheEntry entry, public TimeValue getHeuristicFreshnessLifetime(final HttpCacheEntry entry,
final float coefficient, final TimeValue defaultLifetime) { 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); final Instant lastModifiedValue = DateUtils.parseStandardDate(entry, HeaderConstants.LAST_MODIFIED);
if (dateValue != null && lastModifiedValue != null) { if (dateValue != null && lastModifiedValue != null) {
final long diff = dateValue.getTime() - lastModifiedValue.toEpochMilli(); final Duration diff = Duration.between(lastModifiedValue, dateValue);
if (diff < 0) {
if (diff.isNegative()) {
return TimeValue.ZERO_MILLISECONDS; return TimeValue.ZERO_MILLISECONDS;
} }
return TimeValue.ofSeconds((long) (coefficient * diff / 1000)); return TimeValue.ofSeconds((long) (coefficient * diff.getSeconds()));
} }
return defaultLifetime; return defaultLifetime;
@ -125,7 +127,7 @@ public boolean proxyRevalidate(final HttpCacheEntry entry) {
return hasCacheControlDirective(entry, HeaderConstants.CACHE_CONTROL_PROXY_REVALIDATE); 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<HeaderElement> it = MessageSupport.iterate(entry, HeaderConstants.CACHE_CONTROL); final Iterator<HeaderElement> it = MessageSupport.iterate(entry, HeaderConstants.CACHE_CONTROL);
while (it.hasNext()) { while (it.hasNext()) {
final HeaderElement elt = it.next(); final HeaderElement elt = it.next();
@ -145,7 +147,7 @@ public boolean mayReturnStaleWhileRevalidating(final HttpCacheEntry entry, final
return false; 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); final TimeValue staleness = getStaleness(entry, now);
return mayReturnStaleIfError(request, HeaderConstants.CACHE_CONTROL, staleness) return mayReturnStaleIfError(request, HeaderConstants.CACHE_CONTROL, staleness)
|| mayReturnStaleIfError(entry, 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) { protected TimeValue getApparentAge(final HttpCacheEntry entry) {
final Date dateValue = entry.getDate(); final Instant dateValue = entry.getInstant();
if (dateValue == null) { if (dateValue == null) {
return MAX_AGE; return MAX_AGE;
} }
final long diff = entry.getResponseDate().getTime() - dateValue.getTime(); final Duration diff = Duration.between(dateValue, entry.getResponseInstant());
if (diff < 0L) { if (diff.isNegative()) {
return TimeValue.ZERO_MILLISECONDS; return TimeValue.ZERO_MILLISECONDS;
} }
return TimeValue.ofSeconds(diff / 1000); return TimeValue.ofSeconds(diff.getSeconds());
} }
protected long getAgeValue(final HttpCacheEntry entry) { protected long getAgeValue(final HttpCacheEntry entry) {
@ -234,19 +236,20 @@ protected TimeValue getCorrectedReceivedAge(final HttpCacheEntry entry) {
} }
protected TimeValue getResponseDelay(final HttpCacheEntry entry) { protected TimeValue getResponseDelay(final HttpCacheEntry entry) {
final long diff = entry.getResponseDate().getTime() - entry.getRequestDate().getTime(); final Duration diff = Duration.between(entry.getRequestInstant(), entry.getResponseInstant());
return TimeValue.ofSeconds(diff / 1000); return TimeValue.ofSeconds(diff.getSeconds());
} }
protected TimeValue getCorrectedInitialAge(final HttpCacheEntry entry) { protected TimeValue getCorrectedInitialAge(final HttpCacheEntry entry) {
return TimeValue.ofSeconds(getCorrectedReceivedAge(entry).toSeconds() + getResponseDelay(entry).toSeconds()); return TimeValue.ofSeconds(getCorrectedReceivedAge(entry).toSeconds() + getResponseDelay(entry).toSeconds());
} }
protected TimeValue getResidentTime(final HttpCacheEntry entry, final Date now) { protected TimeValue getResidentTime(final HttpCacheEntry entry, final Instant now) {
final long diff = now.getTime() - entry.getResponseDate().getTime(); final Duration diff = Duration.between(entry.getResponseInstant(), now);
return TimeValue.ofSeconds(diff / 1000); return TimeValue.ofSeconds(diff.getSeconds());
} }
protected long getMaxAge(final HttpCacheEntry entry) { protected long getMaxAge(final HttpCacheEntry entry) {
// This is a header value, we leave as-is // This is a header value, we leave as-is
long maxAge = -1; long maxAge = -1;
@ -279,7 +282,7 @@ public boolean hasCacheControlDirective(final HttpCacheEntry entry, final String
return false; 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 age = getCurrentAge(entry, now);
final TimeValue freshness = getFreshnessLifetime(entry); final TimeValue freshness = getFreshnessLifetime(entry);
if (age.compareTo(freshness) <= 0) { if (age.compareTo(freshness) <= 0) {

View File

@ -27,7 +27,6 @@
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.time.Instant; import java.time.Instant;
import java.util.Date;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse; import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.cache.HeaderConstants; import org.apache.hc.client5.http.cache.HeaderConstants;
@ -65,7 +64,7 @@ class CachedHttpResponseGenerator {
* @return {@link SimpleHttpResponse} constructed response * @return {@link SimpleHttpResponse} constructed response
*/ */
SimpleHttpResponse generateResponse(final HttpRequest request, final HttpCacheEntry entry) throws ResourceIOException { 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()); final SimpleHttpResponse response = new SimpleHttpResponse(entry.getStatus());
response.setVersion(HttpVersion.DEFAULT); response.setVersion(HttpVersion.DEFAULT);

View File

@ -27,7 +27,6 @@
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.time.Instant; import java.time.Instant;
import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import org.apache.hc.client5.http.cache.HeaderConstants; import org.apache.hc.client5.http.cache.HeaderConstants;
@ -71,7 +70,7 @@ class CachedResponseSuitabilityChecker {
this(new CacheValidityPolicy(), config); 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)) { if (validityStrategy.isResponseFresh(entry, now)) {
return true; return true;
} }
@ -142,7 +141,7 @@ private long getMaxStale(final HttpRequest request) {
* Right now in time * Right now in time
* @return boolean yes/no answer * @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)) { if (!isFreshEnough(entry, request, now)) {
LOG.debug("Cache entry is not fresh enough"); LOG.debug("Cache entry is not fresh enough");
return false; return false;
@ -274,13 +273,12 @@ public boolean isConditional(final HttpRequest request) {
* @param now right NOW in time * @param now right NOW in time
* @return {@code true} if the request matches all conditionals * @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 hasEtagValidator = hasSupportedEtagValidator(request);
final boolean hasLastModifiedValidator = hasSupportedLastModifiedValidator(request); final boolean hasLastModifiedValidator = hasSupportedLastModifiedValidator(request);
final boolean etagValidatorMatches = (hasEtagValidator) && etagValidatorMatches(request, entry); final boolean etagValidatorMatches = (hasEtagValidator) && etagValidatorMatches(request, entry);
final boolean lastModifiedValidatorMatches = (hasLastModifiedValidator) && lastModifiedValidatorMatches(request, entry, final boolean lastModifiedValidatorMatches = (hasLastModifiedValidator) && lastModifiedValidatorMatches(request, entry, now);
DateUtils.toInstant(now));
if ((hasEtagValidator && hasLastModifiedValidator) if ((hasEtagValidator && hasLastModifiedValidator)
&& !(etagValidatorMatches && lastModifiedValidatorMatches)) { && !(etagValidatorMatches && lastModifiedValidatorMatches)) {

View File

@ -28,7 +28,7 @@
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Date; import java.time.Instant;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
@ -231,7 +231,7 @@ ClassicHttpResponse callBackend(
final ExecChain.Scope scope, final ExecChain.Scope scope,
final ExecChain chain) throws IOException, HttpException { final ExecChain chain) throws IOException, HttpException {
final Date requestDate = getCurrentDate(); final Instant requestDate = getCurrentDate();
LOG.debug("Calling the backend"); LOG.debug("Calling the backend");
final ClassicHttpResponse backendResponse = chain.proceed(request, scope); final ClassicHttpResponse backendResponse = chain.proceed(request, scope);
@ -253,7 +253,7 @@ private ClassicHttpResponse handleCacheHit(
final HttpClientContext context = scope.clientContext; final HttpClientContext context = scope.clientContext;
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
recordCacheHit(target, request); recordCacheHit(target, request);
final Date now = getCurrentDate(); final Instant now = getCurrentDate();
if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) { if (suitabilityChecker.canCachedResponseBeUsed(target, request, entry, now)) {
LOG.debug("Cache hit"); LOG.debug("Cache hit");
try { try {
@ -306,13 +306,13 @@ ClassicHttpResponse revalidateCacheEntry(
final ExecChain.Scope scope, final ExecChain.Scope scope,
final ExecChain chain, final ExecChain chain,
final HttpCacheEntry cacheEntry) throws IOException, HttpException { final HttpCacheEntry cacheEntry) throws IOException, HttpException {
Date requestDate = getCurrentDate(); Instant requestDate = getCurrentDate();
final ClassicHttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest( final ClassicHttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequest(
scope.originalRequest, cacheEntry); scope.originalRequest, cacheEntry);
ClassicHttpResponse backendResponse = chain.proceed(conditionalRequest, scope); ClassicHttpResponse backendResponse = chain.proceed(conditionalRequest, scope);
try { try {
Date responseDate = getCurrentDate(); Instant responseDate = getCurrentDate();
if (revalidationResponseIsTooOld(backendResponse, cacheEntry)) { if (revalidationResponseIsTooOld(backendResponse, cacheEntry)) {
backendResponse.close(); backendResponse.close();
@ -334,7 +334,7 @@ ClassicHttpResponse revalidateCacheEntry(
final HttpCacheEntry updatedEntry = responseCache.updateCacheEntry( final HttpCacheEntry updatedEntry = responseCache.updateCacheEntry(
target, request, cacheEntry, backendResponse, requestDate, responseDate); target, request, cacheEntry, backendResponse, requestDate, responseDate);
if (suitabilityChecker.isConditional(request) 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.generateNotModifiedResponse(updatedEntry), scope);
} }
return convert(responseGenerator.generateResponse(request, updatedEntry), scope); return convert(responseGenerator.generateResponse(request, updatedEntry), scope);
@ -362,8 +362,8 @@ ClassicHttpResponse handleBackendResponse(
final HttpHost target, final HttpHost target,
final ClassicHttpRequest request, final ClassicHttpRequest request,
final ExecChain.Scope scope, final ExecChain.Scope scope,
final Date requestDate, final Instant requestDate,
final Date responseDate, final Instant responseDate,
final ClassicHttpResponse backendResponse) throws IOException { final ClassicHttpResponse backendResponse) throws IOException {
responseCompliance.ensureProtocolCompliance(scope.originalRequest, request, backendResponse); responseCompliance.ensureProtocolCompliance(scope.originalRequest, request, backendResponse);
@ -384,8 +384,8 @@ ClassicHttpResponse cacheAndReturnResponse(
final HttpRequest request, final HttpRequest request,
final ClassicHttpResponse backendResponse, final ClassicHttpResponse backendResponse,
final ExecChain.Scope scope, final ExecChain.Scope scope,
final Date requestSent, final Instant requestSent,
final Date responseReceived) throws IOException { final Instant responseReceived) throws IOException {
LOG.debug("Caching backend response"); LOG.debug("Caching backend response");
final ByteArrayBuffer buf; final ByteArrayBuffer buf;
final HttpEntity entity = backendResponse.getEntity(); final HttpEntity entity = backendResponse.getEntity();
@ -453,10 +453,10 @@ ClassicHttpResponse negotiateResponseFromVariants(
final Map<String, Variant> variants) throws IOException, HttpException { final Map<String, Variant> variants) throws IOException, HttpException {
final ClassicHttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequestFromVariants(request, variants); final ClassicHttpRequest conditionalRequest = conditionalRequestBuilder.buildConditionalRequestFromVariants(request, variants);
final Date requestDate = getCurrentDate(); final Instant requestDate = getCurrentDate();
final ClassicHttpResponse backendResponse = chain.proceed(conditionalRequest, scope); final ClassicHttpResponse backendResponse = chain.proceed(conditionalRequest, scope);
try { try {
final Date responseDate = getCurrentDate(); final Instant responseDate = getCurrentDate();
backendResponse.addHeader("Via", generateViaHeader(backendResponse)); backendResponse.addHeader("Via", generateViaHeader(backendResponse));

View File

@ -27,7 +27,7 @@
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.time.Instant;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -183,7 +183,7 @@ SimpleHttpResponse generateCachedResponse(
final HttpRequest request, final HttpRequest request,
final HttpContext context, final HttpContext context,
final HttpCacheEntry entry, final HttpCacheEntry entry,
final Date now) throws ResourceIOException { final Instant now) throws ResourceIOException {
final SimpleHttpResponse cachedResponse; final SimpleHttpResponse cachedResponse;
if (request.containsHeader(HeaderConstants.IF_NONE_MATCH) if (request.containsHeader(HeaderConstants.IF_NONE_MATCH)
|| request.containsHeader(HeaderConstants.IF_MODIFIED_SINCE)) { || request.containsHeader(HeaderConstants.IF_MODIFIED_SINCE)) {
@ -202,7 +202,7 @@ SimpleHttpResponse handleRevalidationFailure(
final HttpRequest request, final HttpRequest request,
final HttpContext context, final HttpContext context,
final HttpCacheEntry entry, final HttpCacheEntry entry,
final Date now) throws IOException { final Instant now) throws IOException {
if (staleResponseNotAllowed(request, entry, now)) { if (staleResponseNotAllowed(request, entry, now)) {
return generateGatewayTimeout(context); return generateGatewayTimeout(context);
} else { } else {
@ -226,7 +226,7 @@ SimpleHttpResponse unvalidatedCacheHit(
return cachedResponse; 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) return validityPolicy.mustRevalidate(entry)
|| (cacheConfig.isSharedCache() && validityPolicy.proxyRevalidate(entry)) || (cacheConfig.isSharedCache() && validityPolicy.proxyRevalidate(entry))
|| explicitFreshnessRequest(request, entry, now); || explicitFreshnessRequest(request, entry, now);
@ -244,7 +244,7 @@ boolean mayCallBackend(final HttpRequest request) {
return true; 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<HeaderElement> it = MessageSupport.iterate(request, HeaderConstants.CACHE_CONTROL); final Iterator<HeaderElement> it = MessageSupport.iterate(request, HeaderConstants.CACHE_CONTROL);
while (it.hasNext()) { while (it.hasNext()) {
final HeaderElement elt = it.next(); final HeaderElement elt = it.next();
@ -313,8 +313,8 @@ boolean supportsRangeAndContentRangeHeaders() {
return SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS; return SUPPORTS_RANGE_AND_CONTENT_RANGE_HEADERS;
} }
Date getCurrentDate() { Instant getCurrentDate() {
return new Date(); return Instant.now();
} }
boolean clientRequestsOurOptions(final HttpRequest request) { boolean clientRequestsOurOptions(final HttpRequest request) {
@ -340,7 +340,7 @@ boolean revalidationResponseIsTooOld(final HttpResponse backendResponse, final H
boolean shouldSendNotModifiedResponse(final HttpRequest request, final HttpCacheEntry responseEntry) { boolean shouldSendNotModifiedResponse(final HttpRequest request, final HttpCacheEntry responseEntry) {
return (suitabilityChecker.isConditional(request) return (suitabilityChecker.isConditional(request)
&& suitabilityChecker.allConditionalsMatch(request, responseEntry, new Date())); && suitabilityChecker.allConditionalsMatch(request, responseEntry, Instant.now()));
} }
boolean staleIfErrorAppliesTo(final int statusCode) { boolean staleIfErrorAppliesTo(final int statusCode) {

View File

@ -26,7 +26,7 @@
*/ */
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.util.Date; import java.time.Instant;
import java.util.Map; import java.util.Map;
import org.apache.hc.client5.http.cache.HttpCacheEntry; import org.apache.hc.client5.http.cache.HttpCacheEntry;
@ -79,8 +79,8 @@ Cancellable createCacheEntry(
HttpRequest request, HttpRequest request,
HttpResponse originResponse, HttpResponse originResponse,
ByteArrayBuffer content, ByteArrayBuffer content,
Date requestSent, Instant requestSent,
Date responseReceived, Instant responseReceived,
FutureCallback<HttpCacheEntry> callback); FutureCallback<HttpCacheEntry> callback);
/** /**
@ -91,8 +91,8 @@ Cancellable updateCacheEntry(
HttpRequest request, HttpRequest request,
HttpCacheEntry stale, HttpCacheEntry stale,
HttpResponse originResponse, HttpResponse originResponse,
Date requestSent, Instant requestSent,
Date responseReceived, Instant responseReceived,
FutureCallback<HttpCacheEntry> callback); FutureCallback<HttpCacheEntry> callback);
/** /**
@ -104,8 +104,8 @@ Cancellable updateVariantCacheEntry(
HttpRequest request, HttpRequest request,
HttpResponse originResponse, HttpResponse originResponse,
Variant variant, Variant variant,
Date requestSent, Instant requestSent,
Date responseReceived, Instant responseReceived,
FutureCallback<HttpCacheEntry> callback); FutureCallback<HttpCacheEntry> callback);
/** /**

View File

@ -32,7 +32,7 @@
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Date; import java.time.Instant;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -150,8 +150,8 @@ public HttpCacheStorageEntry deserialize(final byte[] serializedObject) throws R
// Extract metadata pseudo-headers // Extract metadata pseudo-headers
final String storageKey = getCachePseudoHeaderAndRemove(response, SC_HEADER_NAME_STORAGE_KEY); final String storageKey = getCachePseudoHeaderAndRemove(response, SC_HEADER_NAME_STORAGE_KEY);
final Date requestDate = getCachePseudoHeaderDateAndRemove(response, SC_HEADER_NAME_REQUEST_DATE); final Instant requestDate = getCachePseudoHeaderDateAndRemove(response, SC_HEADER_NAME_REQUEST_DATE);
final Date responseDate = getCachePseudoHeaderDateAndRemove(response, SC_HEADER_NAME_RESPONSE_DATE); final Instant responseDate = getCachePseudoHeaderDateAndRemove(response, SC_HEADER_NAME_RESPONSE_DATE);
final boolean noBody = getCachePseudoHeaderBooleanAndRemove(response, SC_HEADER_NAME_NO_CONTENT); final boolean noBody = getCachePseudoHeaderBooleanAndRemove(response, SC_HEADER_NAME_NO_CONTENT);
final Map<String, String> variantMap = getVariantMapPseudoHeadersAndRemove(response); final Map<String, String> variantMap = getVariantMapPseudoHeadersAndRemove(response);
unescapeHeaders(response); unescapeHeaders(response);
@ -255,8 +255,8 @@ private void unescapeHeaders(final HttpResponse httpResponse) {
*/ */
private void addMetadataPseudoHeaders(final HttpResponse httpResponse, final HttpCacheStorageEntry httpCacheEntry) { private void addMetadataPseudoHeaders(final HttpResponse httpResponse, final HttpCacheStorageEntry httpCacheEntry) {
httpResponse.addHeader(SC_HEADER_NAME_STORAGE_KEY, httpCacheEntry.getKey()); 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_RESPONSE_DATE, Long.toString(httpCacheEntry.getContent().getResponseInstant().toEpochMilli()));
httpResponse.addHeader(SC_HEADER_NAME_REQUEST_DATE, Long.toString(httpCacheEntry.getContent().getRequestDate().getTime())); 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. // 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} // Header keys look like: {Accept-Encoding=gzip}
@ -308,12 +308,12 @@ private static String getOptionalCachePseudoHeaderAndRemove(final HttpResponse r
* @return Value for metadata pseudo-header * @return Value for metadata pseudo-header
* @throws ResourceIOException if the given pseudo-header is not found, or contains invalid data * @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); final String value = getCachePseudoHeaderAndRemove(response, name);
response.removeHeaders(name); response.removeHeaders(name);
try { try {
final long timestamp = Long.parseLong(value); final long timestamp = Long.parseLong(value);
return new Date(timestamp); return Instant.ofEpochMilli(timestamp);
} catch (final NumberFormatException e) { } catch (final NumberFormatException e) {
throw new ResourceIOException("Invalid value for header '" + name + "'", e); throw new ResourceIOException("Invalid value for header '" + name + "'", e);
} }
@ -410,7 +410,7 @@ protected void writeHeadLine(
*/ */
private static class NoAgeCacheValidityPolicy extends CacheValidityPolicy { private static class NoAgeCacheValidityPolicy extends CacheValidityPolicy {
@Override @Override
public TimeValue getCurrentAge(final HttpCacheEntry entry, final Date now) { public TimeValue getCurrentAge(final HttpCacheEntry entry, final Instant now) {
return TimeValue.ZERO_MILLISECONDS; return TimeValue.ZERO_MILLISECONDS;
} }
} }

View File

@ -26,7 +26,7 @@
*/ */
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.util.Date; import java.time.Instant;
import java.util.Map; import java.util.Map;
import org.apache.hc.client5.http.cache.HttpCacheEntry; import org.apache.hc.client5.http.cache.HttpCacheEntry;
@ -73,8 +73,8 @@ HttpCacheEntry createCacheEntry(
HttpRequest request, HttpRequest request,
HttpResponse originResponse, HttpResponse originResponse,
ByteArrayBuffer content, ByteArrayBuffer content,
Date requestSent, Instant requestSent,
Date responseReceived); Instant responseReceived);
/** /**
* Update a {@link HttpCacheEntry} using a 304 {@link HttpResponse}. * Update a {@link HttpCacheEntry} using a 304 {@link HttpResponse}.
@ -84,8 +84,8 @@ HttpCacheEntry updateCacheEntry(
HttpRequest request, HttpRequest request,
HttpCacheEntry stale, HttpCacheEntry stale,
HttpResponse originResponse, HttpResponse originResponse,
Date requestSent, Instant requestSent,
Date responseReceived); Instant responseReceived);
/** /**
* Update a specific {@link HttpCacheEntry} representing a cached variant * Update a specific {@link HttpCacheEntry} representing a cached variant
@ -96,8 +96,8 @@ HttpCacheEntry updateVariantCacheEntry(
HttpRequest request, HttpRequest request,
HttpResponse originResponse, HttpResponse originResponse,
Variant variant, Variant variant,
Date requestSent, Instant requestSent,
Date responseReceived); Instant responseReceived);
/** /**
* Specifies cache should reuse the given cached variant to satisfy * Specifies cache should reuse the given cached variant to satisfy

View File

@ -29,7 +29,6 @@
import java.io.IOException; import java.io.IOException;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import org.apache.hc.client5.http.ClientProtocolException; import org.apache.hc.client5.http.ClientProtocolException;
@ -101,8 +100,8 @@ private void warningsWithNonMatchingWarnDatesAreRemoved(
boolean modified = false; boolean modified = false;
for(final Header h : warningHeaders) { for(final Header h : warningHeaders) {
for(final WarningValue wv : WarningValue.getWarningValues(h)) { for(final WarningValue wv : WarningValue.getWarningValues(h)) {
final Date warnDate = wv.getWarnDate(); final Instant warnInstant = wv.getWarnDate();
if (warnDate == null || warnDate.equals(responseDate)) { if (warnInstant == null || warnInstant.equals(responseDate)) {
newWarningHeaders.add(new BasicHeader(HeaderConstants.WARNING,wv.toString())); newWarningHeaders.add(new BasicHeader(HeaderConstants.WARNING,wv.toString()));
} else { } else {
modified = true; modified = true;

View File

@ -26,8 +26,8 @@
*/ */
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -48,7 +48,7 @@ class WarningValue {
private int warnCode; private int warnCode;
private String warnAgent; private String warnAgent;
private String warnText; private String warnText;
private Date warnDate; private Instant warnDate;
WarningValue(final String s) { WarningValue(final String s) {
this(s, 0); this(s, 0);
@ -265,7 +265,7 @@ protected void consumeWarnDate() {
parseError(); parseError();
} }
offs += m.end(); 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 /** Returns the date and time when this warning was added, or
* {@code null} if a warning date was not supplied in the * {@code null} if a warning date was not supplied in the
* header. * 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} /** Formats a {@code WarningValue} as a {@link String}
* suitable for including in a header. For example, you can: * suitable for including in a header. For example, you can:
@ -359,7 +359,7 @@ private void parseError() {
public String toString() { public String toString() {
if (warnDate != null) { if (warnDate != null) {
return String.format("%d %s %s \"%s\"", warnCode, return String.format("%d %s %s \"%s\"", warnCode,
warnAgent, warnText, DateUtils.formatStandardDate(DateUtils.toInstant(warnDate))); warnAgent, warnText, DateUtils.formatStandardDate(warnDate));
} else { } else {
return String.format("%d %s %s", warnCode, warnAgent, warnText); return String.format("%d %s %s", warnCode, warnAgent, warnText);
} }

View File

@ -27,7 +27,6 @@
package org.apache.hc.client5.http.cache; package org.apache.hc.client5.http.cache;
import static org.junit.jupiter.api.Assertions.assertEquals; 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.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
@ -66,7 +65,7 @@ public void setUp() {
} }
private HttpCacheEntry makeEntry(final Header[] headers) { 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); HttpStatus.SC_OK, headers, mockResource);
} }
@ -110,13 +109,6 @@ public void testGetFirstHeaderReturnsNullIfNoneMatch() {
assertNull(entry.getFirstHeader("quux")); assertNull(entry.getFirstHeader("quux"));
} }
@Test
public void testCacheEntryWithNoVaryHeaderDoesNotHaveVariants() {
final Header[] headers = new Header[0];
entry = makeEntry(headers);
assertFalse(entry.hasVariants());
}
@Test @Test
public void testCacheEntryWithOneVaryHeaderHasVariants() { public void testCacheEntryWithOneVaryHeaderHasVariants() {
final Header[] headers = { new BasicHeader("Vary", "User-Agent") }; final Header[] headers = { new BasicHeader("Vary", "User-Agent") };
@ -140,11 +132,24 @@ public void testCacheEntryWithVaryStarHasVariants(){
assertTrue(entry.hasVariants()); 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") @SuppressWarnings("unused")
@Test @Test
public void mustProvideRequestDate() { public void mustProvideRequestDate() {
try { 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"); fail("Should have thrown exception");
} catch (final NullPointerException expected) { } catch (final NullPointerException expected) {
} }
@ -154,7 +159,7 @@ public void mustProvideRequestDate() {
@Test @Test
public void mustProvideResponseDate() { public void mustProvideResponseDate() {
try { 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"); fail("Should have thrown exception");
} catch (final NullPointerException expected) { } catch (final NullPointerException expected) {
} }
@ -164,7 +169,7 @@ public void mustProvideResponseDate() {
@Test @Test
public void mustProvideResponseHeaders() { public void mustProvideResponseHeaders() {
try { 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"); fail("Should have thrown exception");
} catch (final NullPointerException expected) { } catch (final NullPointerException expected) {
} }
@ -172,27 +177,27 @@ public void mustProvideResponseHeaders() {
@Test @Test
public void statusCodeComesFromOriginalStatusLine() { 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()); assertEquals(HttpStatus.SC_OK, entry.getStatus());
} }
@Test @Test
public void canGetOriginalRequestDate() { public void canGetOriginalRequestDate() {
final Date requestDate = new Date(); final Instant requestDate = Instant.now();
entry = new HttpCacheEntry(requestDate, new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource); entry = new HttpCacheEntry(requestDate, Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource);
assertSame(requestDate, entry.getRequestDate()); assertEquals(requestDate, entry.getRequestInstant());
} }
@Test @Test
public void canGetOriginalResponseDate() { public void canGetOriginalResponseDate() {
final Date responseDate = new Date(); final Instant responseDate = Instant.now();
entry = new HttpCacheEntry(new Date(), responseDate, HttpStatus.SC_OK, new Header[]{}, mockResource); entry = new HttpCacheEntry(Instant.now(), responseDate, HttpStatus.SC_OK, new Header[]{}, mockResource);
assertSame(responseDate, entry.getResponseDate()); assertEquals(responseDate, entry.getResponseInstant());
} }
@Test @Test
public void canGetOriginalResource() { 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()); assertSame(mockResource, entry.getResource());
} }
@ -202,7 +207,7 @@ public void canGetOriginalHeaders() {
new BasicHeader("Server", "MockServer/1.0"), new BasicHeader("Server", "MockServer/1.0"),
new BasicHeader("Date", DateUtils.formatStandardDate(now)) 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(); final Header[] result = entry.getHeaders();
assertEquals(headers.length, result.length); assertEquals(headers.length, result.length);
for(int i=0; i<headers.length; i++) { for(int i=0; i<headers.length; i++) {
@ -213,13 +218,13 @@ public void canGetOriginalHeaders() {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Test @Test
public void canConstructWithoutVariants() { public void canConstructWithoutVariants() {
new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, new Header[]{}, mockResource); new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK, new Header[]{}, mockResource);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Test @Test
public void canProvideVariantMap() { public void canProvideVariantMap() {
new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK,
new Header[]{}, mockResource, new Header[]{}, mockResource,
new HashMap<>()); new HashMap<>());
} }
@ -229,7 +234,7 @@ public void canRetrieveOriginalVariantMap() {
final Map<String,String> variantMap = new HashMap<>(); final Map<String,String> variantMap = new HashMap<>();
variantMap.put("A","B"); variantMap.put("A","B");
variantMap.put("C","D"); 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, new Header[]{}, mockResource,
variantMap); variantMap);
final Map<String,String> result = entry.getVariantMap(); final Map<String,String> result = entry.getVariantMap();
@ -243,7 +248,7 @@ public void retrievedVariantMapIsNotModifiable() {
final Map<String,String> variantMap = new HashMap<>(); final Map<String,String> variantMap = new HashMap<>();
variantMap.put("A","B"); variantMap.put("A","B");
variantMap.put("C","D"); 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, new Header[]{}, mockResource,
variantMap); variantMap);
final Map<String,String> result = entry.getVariantMap(); final Map<String,String> result = entry.getVariantMap();
@ -261,7 +266,7 @@ public void retrievedVariantMapIsNotModifiable() {
@Test @Test
public void canConvertToString() { 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); new Header[]{}, mockResource);
assertNotNull(entry.toString()); assertNotNull(entry.toString());
assertNotEquals("", entry.toString()); assertNotEquals("", entry.toString());
@ -270,7 +275,7 @@ public void canConvertToString() {
@Test @Test
public void testMissingDateHeaderIsIgnored() { public void testMissingDateHeaderIsIgnored() {
final Header[] headers = new Header[] {}; final Header[] headers = new Header[] {};
entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK,
headers, mockResource); headers, mockResource);
assertNull(entry.getDate()); assertNull(entry.getDate());
} }
@ -278,7 +283,7 @@ public void testMissingDateHeaderIsIgnored() {
@Test @Test
public void testMalformedDateHeaderIsIgnored() { public void testMalformedDateHeaderIsIgnored() {
final Header[] headers = new Header[] { new BasicHeader("Date", "asdf") }; final Header[] headers = new Header[] { new BasicHeader("Date", "asdf") };
entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK,
headers, mockResource); headers, mockResource);
assertNull(entry.getDate()); assertNull(entry.getDate());
} }
@ -287,20 +292,11 @@ public void testMalformedDateHeaderIsIgnored() {
public void testValidDateHeaderIsParsed() { public void testValidDateHeaderIsParsed() {
final Instant date = Instant.now().with(ChronoField.MILLI_OF_SECOND, 0); final Instant date = Instant.now().with(ChronoField.MILLI_OF_SECOND, 0);
final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatStandardDate(date)) }; final Header[] headers = new Header[] { new BasicHeader("Date", DateUtils.formatStandardDate(date)) };
entry = new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK, entry = new HttpCacheEntry(Instant.now(), Instant.now(), HttpStatus.SC_OK,
headers, mockResource); headers, mockResource);
final Date dateHeaderValue = entry.getDate(); final Date dateHeaderValue = entry.getDate();
assertNotNull(dateHeaderValue); assertNotNull(dateHeaderValue);
assertEquals(DateUtils.toDate(date), 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());
}
} }

View File

@ -34,8 +34,8 @@
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.Map; import java.util.Map;
import org.apache.hc.client5.http.cache.HttpCacheEntry; import org.apache.hc.client5.http.cache.HttpCacheEntry;
@ -59,8 +59,8 @@ class HttpByteArrayCacheEntrySerializerTestUtils {
*/ */
static class HttpCacheStorageEntryTestTemplate { static class HttpCacheStorageEntryTestTemplate {
Resource resource; Resource resource;
Date requestDate; Instant requestDate;
Date responseDate; Instant responseDate;
int responseCode; int responseCode;
Header[] responseHeaders; Header[] responseHeaders;
Map<String, String> variantMap; Map<String, String> variantMap;
@ -120,8 +120,8 @@ private HttpCacheStorageEntryTestTemplate(final HttpCacheStorageEntryTestTemplat
private static final HttpCacheStorageEntryTestTemplate DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE = new HttpCacheStorageEntryTestTemplate(); private static final HttpCacheStorageEntryTestTemplate DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE = new HttpCacheStorageEntryTestTemplate();
static { static {
DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.resource = new HeapResource("Hello World".getBytes(StandardCharsets.UTF_8)); 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.requestDate = Instant.ofEpochMilli(165214800000L);
DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.responseDate = new Date(2611108800000L); 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.responseCode = 200;
DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.responseHeaders = new Header[]{ DEFAULT_HTTP_CACHE_STORAGE_ENTRY_TEST_TEMPLATE.responseHeaders = new Header[]{
new BasicHeader("Content-type", "text/html"), new BasicHeader("Content-type", "text/html"),
@ -220,8 +220,9 @@ static void assertCacheEntriesEqual(final HttpCacheStorageEntry expected, final
final HttpCacheEntry expectedContent = expected.getContent(); final HttpCacheEntry expectedContent = expected.getContent();
final HttpCacheEntry actualContent = actual.getContent(); final HttpCacheEntry actualContent = actual.getContent();
assertEquals(expectedContent.getRequestDate(), actualContent.getRequestDate()); assertEquals(expectedContent.getRequestInstant(), actualContent.getRequestInstant());
assertEquals(expectedContent.getResponseDate(), actualContent.getResponseDate()); assertEquals(expectedContent.getResponseInstant(), actualContent.getResponseInstant());
assertEquals(expectedContent.getStatus(), actualContent.getStatus()); assertEquals(expectedContent.getStatus(), actualContent.getStatus());
assertArrayEquals(expectedContent.getVariantMap().keySet().toArray(), actualContent.getVariantMap().keySet().toArray()); assertArrayEquals(expectedContent.getVariantMap().keySet().toArray(), actualContent.getVariantMap().keySet().toArray());

View File

@ -26,8 +26,8 @@
*/ */
package org.apache.hc.client5.http.impl.cache; package org.apache.hc.client5.http.impl.cache;
import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import org.apache.hc.client5.http.cache.HttpCacheEntry; import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.cache.Resource; import org.apache.hc.client5.http.cache.Resource;
@ -57,16 +57,17 @@ public boolean matches(final Object item) {
if (expectedStatus != otherStatus) { if (expectedStatus != otherStatus) {
return false; return false;
} }
final Date expectedRequestDate = expectedValue.getRequestDate(); final Instant expectedRequestInstant = expectedValue.getRequestInstant();
final Date otherRequestDate = otherValue.getRequestDate(); final Instant otherRequestInstant = otherValue.getRequestInstant();
if (!LangUtils.equals(expectedRequestDate, otherRequestDate)) { if (!LangUtils.equals(expectedRequestInstant, otherRequestInstant)) {
return false; return false;
} }
final Date expectedResponseDate = expectedValue.getResponseDate(); final Instant expectedResponseInstant = expectedValue.getResponseInstant();
final Date otherResponseDate = otherValue.getResponseDate(); final Instant otherResponseInstant = otherValue.getResponseInstant();
if (!LangUtils.equals(expectedResponseDate, otherResponseDate)) { if (!LangUtils.equals(expectedResponseInstant, otherResponseInstant)) {
return false; return false;
} }
final Header[] expectedHeaders = expectedValue.getHeaders(); final Header[] expectedHeaders = expectedValue.getHeaders();
final Header[] otherHeaders = otherValue.getHeaders(); final Header[] otherHeaders = otherValue.getHeaders();
if (expectedHeaders.length != otherHeaders.length) { if (expectedHeaders.length != otherHeaders.length) {

View File

@ -29,7 +29,6 @@
import java.io.InputStream; import java.io.InputStream;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -268,7 +267,7 @@ public static HttpCacheEntry makeCacheEntry(final Map<String,String> variantMap)
return makeCacheEntry(now, now, getStockHeaders(now), return makeCacheEntry(now, now, getStockHeaders(now),
getRandomBytes(128), variantMap); getRandomBytes(128), variantMap);
} }
@SuppressWarnings("deprecation")
public static HttpCacheEntry makeCacheEntry(final Instant requestDate, public static HttpCacheEntry makeCacheEntry(final Instant requestDate,
final Instant responseDate, final Header[] headers, final byte[] bytes, final Instant responseDate, final Header[] headers, final byte[] bytes,
final Map<String,String> variantMap) { final Map<String,String> variantMap) {
@ -295,31 +294,6 @@ public static HttpCacheEntry makeCacheEntry() {
return makeCacheEntry(now, now); 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() { public static ClassicHttpResponse make200Response() {
final ClassicHttpResponse out = new BasicClassicHttpResponse(HttpStatus.SC_OK, "OK"); final ClassicHttpResponse out = new BasicClassicHttpResponse(HttpStatus.SC_OK, "OK");
out.setHeader("Date", DateUtils.formatStandardDate(Instant.now())); out.setHeader("Date", DateUtils.formatStandardDate(Instant.now()));
@ -373,4 +347,30 @@ public static Map<String, String> makeDefaultVariantMap(final String key, final
return variants; 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);
}
} }

View File

@ -34,7 +34,6 @@
import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import java.time.Instant; import java.time.Instant;
import java.util.Date;
import java.util.Map; import java.util.Map;
import org.apache.hc.client5.http.cache.HeaderConstants; import org.apache.hc.client5.http.cache.HeaderConstants;
@ -231,7 +230,7 @@ public void testGetCacheEntryReturnsNullIfNoVariantInCache() throws Exception {
origResponse.setHeader("Vary", "Accept-Encoding"); origResponse.setHeader("Vary", "Accept-Encoding");
origResponse.setHeader("Content-Encoding","gzip"); 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 HttpRequest request = new HttpGet("http://foo.example.com/bar");
final HttpCacheEntry result = impl.getCacheEntry(host, request); final HttpCacheEntry result = impl.getCacheEntry(host, request);
@ -253,7 +252,7 @@ public void testGetCacheEntryReturnsVariantIfPresentInCache() throws Exception {
origResponse.setHeader("Vary", "Accept-Encoding"); origResponse.setHeader("Vary", "Accept-Encoding");
origResponse.setHeader("Content-Encoding","gzip"); 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 HttpRequest request = new HttpGet("http://foo.example.com/bar");
request.setHeader("Accept-Encoding","gzip"); request.setHeader("Accept-Encoding","gzip");
@ -297,8 +296,8 @@ public void testGetVariantCacheEntriesReturnsAllVariants() throws Exception {
resp2.setHeader("Content-Encoding","gzip"); resp2.setHeader("Content-Encoding","gzip");
resp2.setHeader("Vary", "Accept-Encoding"); resp2.setHeader("Vary", "Accept-Encoding");
impl.createCacheEntry(host, req1, resp1, null, new Date(), new Date()); impl.createCacheEntry(host, req1, resp1, null, Instant.now(), Instant.now());
impl.createCacheEntry(host, req2, resp2, null, new Date(), new Date()); impl.createCacheEntry(host, req2, resp2, null, Instant.now(), Instant.now());
final Map<String,Variant> variants = impl.getVariantCacheEntriesWithEtags(host, req1); final Map<String,Variant> variants = impl.getVariantCacheEntriesWithEtags(host, req1);

View File

@ -37,6 +37,7 @@
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -61,7 +62,12 @@ public void setUp() {
} }
@Test @Test
public void canSerializeEntriesWithVariantMaps() throws Exception { public void canSerializeEntriesWithVariantMapsDeprecatedConstructor() throws Exception {
readWriteVerify(makeCacheEntryDeprecatedConstructorWithVariantMap("somekey"));
}
@Test
public void canSerializeEntriesWithVariantMapsAndInstant() throws Exception {
readWriteVerify(makeCacheEntryWithVariantMap("somekey")); readWriteVerify(makeCacheEntryWithVariantMap("somekey"));
} }
@ -85,6 +91,11 @@ public void isAllowedClassNameDataTrue() {
assertIsAllowedClassNameTrue(Date.class.getName()); assertIsAllowedClassNameTrue(Date.class.getName());
} }
@Test
public void isAllowedClassNameInstantTrue() {
assertIsAllowedClassNameTrue(Instant.class.getName());
}
@Test @Test
public void isAllowedClassNameStatusLineTrue() { public void isAllowedClassNameStatusLineTrue() {
assertIsAllowedClassNameTrue(StatusLine.class.getName()); assertIsAllowedClassNameTrue(StatusLine.class.getName());
@ -257,6 +268,27 @@ public void readWriteVerify(final HttpCacheStorageEntry writeEntry) throws Excep
assertThat(readEntry.getContent(), HttpCacheEntryMatcher.equivalent(writeEntry.getContent())); 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<String,String> 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) { private HttpCacheStorageEntry makeCacheEntryWithVariantMap(final String key) {
final Header[] headers = new Header[5]; final Header[] headers = new Header[5];
for (int i = 0; i < headers.length; i++) { 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 1","true");
variantMap.put("test variant 2","true"); variantMap.put("test variant 2","true");
final HttpCacheEntry cacheEntry = new HttpCacheEntry( final HttpCacheEntry cacheEntry = new HttpCacheEntry(
new Date(), Instant.now(),
new Date(), Instant.now(),
HttpStatus.SC_OK, HttpStatus.SC_OK,
headers, headers,
new HeapResource(body.getBytes(StandardCharsets.UTF_8)), variantMap); new HeapResource(body.getBytes(StandardCharsets.UTF_8)), variantMap);

View File

@ -34,7 +34,6 @@
import java.io.IOException; import java.io.IOException;
import java.time.Instant; import java.time.Instant;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -83,7 +82,7 @@ public void testUpdateCacheEntryReturnsDifferentEntryInstance()
throws IOException { throws IOException {
entry = HttpTestUtils.makeCacheEntry(); entry = HttpTestUtils.makeCacheEntry();
final HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry, final HttpCacheEntry newEntry = impl.updateCacheEntry(null, entry,
DateUtils.toDate(requestDate), DateUtils.toDate(responseDate), response); requestDate, responseDate, response);
assertNotSame(newEntry, entry); assertNotSame(newEntry, entry);
} }
@ -96,7 +95,7 @@ public void testHeadersAreMergedCorrectly() throws IOException {
response.setHeaders(); response.setHeaders();
final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, 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("Date", DateUtils.formatStandardDate(responseDate)));
assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\"")); assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
@ -116,7 +115,7 @@ public void testNewerHeadersReplaceExistingHeaders() throws IOException {
new BasicHeader("Cache-Control", "public")); new BasicHeader("Cache-Control", "public"));
final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, 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("Date", DateUtils.formatStandardDate(requestDate)));
assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\"")); assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
@ -136,7 +135,7 @@ public void testNewHeadersAreAddedByMerge() throws IOException {
new BasicHeader("Cache-Control", "public")); new BasicHeader("Cache-Control", "public"));
final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, 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("Date", DateUtils.formatStandardDate(requestDate)));
assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\"")); assertThat(updatedEntry, ContainsHeaderMatcher.contains("ETag", "\"etag\""));
@ -154,8 +153,8 @@ public void oldHeadersRetainedIfResponseOlderThanEntry()
entry = HttpTestUtils.makeCacheEntry(twoSecondsAgo, now, headers); entry = HttpTestUtils.makeCacheEntry(twoSecondsAgo, now, headers);
response.setHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo)); response.setHeader("Date", DateUtils.formatStandardDate(tenSecondsAgo));
response.setHeader("ETag", "\"old-etag\""); response.setHeader("ETag", "\"old-etag\"");
final HttpCacheEntry result = impl.updateCacheEntry("A", entry, new Date(), final HttpCacheEntry result = impl.updateCacheEntry("A", entry, Instant.now(),
new Date(), response); Instant.now(), response);
assertThat(result, ContainsHeaderMatcher.contains("Date", DateUtils.formatStandardDate(oneSecondAgo))); assertThat(result, ContainsHeaderMatcher.contains("Date", DateUtils.formatStandardDate(oneSecondAgo)));
assertThat(result, ContainsHeaderMatcher.contains("ETag", "\"new-etag\"")); assertThat(result, ContainsHeaderMatcher.contains("ETag", "\"new-etag\""));
} }
@ -165,10 +164,10 @@ public void testUpdatedEntryHasLatestRequestAndResponseDates()
throws IOException { throws IOException {
entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo); entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo);
final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
DateUtils.toDate(twoSecondsAgo), DateUtils.toDate(oneSecondAgo), response); twoSecondsAgo, oneSecondAgo, response);
assertEquals(DateUtils.toDate(twoSecondsAgo), updated.getRequestDate()); assertEquals(twoSecondsAgo, updated.getRequestInstant());
assertEquals(DateUtils.toDate(oneSecondAgo), updated.getResponseDate()); assertEquals(oneSecondAgo, updated.getResponseInstant());
} }
@Test @Test
@ -182,7 +181,7 @@ public void entry1xxWarningsAreRemovedOnUpdate() throws Exception {
response.setHeader("ETag", "\"new\""); response.setHeader("ETag", "\"new\"");
response.setHeader("Date", DateUtils.formatStandardDate(twoSecondsAgo)); response.setHeader("Date", DateUtils.formatStandardDate(twoSecondsAgo));
final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
DateUtils.toDate(twoSecondsAgo), DateUtils.toDate(oneSecondAgo), response); twoSecondsAgo, oneSecondAgo, response);
assertEquals(0, updated.getHeaders("Warning").length); assertEquals(0, updated.getHeaders("Warning").length);
} }
@ -197,7 +196,7 @@ public void entryWithMalformedDateIsStillUpdated() throws Exception {
response.setHeader("ETag", "\"new\""); response.setHeader("ETag", "\"new\"");
response.setHeader("Date", DateUtils.formatStandardDate(twoSecondsAgo)); response.setHeader("Date", DateUtils.formatStandardDate(twoSecondsAgo));
final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, final HttpCacheEntry updated = impl.updateCacheEntry(null, entry,
DateUtils.toDate(twoSecondsAgo), DateUtils.toDate(oneSecondAgo), response); twoSecondsAgo, oneSecondAgo, response);
assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue()); assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue());
} }
@ -211,8 +210,8 @@ public void entryIsStillUpdatedByResponseWithMalformedDate() throws Exception {
entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers); entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, headers);
response.setHeader("ETag", "\"new\""); response.setHeader("ETag", "\"new\"");
response.setHeader("Date", "bad-date"); response.setHeader("Date", "bad-date");
final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, final HttpCacheEntry updated = impl.updateCacheEntry(null, entry, twoSecondsAgo,
DateUtils.toDate(twoSecondsAgo), DateUtils.toDate(oneSecondAgo), response); oneSecondAgo, response);
assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue()); assertEquals("\"new\"", updated.getFirstHeader("ETag").getValue());
} }
@ -222,7 +221,7 @@ public void cannotUpdateFromANon304OriginResponse() throws Exception {
entry = HttpTestUtils.makeCacheEntry(); entry = HttpTestUtils.makeCacheEntry();
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK"); response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
try { try {
impl.updateCacheEntry("A", entry, new Date(), new Date(), impl.updateCacheEntry("A", entry, Instant.now(), Instant.now(),
response); response);
fail("should have thrown exception"); fail("should have thrown exception");
} catch (final IllegalArgumentException expected) { } catch (final IllegalArgumentException expected) {
@ -261,7 +260,7 @@ public void testContentEncodingHeaderIsNotUpdatedByMerge() throws IOException {
new BasicHeader("Content-Encoding", "gzip")); new BasicHeader("Content-Encoding", "gzip"));
final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
new Date(), new Date(), response); Instant.now(), Instant.now(), response);
final Header[] updatedHeaders = updatedEntry.getHeaders(); final Header[] updatedHeaders = updatedEntry.getHeaders();
headersContain(updatedHeaders, "Content-Encoding", "identity"); headersContain(updatedHeaders, "Content-Encoding", "identity");
@ -281,7 +280,7 @@ public void testContentLengthIsNotAddedWhenTransferEncodingIsPresent() throws IO
new BasicHeader("Content-Length", "0")); new BasicHeader("Content-Length", "0"));
final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry, final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
new Date(), new Date(), response); Instant.now(), Instant.now(), response);
final Header[] updatedHeaders = updatedEntry.getHeaders(); final Header[] updatedHeaders = updatedEntry.getHeaders();
headersContain(updatedHeaders, "Transfer-Encoding", "chunked"); headersContain(updatedHeaders, "Transfer-Encoding", "chunked");

View File

@ -33,7 +33,6 @@
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.Instant; import java.time.Instant;
import java.util.Date;
import org.apache.hc.client5.http.cache.HttpCacheEntry; import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.utils.DateUtils; import org.apache.hc.client5.http.utils.DateUtils;
@ -141,7 +140,7 @@ protected TimeValue getResponseDelay(final HttpCacheEntry ent) {
@Test @Test
public void testResidentTimeSecondsIsTimeSinceResponseTime() { public void testResidentTimeSecondsIsTimeSinceResponseTime() {
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, sixSecondsAgo); 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 @Test
@ -153,11 +152,11 @@ protected TimeValue getCorrectedInitialAge(final HttpCacheEntry ent) {
return TimeValue.ofSeconds(11); return TimeValue.ofSeconds(11);
} }
@Override @Override
protected TimeValue getResidentTime(final HttpCacheEntry ent, final Date d) { protected TimeValue getResidentTime(final HttpCacheEntry ent, final Instant d) {
return TimeValue.ofSeconds(17); return TimeValue.ofSeconds(17);
} }
}; };
assertEquals(TimeValue.ofSeconds(28), impl.getCurrentAge(entry, new Date())); assertEquals(TimeValue.ofSeconds(28), impl.getCurrentAge(entry, Instant.now()));
} }
@Test @Test
@ -250,9 +249,9 @@ public void testResponseIsFreshIfFreshnessLifetimeExceedsCurrentAge() {
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
impl = new CacheValidityPolicy() { impl = new CacheValidityPolicy() {
@Override @Override
public TimeValue getCurrentAge(final HttpCacheEntry e, final Date d) { public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) {
assertSame(entry, e); assertSame(entry, e);
assertEquals(DateUtils.toDate(now), d); assertEquals(now, d);
return TimeValue.ofSeconds(6); return TimeValue.ofSeconds(6);
} }
@Override @Override
@ -261,7 +260,7 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry e) {
return TimeValue.ofSeconds(10); return TimeValue.ofSeconds(10);
} }
}; };
assertTrue(impl.isResponseFresh(entry, DateUtils.toDate(now))); assertTrue(impl.isResponseFresh(entry, now));
} }
@Test @Test
@ -269,8 +268,8 @@ public void testResponseIsNotFreshIfFreshnessLifetimeEqualsCurrentAge() {
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
impl = new CacheValidityPolicy() { impl = new CacheValidityPolicy() {
@Override @Override
public TimeValue getCurrentAge(final HttpCacheEntry e, final Date d) { public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) {
assertEquals(DateUtils.toDate(now), d); assertEquals(now, d);
assertSame(entry, e); assertSame(entry, e);
return TimeValue.ofSeconds(6); return TimeValue.ofSeconds(6);
} }
@ -280,7 +279,7 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry e) {
return TimeValue.ofSeconds(6); return TimeValue.ofSeconds(6);
} }
}; };
assertFalse(impl.isResponseFresh(entry, DateUtils.toDate(now))); assertFalse(impl.isResponseFresh(entry, now));
} }
@Test @Test
@ -288,8 +287,8 @@ public void testResponseIsNotFreshIfCurrentAgeExceedsFreshnessLifetime() {
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry();
impl = new CacheValidityPolicy() { impl = new CacheValidityPolicy() {
@Override @Override
public TimeValue getCurrentAge(final HttpCacheEntry e, final Date d) { public TimeValue getCurrentAge(final HttpCacheEntry e, final Instant d) {
assertEquals(DateUtils.toDate(now), d); assertEquals(now, d);
assertSame(entry, e); assertSame(entry, e);
return TimeValue.ofSeconds(10); return TimeValue.ofSeconds(10);
} }
@ -299,7 +298,7 @@ public TimeValue getFreshnessLifetime(final HttpCacheEntry e) {
return TimeValue.ofSeconds(6); return TimeValue.ofSeconds(6);
} }
}; };
assertFalse(impl.isResponseFresh(entry, DateUtils.toDate(now))); assertFalse(impl.isResponseFresh(entry, now));
} }
@Test @Test
@ -421,7 +420,7 @@ public void testMayReturnStaleIfErrorInResponseIsTrueWithinStaleness(){
}; };
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
final HttpRequest req = new BasicHttpRequest("GET","/"); final HttpRequest req = new BasicHttpRequest("GET","/");
assertTrue(impl.mayReturnStaleIfError(req, entry, DateUtils.toDate(now))); assertTrue(impl.mayReturnStaleIfError(req, entry, now));
} }
@Test @Test
@ -433,7 +432,7 @@ public void testMayReturnStaleIfErrorInRequestIsTrueWithinStaleness(){
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
final HttpRequest req = new BasicHttpRequest("GET","/"); final HttpRequest req = new BasicHttpRequest("GET","/");
req.setHeader("Cache-Control","stale-if-error=15"); req.setHeader("Cache-Control","stale-if-error=15");
assertTrue(impl.mayReturnStaleIfError(req, entry, DateUtils.toDate(now))); assertTrue(impl.mayReturnStaleIfError(req, entry, now));
} }
@Test @Test
@ -444,7 +443,7 @@ public void testMayNotReturnStaleIfErrorInResponseAndAfterResponseWindow(){
}; };
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
final HttpRequest req = new BasicHttpRequest("GET","/"); final HttpRequest req = new BasicHttpRequest("GET","/");
assertFalse(impl.mayReturnStaleIfError(req, entry, DateUtils.toDate(now))); assertFalse(impl.mayReturnStaleIfError(req, entry, now));
} }
@Test @Test
@ -456,7 +455,7 @@ public void testMayNotReturnStaleIfErrorInResponseAndAfterRequestWindow(){
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
final HttpRequest req = new BasicHttpRequest("GET","/"); final HttpRequest req = new BasicHttpRequest("GET","/");
req.setHeader("Cache-Control","stale-if-error=1"); req.setHeader("Cache-Control","stale-if-error=1");
assertFalse(impl.mayReturnStaleIfError(req, entry, DateUtils.toDate(now))); assertFalse(impl.mayReturnStaleIfError(req, entry, now));
} }
@Test @Test
@ -464,7 +463,7 @@ public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveIsAbsent() {
final Header[] headers = new Header[] { new BasicHeader("Cache-control", "public") }; final Header[] headers = new Header[] { new BasicHeader("Cache-control", "public") };
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(headers);
assertFalse(impl.mayReturnStaleWhileRevalidating(entry, DateUtils.toDate(now))); assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
} }
@Test @Test
@ -475,7 +474,7 @@ public void testMayReturnStaleWhileRevalidatingIsTrueWhenWithinStaleness() {
}; };
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
assertTrue(impl.mayReturnStaleWhileRevalidating(entry, DateUtils.toDate(now))); assertTrue(impl.mayReturnStaleWhileRevalidating(entry, now));
} }
@Test @Test
@ -487,7 +486,7 @@ public void testMayReturnStaleWhileRevalidatingIsFalseWhenPastStaleness() {
}; };
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
assertFalse(impl.mayReturnStaleWhileRevalidating(entry, DateUtils.toDate(now))); assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
} }
@Test @Test
@ -498,6 +497,6 @@ public void testMayReturnStaleWhileRevalidatingIsFalseWhenDirectiveEmpty() {
}; };
final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers); final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(now, now, headers);
assertFalse(impl.mayReturnStaleWhileRevalidating(entry, DateUtils.toDate(now))); assertFalse(impl.mayReturnStaleWhileRevalidating(entry, now));
} }
} }

View File

@ -32,7 +32,7 @@
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.util.Date; import java.time.Instant;
import java.util.HashMap; import java.util.HashMap;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse; import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
@ -112,7 +112,7 @@ public void testAgeHeaderIsPopulatedWithCurrentAgeOfCacheEntryIfNonZero() throws
final SimpleHttpResponse response = impl.generateResponse(request, entry); 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"); final Header ageHdr = response.getFirstHeader("Age");
Assertions.assertNotNull(ageHdr); Assertions.assertNotNull(ageHdr);
@ -125,7 +125,7 @@ public void testAgeHeaderIsNotPopulatedIfCurrentAgeOfCacheEntryIsZero() throws E
final SimpleHttpResponse response = impl.generateResponse(request, entry); 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"); final Header ageHdr = response.getFirstHeader("Age");
Assertions.assertNull(ageHdr); Assertions.assertNull(ageHdr);
@ -137,7 +137,7 @@ public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() throws Except
final SimpleHttpResponse response = impl.generateResponse(request, entry); 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"); final Header ageHdr = response.getFirstHeader("Age");
Assertions.assertNotNull(ageHdr); Assertions.assertNotNull(ageHdr);
@ -147,7 +147,7 @@ public void testAgeHeaderIsPopulatedWithMaxAgeIfCurrentAgeTooBig() throws Except
private void currentAge(final TimeValue age) { private void currentAge(final TimeValue age) {
when( when(
mockValidityPolicy.getCurrentAge(same(entry), mockValidityPolicy.getCurrentAge(same(entry),
isA(Date.class))).thenReturn(age); isA(Instant.class))).thenReturn(age);
} }
@Test @Test

View File

@ -78,7 +78,7 @@ public void testNotSuitableIfContentLengthHeaderIsWrong() {
new BasicHeader("Content-Length","1") new BasicHeader("Content-Length","1")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -89,7 +89,7 @@ public void testSuitableIfCacheEntryIsFresh() {
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -100,7 +100,7 @@ public void testNotSuitableIfCacheEntryIsNotFresh() {
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -112,7 +112,7 @@ public void testNotSuitableIfRequestHasNoCache() {
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -124,7 +124,7 @@ public void testNotSuitableIfAgeExceedsRequestMaxAge() {
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -136,7 +136,7 @@ public void testSuitableIfFreshAndAgeIsUnderRequestMaxAge() {
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -148,7 +148,7 @@ public void testSuitableIfFreshAndFreshnessLifetimeGreaterThanRequestMinFresh()
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -160,7 +160,7 @@ public void testNotSuitableIfFreshnessLifetimeLessThanRequestMinFresh() {
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -172,7 +172,7 @@ public void testSuitableEvenIfStaleButPermittedByRequestMaxStale() {
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -184,7 +184,7 @@ public void testNotSuitableIfStaleButTooStaleForRequestMaxStale() {
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); 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") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -209,7 +209,7 @@ public void testMalformedCacheControlMinFreshRequestHeaderCausesUnsuitableEntry(
new BasicHeader("Content-Length","128") new BasicHeader("Content-Length","128")
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -230,7 +230,7 @@ public void testSuitableIfCacheEntryIsHeuristicallyFreshEnough() {
.setHeuristicCoefficient(0.1f).build(); .setHeuristicCoefficient(0.1f).build();
impl = new CachedResponseSuitabilityChecker(config); impl = new CachedResponseSuitabilityChecker(config);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -248,7 +248,7 @@ public void testSuitableIfCacheEntryIsHeuristicallyFreshEnoughByDefault() {
.build(); .build();
impl = new CachedResponseSuitabilityChecker(config); impl = new CachedResponseSuitabilityChecker(config);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -261,7 +261,7 @@ public void testSuitableIfRequestMethodisHEAD() {
}; };
entry = getEntry(headers); entry = getEntry(headers);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, headRequest, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, headRequest, entry, now));
} }
@Test @Test
@ -273,7 +273,7 @@ public void testNotSuitableIfRequestMethodIsGETAndEntryResourceIsNull() {
}; };
entry = HttpTestUtils.makeHeadCacheEntry(headers); entry = HttpTestUtils.makeHeadCacheEntry(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -286,7 +286,7 @@ public void testNotSuitableForGETIfEntryDoesNotSpecifyARequestMethodOrEntity() {
}; };
entry = HttpTestUtils.makeCacheEntryWithNoRequestMethodOrEntity(headers); entry = HttpTestUtils.makeCacheEntryWithNoRequestMethodOrEntity(headers);
Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertFalse(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -299,7 +299,7 @@ public void testSuitableForGETIfEntryDoesNotSpecifyARequestMethodButContainsEnti
}; };
entry = HttpTestUtils.makeCacheEntryWithNoRequestMethod(headers); entry = HttpTestUtils.makeCacheEntryWithNoRequestMethod(headers);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -311,7 +311,7 @@ public void testSuitableForGETIfHeadResponseCachingEnabledAndEntryDoesNotSpecify
}; };
entry = HttpTestUtils.make204CacheEntryWithNoRequestMethod(headers); entry = HttpTestUtils.make204CacheEntryWithNoRequestMethod(headers);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, request, entry, now));
} }
@Test @Test
@ -325,6 +325,6 @@ public void testSuitableForHEADIfHeadResponseCachingEnabledAndEntryDoesNotSpecif
}; };
entry = HttpTestUtils.makeHeadCacheEntryWithNoRequestMethod(headers); entry = HttpTestUtils.makeHeadCacheEntryWithNoRequestMethod(headers);
Assertions.assertTrue(impl.canCachedResponseBeUsed(host, headRequest, entry, DateUtils.toDate(now))); Assertions.assertTrue(impl.canCachedResponseBeUsed(host, headRequest, entry, now));
} }
} }

View File

@ -1009,8 +1009,7 @@ public void testTooLargeResponsesAreNotCached() throws Exception {
originResponse.setHeader("ETag", "\"etag\""); originResponse.setHeader("ETag", "\"etag\"");
final ExecChain.Scope scope = new ExecChain.Scope("test", route, request, mockExecRuntime, context); final ExecChain.Scope scope = new ExecChain.Scope("test", route, request, mockExecRuntime, context);
impl.cacheAndReturnResponse(host, request, originResponse, scope, impl.cacheAndReturnResponse(host, request, originResponse, scope, requestSent, responseReceived);
DateUtils.toDate(requestSent), DateUtils.toDate(responseReceived));
Mockito.verify(cache, Mockito.never()).createCacheEntry( Mockito.verify(cache, Mockito.never()).createCacheEntry(
Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
@ -1043,12 +1042,11 @@ public void testSmallEnoughResponsesAreCached() throws Exception {
RequestEquivalent.eq(request), RequestEquivalent.eq(request),
ResponseEquivalent.eq(response), ResponseEquivalent.eq(response),
Mockito.any(), Mockito.any(),
Mockito.eq(DateUtils.toDate(requestSent)), Mockito.eq(requestSent),
Mockito.eq(DateUtils.toDate(responseReceived)))).thenReturn(httpCacheEntry); Mockito.eq(responseReceived))).thenReturn(httpCacheEntry);
final ExecChain.Scope scope = new ExecChain.Scope("test", route, request, mockExecRuntime, context); final ExecChain.Scope scope = new ExecChain.Scope("test", route, request, mockExecRuntime, context);
impl.cacheAndReturnResponse(host, request, originResponse, scope, impl.cacheAndReturnResponse(host, request, originResponse, scope, requestSent, responseReceived);
DateUtils.toDate(requestSent), DateUtils.toDate(responseReceived));
Mockito.verify(mockCache).createCacheEntry( Mockito.verify(mockCache).createCacheEntry(
Mockito.any(), Mockito.any(),

View File

@ -82,6 +82,98 @@ public void before() {
serializer = HttpByteArrayCacheEntrySerializer.INSTANCE; 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<ClassicHttpResponse> 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<ClassicHttpResponse> 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. * 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. * Attempt to store a cache entry with a null storage key.
* *
* @throws Exception is expected
*/ */
@Test @Test
public void testNullStorageKey() throws Exception { public void testNullStorageKey() {
final HttpCacheStorageEntryTestTemplate cacheObjectValues = HttpCacheStorageEntryTestTemplate.makeDefault(); final HttpCacheStorageEntryTestTemplate cacheObjectValues = HttpCacheStorageEntryTestTemplate.makeDefault();
cacheObjectValues.storageKey = null; cacheObjectValues.storageKey = null;
@ -291,71 +382,6 @@ public void noBodyTestFromPreviouslySerialized() throws Exception {
verifyHttpCacheEntryFromTestFile(serializer, testEntry, NO_BODY_TEST_SERIALIZED_NAME, reserializeFiles); 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. * Test an HttpException being thrown while serializing.
* *
@ -382,26 +408,5 @@ protected AbstractMessageWriter<SimpleHttpResponse> makeHttpResponseWriter(final
testSerializer.serialize(testEntry)); testSerializer.serialize(testEntry));
} }
/**
* Test an IOException being thrown while deserializing.
*
* @throws Exception is expected
*/
@Test
public void testDeserializeWithIOException() throws Exception {
final AbstractMessageParser<ClassicHttpResponse> 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<ClassicHttpResponse> makeHttpResponseParser() {
return throwyParser;
}
};
Assertions.assertThrows(ResourceIOException.class, () ->
testSerializer.deserialize(new byte[0]));
}
} }

View File

@ -204,7 +204,7 @@ public void testConstructWarnValueWithAscTimeWarnDate() throws Exception {
Assertions.assertEquals("fred", impl.getWarnAgent()); Assertions.assertEquals("fred", impl.getWarnAgent());
Assertions.assertEquals("\"stale\"", impl.getWarnText()); Assertions.assertEquals("\"stale\"", impl.getWarnText());
final Instant target = DateUtils.parseStandardDate("Sun Nov 6 08:49:37 1994"); 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 @Test
@ -214,7 +214,7 @@ public void testConstructWarnValueWithRFC850WarnDate() throws Exception {
Assertions.assertEquals("fred", impl.getWarnAgent()); Assertions.assertEquals("fred", impl.getWarnAgent());
Assertions.assertEquals("\"stale\"", impl.getWarnText()); Assertions.assertEquals("\"stale\"", impl.getWarnText());
final Instant target = DateUtils.parseStandardDate("Sunday, 06-Nov-94 08:49:37 GMT"); 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 @Test
@ -224,7 +224,7 @@ public void testConstructWarnValueWithRFC1123WarnDate() throws Exception {
Assertions.assertEquals("fred", impl.getWarnAgent()); Assertions.assertEquals("fred", impl.getWarnAgent());
Assertions.assertEquals("\"stale\"", impl.getWarnText()); Assertions.assertEquals("\"stale\"", impl.getWarnText());
final Instant target = DateUtils.parseStandardDate("Sun, 06 Nov 1994 08:49:37 GMT"); 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());
} }
} }

View File

@ -33,6 +33,7 @@
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
@ -260,21 +261,48 @@ ClassicHttpRequest getRequest() {
return request; return request;
} }
/**
* @deprecated Use {@link #setDate(Instant)}
*/
@Deprecated
public Request setDate(final Date date) { public Request setDate(final Date date) {
this.request.setHeader(HttpHeader.DATE, DateUtils.formatStandardDate(DateUtils.toInstant(date))); this.request.setHeader(HttpHeader.DATE, DateUtils.formatStandardDate(DateUtils.toInstant(date)));
return this; return this;
} }
/**
* @deprecated Use {@link #setIfModifiedSince(Instant)}
*/
@Deprecated
public Request setIfModifiedSince(final Date date) { public Request setIfModifiedSince(final Date date) {
this.request.setHeader(HttpHeader.IF_MODIFIED_SINCE, DateUtils.formatStandardDate(DateUtils.toInstant(date))); this.request.setHeader(HttpHeader.IF_MODIFIED_SINCE, DateUtils.formatStandardDate(DateUtils.toInstant(date)));
return this; return this;
} }
/**
* @deprecated Use {@link #setIfUnmodifiedSince(Instant)}
*/
@Deprecated
public Request setIfUnmodifiedSince(final Date date) { public Request setIfUnmodifiedSince(final Date date) {
this.request.setHeader(HttpHeader.IF_UNMODIFIED_SINCE, DateUtils.formatStandardDate(DateUtils.toInstant(date))); this.request.setHeader(HttpHeader.IF_UNMODIFIED_SINCE, DateUtils.formatStandardDate(DateUtils.toInstant(date)));
return this; 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 //// HTTP protocol parameter operations
public Request version(final HttpVersion version) { public Request version(final HttpVersion version) {

View File

@ -248,7 +248,7 @@ public String toString() {
public static RequestConfig.Builder custom() { public static RequestConfig.Builder custom() {
return new Builder(); return new Builder();
} }
@SuppressWarnings("deprecation")
public static RequestConfig.Builder copy(final RequestConfig config) { public static RequestConfig.Builder copy(final RequestConfig config) {
return new Builder() return new Builder()
.setExpectContinueEnabled(config.isExpectContinueEnabled()) .setExpectContinueEnabled(config.isExpectContinueEnabled())

View File

@ -29,6 +29,7 @@
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.Serializable; import java.io.Serializable;
import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
@ -83,7 +84,7 @@ public void addCookie(final Cookie cookie) {
try { try {
// first remove any old cookie that is equivalent // first remove any old cookie that is equivalent
cookies.remove(cookie); cookies.remove(cookie);
if (!cookie.isExpired(new Date())) { if (!cookie.isExpired(Instant.now())) {
cookies.add(cookie); cookies.add(cookie);
} }
} finally { } finally {
@ -136,6 +137,7 @@ public List<Cookie> getCookies() {
* @see Cookie#isExpired(Date) * @see Cookie#isExpired(Date)
*/ */
@Override @Override
@SuppressWarnings("deprecation")
public boolean clearExpired(final Date date) { public boolean clearExpired(final Date date) {
if (date == null) { if (date == null) {
return false; 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<Cookie> it = cookies.iterator(); it.hasNext(); ) {
if (it.next().isExpired(instant)) {
it.remove();
removed = true;
}
}
return removed;
} finally {
lock.writeLock().unlock();
}
}
/** /**
* Clears all cookies. * Clears all cookies.
*/ */

View File

@ -27,6 +27,7 @@
package org.apache.hc.client5.http.cookie; package org.apache.hc.client5.http.cookie;
import java.time.Instant;
import java.util.Date; import java.util.Date;
/** /**
@ -77,9 +78,26 @@ public interface Cookie {
* considered immutable. Changing it (e.g. using setTime()) could result * considered immutable. Changing it (e.g. using setTime()) could result
* in undefined behaviour. Do so at your peril. </p> * in undefined behaviour. Do so at your peril. </p>
* @return Expiration {@link Date}, or {@code null}. * @return Expiration {@link Date}, or {@code null}.
* @deprecated Use {{@link #getExpiryInstant()}}
*/ */
@Deprecated
Date getExpiryDate(); Date getExpiryDate();
/**
* Returns the expiration {@link Instant} of the cookie, or {@code null} if none exists.
* <p><strong>Note:</strong> 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. </p>
*
* @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 * Returns {@code false} if the cookie should be discarded at the end
* of the "session"; {@code true} otherwise. * of the "session"; {@code true} otherwise.
@ -119,13 +137,34 @@ public interface Cookie {
* @param date Current time * @param date Current time
* *
* @return {@code true} if the cookie has expired. * @return {@code true} if the cookie has expired.
* @deprecated Use {{@link #isExpired(Instant)}}
*/ */
@Deprecated
boolean isExpired(final Date date); 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. * Returns creation time of the cookie.
*/ */
Date getCreationDate(); default Instant getCreationInstant() { return null; }
/** /**
* Checks whether this Cookie has been marked as {@code httpOnly}. * Checks whether this Cookie has been marked as {@code httpOnly}.

View File

@ -27,8 +27,8 @@
package org.apache.hc.client5.http.cookie; package org.apache.hc.client5.http.cookie;
import java.time.Instant;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; 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 l2 = getPathLength(c2);
final int result = l2 - l1; final int result = l2 - l1;
if (result == 0) { if (result == 0) {
final Date d1 = c1.getCreationDate(); final Instant d1 = c1.getCreationInstant();
final Date d2 = c2.getCreationDate(); final Instant d2 = c2.getCreationInstant();
if (d1 != null && d2 != null) { if (d1 != null && d2 != null) {
return (int) (d1.getTime() - d2.getTime()); return (int) (d1.toEpochMilli() - d2.toEpochMilli());
} }
} }
return result; return result;

View File

@ -26,6 +26,7 @@
*/ */
package org.apache.hc.client5.http.cookie; package org.apache.hc.client5.http.cookie;
import java.time.Instant;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -58,9 +59,22 @@ public interface CookieStore {
* the specified {@link java.util.Date}. * the specified {@link java.util.Date}.
* *
* @return true if any cookies were purged. * @return true if any cookies were purged.
* @deprecated Use {@link #clearExpired(Instant)}
*/ */
@Deprecated
boolean clearExpired(Date date); 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. * Clears all cookies.
*/ */

View File

@ -27,8 +27,11 @@
package org.apache.hc.client5.http.cookie; package org.apache.hc.client5.http.cookie;
import java.time.Instant;
import java.util.Date; import java.util.Date;
import org.apache.hc.client5.http.utils.DateUtils;
/** /**
* This interface represents a {@code Set-Cookie} response header sent by the * 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. * 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. * @param expiryDate the {@link Date} after which this cookie is no longer valid.
* *
* @see Cookie#getExpiryDate * @see Cookie#getExpiryDate
* * @deprecated Use {{@link #setExpiryDate(Instant)}}
*/ */
@Deprecated
void setExpiryDate (Date expiryDate); void setExpiryDate (Date expiryDate);
/**
* Sets expiration date.
* <p><strong>Note:</strong> 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.</p>
*
* @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. * Sets the domain attribute.
* *

View File

@ -749,7 +749,7 @@ protected void addCloseable(final Closeable closeable) {
} }
closeables.add(closeable); closeables.add(closeable);
} }
@SuppressWarnings("deprecated")
public CloseableHttpAsyncClient build() { public CloseableHttpAsyncClient build() {
AsyncClientConnectionManager connManagerCopy = this.connManager; AsyncClientConnectionManager connManagerCopy = this.connManager;
if (connManagerCopy == null) { if (connManagerCopy == null) {

View File

@ -28,12 +28,14 @@
package org.apache.hc.client5.http.impl.cookie; package org.apache.hc.client5.http.impl.cookie;
import java.io.Serializable; import java.io.Serializable;
import java.time.Instant;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.hc.client5.http.cookie.SetCookie; import org.apache.hc.client5.http.cookie.SetCookie;
import org.apache.hc.client5.http.utils.DateUtils;
import org.apache.hc.core5.util.Args; import org.apache.hc.core5.util.Args;
/** /**
@ -99,9 +101,19 @@ public void setValue(final String value) {
* *
* @see #setExpiryDate(java.util.Date) * @see #setExpiryDate(java.util.Date)
* *
* @deprecated Use {@link #getExpiryInstant()}
*/ */
@Deprecated
@Override @Override
public Date getExpiryDate() { public Date getExpiryDate() {
return DateUtils.toDate(cookieExpiryDate);
}
/**
* {@inheritDoc}
*/
@Override
public Instant getExpiryInstant() {
return cookieExpiryDate; return cookieExpiryDate;
} }
@ -113,12 +125,28 @@ public Date getExpiryDate() {
* *
* @param expiryDate the {@link Date} after which this cookie is no longer valid. * @param expiryDate the {@link Date} after which this cookie is no longer valid.
* *
* @see #getExpiryDate * @deprecated Use {{@link #setExpiryDate(Instant)}}
* *
*/ */
@Deprecated
@Override @Override
public void setExpiryDate (final Date expiryDate) { public void setExpiryDate (final Date expiryDate) {
cookieExpiryDate = expiryDate; cookieExpiryDate = DateUtils.toInstant(expiryDate);
}
/**
* Sets expiration date.
* <p><strong>Note:</strong> 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.</p>
*
* @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;
} }
@ -233,19 +261,46 @@ public void setHttpOnly(final boolean httpOnly) {
* @param date Current time * @param date Current time
* *
* @return {@code true} if the cookie has expired. * @return {@code true} if the cookie has expired.
*
* @deprecated Use {@link #isExpired(Instant)}
*/ */
@Deprecated
@Override @Override
public boolean isExpired(final Date date) { public boolean isExpired(final Date date) {
Args.notNull(date, "Date"); Args.notNull(date, "Date");
return (cookieExpiryDate != null 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());
} }
/** /**
* @since 4.4 * @since 4.4
*
* @deprecated Use {@link #getCreationInstant()}.
*/ */
@Deprecated
@Override @Override
public Date getCreationDate() { public Date getCreationDate() {
return DateUtils.toDate(creationDate);
}
/**
* @since 5.2
*/
@Override
public Instant getCreationInstant() {
return creationDate; return creationDate;
} }
@ -261,8 +316,17 @@ public boolean isHttpOnly() {
/** /**
* @since 4.4 * @since 4.4
* @deprecated Use {@link #setCreationDate(Instant)}
*/ */
@Deprecated
public void setCreationDate(final Date creationDate) { public void setCreationDate(final Date creationDate) {
this.creationDate = DateUtils.toInstant(creationDate);
}
/**
* @since 5.2
*/
public void setCreationDate(final Instant creationDate) {
this.creationDate = creationDate; this.creationDate = creationDate;
} }
@ -329,8 +393,8 @@ public String toString() {
/** Domain attribute. */ /** Domain attribute. */
private String cookieDomain; private String cookieDomain;
/** Expiration {@link Date}. */ /** Expiration {@link Instant}. */
private Date cookieExpiryDate; private Instant cookieExpiryDate;
/** Path attribute. */ /** Path attribute. */
private String cookiePath; private String cookiePath;
@ -338,7 +402,7 @@ public String toString() {
/** My secure flag. */ /** My secure flag. */
private boolean isSecure; private boolean isSecure;
private Date creationDate; private Instant creationDate;
/** The {@code httpOnly} flag. */ /** The {@code httpOnly} flag. */
private boolean httpOnly; private boolean httpOnly;

View File

@ -86,7 +86,7 @@ public void parse(final SetCookie cookie, final String value)
throw new MalformedCookieException("Invalid 'expires' attribute: " throw new MalformedCookieException("Invalid 'expires' attribute: "
+ value); + value);
} }
cookie.setExpiryDate(DateUtils.toDate(expiry)); cookie.setExpiryDate(expiry);
} }
@Override @Override

View File

@ -26,7 +26,7 @@
*/ */
package org.apache.hc.client5.http.impl.cookie; 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.CommonCookieAttributeHandler;
import org.apache.hc.client5.http.cookie.Cookie; 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: " throw new MalformedCookieException ("Negative 'max-age' attribute: "
+ value); + value);
} }
cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L)); cookie.setExpiryDate(Instant.now().plusSeconds(age));
} }
@Override @Override

View File

@ -41,7 +41,6 @@
import org.apache.hc.client5.http.cookie.Cookie; import org.apache.hc.client5.http.cookie.Cookie;
import org.apache.hc.client5.http.cookie.MalformedCookieException; import org.apache.hc.client5.http.cookie.MalformedCookieException;
import org.apache.hc.client5.http.cookie.SetCookie; 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.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.util.Args; 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, final Instant expiryDate = ZonedDateTime.of(year, month.getValue(), day, hour, minute, second, 0,
ZoneId.of("UTC")).toInstant(); ZoneId.of("UTC")).toInstant();
cookie.setExpiryDate(DateUtils.toDate(expiryDate)); cookie.setExpiryDate(expiryDate);
} }
private void skipDelims(final CharSequence buf, final Tokenizer.Cursor cursor) { private void skipDelims(final CharSequence buf, final Tokenizer.Cursor cursor) {

View File

@ -26,7 +26,7 @@
*/ */
package org.apache.hc.client5.http.impl.cookie; 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.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -68,8 +68,8 @@ public void parse(final SetCookie cookie, final String value) throws MalformedCo
} catch (final NumberFormatException e) { } catch (final NumberFormatException e) {
return; return;
} }
final Date expiryDate = age >= 0 ? new Date(System.currentTimeMillis() + age * 1000L) : final Instant expiryDate = age >= 0 ? Instant.now().plusSeconds(age) :
new Date(Long.MIN_VALUE); Instant.EPOCH;
cookie.setExpiryDate(expiryDate); cookie.setExpiryDate(expiryDate);
} }
} }

View File

@ -27,10 +27,10 @@
package org.apache.hc.client5.http.impl.cookie; package org.apache.hc.client5.http.impl.cookie;
import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.BitSet; import java.util.BitSet;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -146,7 +146,7 @@ public final List<Cookie> parse(final Header header, final CookieOrigin origin)
final BasicClientCookie cookie = new BasicClientCookie(name, value); final BasicClientCookie cookie = new BasicClientCookie(name, value);
cookie.setPath(getDefaultPath(origin)); cookie.setPath(getDefaultPath(origin));
cookie.setDomain(getDefaultDomain(origin)); cookie.setDomain(getDefaultDomain(origin));
cookie.setCreationDate(new Date()); cookie.setCreationDate(Instant.now());
final Map<String, String> attribMap = new LinkedHashMap<>(); final Map<String, String> attribMap = new LinkedHashMap<>();
while (!cursor.atEnd()) { while (!cursor.atEnd()) {

View File

@ -28,7 +28,7 @@
package org.apache.hc.client5.http.impl.io; package org.apache.hc.client5.http.impl.io;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.time.Instant;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -259,7 +259,7 @@ private synchronized void closeConnection(final CloseMode closeMode) {
private void checkExpiry() { private void checkExpiry() {
if (this.conn != null && System.currentTimeMillis() >= this.expiry) { if (this.conn != null && System.currentTimeMillis() >= this.expiry) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("{} Connection expired @ {}", id, new Date(this.expiry)); LOG.debug("{} Connection expired @ {}", id, Instant.ofEpochMilli(this.expiry));
} }
closeConnection(CloseMode.GRACEFUL); closeConnection(CloseMode.GRACEFUL);
} }

View File

@ -28,8 +28,8 @@
package org.apache.hc.client5.http.protocol; package org.apache.hc.client5.http.protocol;
import java.io.IOException; import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import org.apache.hc.client5.http.RouteInfo; import org.apache.hc.client5.http.RouteInfo;
@ -150,7 +150,7 @@ public void process(final HttpRequest request, final EntityDetails entity, final
final List<Cookie> cookies = cookieStore.getCookies(); final List<Cookie> cookies = cookieStore.getCookies();
// Find cookies matching the given origin // Find cookies matching the given origin
final List<Cookie> matchedCookies = new ArrayList<>(); final List<Cookie> matchedCookies = new ArrayList<>();
final Date now = new Date(); final Instant now = Instant.now();
boolean expired = false; boolean expired = false;
for (final Cookie cookie : cookies) { for (final Cookie cookie : cookies) {
if (!cookie.isExpired(now)) { if (!cookie.isExpired(now)) {

View File

@ -149,7 +149,7 @@ private static String formatCookie(final Cookie cookie) {
buf.append(", path:"); buf.append(", path:");
buf.append(cookie.getPath()); buf.append(cookie.getPath());
buf.append(", expiry:"); buf.append(", expiry:");
buf.append(cookie.getExpiryDate()); buf.append(cookie.getExpiryInstant());
return buf.toString(); return buf.toString();
} }

View File

@ -110,6 +110,7 @@ void applyParameters(final SSLEngine sslEngine, final SSLParameters sslParameter
} }
@Override @Override
@SuppressWarnings("deprecated")
TlsDetails createTlsDetails(final SSLEngine sslEngine) { TlsDetails createTlsDetails(final SSLEngine sslEngine) {
return tlsDetailsFactory != null ? tlsDetailsFactory.create(sslEngine) : null; return tlsDetailsFactory != null ? tlsDetailsFactory.create(sslEngine) : null;
} }

View File

@ -27,8 +27,8 @@
package org.apache.hc.client5.http.cookie; package org.apache.hc.client5.http.cookie;
import java.time.Instant;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie; import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
@ -101,10 +101,10 @@ public void testEqualitySameLength() {
public void testUnequalityCreationDate() { public void testUnequalityCreationDate() {
final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value"); final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value");
cookie1.setPath("/blah"); cookie1.setPath("/blah");
cookie1.setCreationDate(new Date(System.currentTimeMillis() - 200000)); cookie1.setCreationDate(Instant.now().minusMillis(200000));
final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value"); final BasicClientCookie cookie2 = new BasicClientCookie("name1", "value");
cookie2.setPath("/blah"); cookie2.setPath("/blah");
cookie2.setCreationDate(new Date(System.currentTimeMillis())); cookie2.setCreationDate(Instant.now());
Assertions.assertTrue(comparator.compare(cookie1, cookie2) < 0); Assertions.assertTrue(comparator.compare(cookie1, cookie2) < 0);
Assertions.assertTrue(comparator.compare(cookie2, cookie1) > 0); Assertions.assertTrue(comparator.compare(cookie2, cookie1) > 0);
} }

View File

@ -267,7 +267,7 @@ public void testBasicMaxAgeParse() throws Exception {
final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final BasicClientCookie cookie = new BasicClientCookie("name", "value");
final CookieAttributeHandler h = new BasicMaxAgeHandler(); final CookieAttributeHandler h = new BasicMaxAgeHandler();
h.parse(cookie, "2000"); h.parse(cookie, "2000");
Assertions.assertNotNull(cookie.getExpiryDate()); Assertions.assertNotNull(cookie.getExpiryInstant());
} }
@Test @Test
@ -327,7 +327,7 @@ public void testBasicExpiresParse() throws Exception {
final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123); final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123);
h.parse(cookie, DateUtils.formatStandardDate(Instant.now())); h.parse(cookie, DateUtils.formatStandardDate(Instant.now()));
Assertions.assertNotNull(cookie.getExpiryDate()); Assertions.assertNotNull(cookie.getExpiryInstant());
} }
@Test @Test

View File

@ -31,7 +31,8 @@
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.util.Calendar; import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List; import java.util.List;
import org.apache.hc.client5.http.cookie.BasicCookieStore; import org.apache.hc.client5.http.cookie.BasicCookieStore;
@ -65,9 +66,8 @@ public void testExpiredCookie() throws Exception {
final BasicCookieStore store = new BasicCookieStore(); final BasicCookieStore store = new BasicCookieStore();
final BasicClientCookie cookie = new BasicClientCookie("name1", "value1"); final BasicClientCookie cookie = new BasicClientCookie("name1", "value1");
final Calendar c = Calendar.getInstance(); final Instant minus_10_days = Instant.now().minus(10, ChronoUnit.DAYS);
c.add(Calendar.DAY_OF_YEAR, -10); cookie.setExpiryDate(minus_10_days);
cookie.setExpiryDate(c.getTime());
store.addCookie(cookie); store.addCookie(cookie);
final List<Cookie> list = store.getCookies(); final List<Cookie> list = store.getCookies();
Assertions.assertNotNull(list); Assertions.assertNotNull(list);

View File

@ -43,7 +43,7 @@ public void testParseMaxAge() throws Exception {
final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final BasicClientCookie cookie = new BasicClientCookie("name", "value");
final CookieAttributeHandler h = new LaxMaxAgeHandler(); final CookieAttributeHandler h = new LaxMaxAgeHandler();
h.parse(cookie, "2000"); h.parse(cookie, "2000");
Assertions.assertNotNull(cookie.getExpiryDate()); Assertions.assertNotNull(cookie.getExpiryInstant());
} }
@Test @Test
@ -51,7 +51,7 @@ public void testParseMaxNegative() throws Exception {
final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final BasicClientCookie cookie = new BasicClientCookie("name", "value");
final CookieAttributeHandler h = new LaxMaxAgeHandler(); final CookieAttributeHandler h = new LaxMaxAgeHandler();
h.parse(cookie, "-2000"); h.parse(cookie, "-2000");
Assertions.assertNotNull(cookie.getExpiryDate()); Assertions.assertNotNull(cookie.getExpiryInstant());
} }
@Test @Test
@ -59,7 +59,7 @@ public void testParseMaxZero() throws Exception {
final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final BasicClientCookie cookie = new BasicClientCookie("name", "value");
final CookieAttributeHandler h = new LaxMaxAgeHandler(); final CookieAttributeHandler h = new LaxMaxAgeHandler();
h.parse(cookie, "0000"); h.parse(cookie, "0000");
Assertions.assertNotNull(cookie.getExpiryDate()); Assertions.assertNotNull(cookie.getExpiryInstant());
} }
@Test @Test
@ -67,7 +67,7 @@ public void testBasicMaxAgeParseEmpty() throws Exception {
final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final BasicClientCookie cookie = new BasicClientCookie("name", "value");
final CookieAttributeHandler h = new LaxMaxAgeHandler(); final CookieAttributeHandler h = new LaxMaxAgeHandler();
h.parse(cookie, " "); h.parse(cookie, " ");
Assertions.assertNull(cookie.getExpiryDate()); Assertions.assertNull(cookie.getExpiryInstant());
} }
@Test @Test
@ -75,7 +75,7 @@ public void testBasicMaxAgeParseInvalid() throws Exception {
final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final BasicClientCookie cookie = new BasicClientCookie("name", "value");
final CookieAttributeHandler h = new LaxMaxAgeHandler(); final CookieAttributeHandler h = new LaxMaxAgeHandler();
h.parse(cookie, "garbage"); h.parse(cookie, "garbage");
Assertions.assertNull(cookie.getExpiryDate()); Assertions.assertNull(cookie.getExpiryInstant());
} }
@Test @Test
@ -98,7 +98,25 @@ public void testParseExpiry() throws Exception {
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, "1:0:12 8-jan-2012"); 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.assertNotNull(expiryDate);
Assertions.assertEquals(2012, expiryDate.get(ChronoField.YEAR)); Assertions.assertEquals(2012, expiryDate.get(ChronoField.YEAR));
@ -115,7 +133,7 @@ public void testParseExpiryInvalidTime0() throws Exception {
final BasicClientCookie cookie = new BasicClientCookie("name", "value"); final BasicClientCookie cookie = new BasicClientCookie("name", "value");
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, null); h.parse(cookie, null);
Assertions.assertNull(cookie.getExpiryDate()); Assertions.assertNull(cookie.getExpiryInstant());
} }
@Test @Test
@ -156,7 +174,25 @@ public void testParseExpiryFunnyTime() throws Exception {
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, "1:59:00blah; 8-feb-2000"); 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.assertNotNull(expiryDate);
Assertions.assertEquals(2000, expiryDate.get(ChronoField.YEAR_OF_ERA)); Assertions.assertEquals(2000, expiryDate.get(ChronoField.YEAR_OF_ERA));
@ -198,7 +234,25 @@ public void testParseExpiryFunnyDayOfMonth() throws Exception {
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, "12:00:00 8blah;mar;1880"); 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.assertNotNull(expiryDate);
Assertions.assertEquals(1880, expiryDate.get(ChronoField.YEAR)); Assertions.assertEquals(1880, expiryDate.get(ChronoField.YEAR));
@ -224,7 +278,25 @@ public void testParseExpiryFunnyMonth() throws Exception {
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, "23:59:59; 1-ApriLLLLL-2008"); 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.assertNotNull(expiryDate);
Assertions.assertEquals(2008, expiryDate.get(ChronoField.YEAR)); Assertions.assertEquals(2008, expiryDate.get(ChronoField.YEAR));
@ -266,7 +338,25 @@ public void testParseExpiryFunnyYear() throws Exception {
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, "23:59:59; 1-Apr-2008blah"); 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.assertNotNull(expiryDate);
Assertions.assertEquals(2008, expiryDate.get(ChronoField.YEAR)); Assertions.assertEquals(2008, expiryDate.get(ChronoField.YEAR));
@ -284,7 +374,7 @@ public void testParseExpiryYearTwoDigit1() throws Exception {
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, "23:59:59; 1-Apr-70"); 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.assertNotNull(expiryDate);
Assertions.assertEquals(1970, expiryDate.get(ChronoField.YEAR)); Assertions.assertEquals(1970, expiryDate.get(ChronoField.YEAR));
@ -296,7 +386,7 @@ public void testParseExpiryYearTwoDigit2() throws Exception {
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, "23:59:59; 1-Apr-99"); 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.assertNotNull(expiryDate);
Assertions.assertEquals(1999, expiryDate.get(ChronoField.YEAR)); Assertions.assertEquals(1999, expiryDate.get(ChronoField.YEAR));
@ -308,7 +398,7 @@ public void testParseExpiryYearTwoDigit3() throws Exception {
final CookieAttributeHandler h = new LaxExpiresHandler(); final CookieAttributeHandler h = new LaxExpiresHandler();
h.parse(cookie, "23:59:59; 1-Apr-00"); 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.assertNotNull(expiryDate);
Assertions.assertEquals(2000, expiryDate.get(ChronoField.YEAR)); Assertions.assertEquals(2000, expiryDate.get(ChronoField.YEAR));

View File

@ -26,7 +26,7 @@
*/ */
package org.apache.hc.client5.http.protocol; 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.HttpRoute;
import org.apache.hc.client5.http.RouteInfo.LayerType; import org.apache.hc.client5.http.RouteInfo.LayerType;
@ -321,7 +321,7 @@ public void testExcludeExpiredCookies() throws Exception {
final BasicClientCookie cookie3 = new BasicClientCookie("name3", "value3"); final BasicClientCookie cookie3 = new BasicClientCookie("name3", "value3");
cookie3.setDomain("localhost.local"); cookie3.setDomain("localhost.local");
cookie3.setPath("/"); cookie3.setPath("/");
cookie3.setExpiryDate(new Date(System.currentTimeMillis() + 100)); cookie3.setExpiryDate(Instant.now().plusMillis(100));
this.cookieStore.addCookie(cookie3); this.cookieStore.addCookie(cookie3);
Assertions.assertEquals(3, this.cookieStore.getCookies().size()); Assertions.assertEquals(3, this.cookieStore.getCookies().size());
@ -346,7 +346,7 @@ public void testExcludeExpiredCookies() throws Exception {
Assertions.assertEquals(1, headers.length); Assertions.assertEquals(1, headers.length);
Assertions.assertEquals("name1=value1; name2=value2", headers[0].getValue()); 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 @Test