Replaced SimpleDateFormat and Calendar with Java 8 Time APIs; removed thread-local from DateUtils
This commit is contained in:
parent
ffc8cd7585
commit
dfc2086d24
|
@ -132,7 +132,7 @@ public class HttpCacheEntry implements MessageHeaders, Serializable {
|
|||
* @return the Date value of the header or null if the header is not present
|
||||
*/
|
||||
private Date parseDate() {
|
||||
return DateUtils.parseDate(this, HttpHeaders.DATE);
|
||||
return DateUtils.toDate(DateUtils.parseStandardDate(this, HttpHeaders.DATE));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,7 +51,6 @@ import org.apache.hc.client5.http.cache.ResourceIOException;
|
|||
import org.apache.hc.client5.http.impl.ExecSupport;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.schedule.SchedulingStrategy;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.concurrent.CancellableDependency;
|
||||
|
@ -574,7 +573,7 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
|
|||
|
||||
@Override
|
||||
public void completed(final HttpCacheEntry existingEntry) {
|
||||
if (DateUtils.isAfter(existingEntry, backendResponse, HttpHeaders.DATE)) {
|
||||
if (DateSupport.isAfter(existingEntry, backendResponse, HttpHeaders.DATE)) {
|
||||
LOG.debug("Backend already contains fresher cache entry");
|
||||
try {
|
||||
final SimpleHttpResponse cacheResponse = responseGenerator.generateResponse(request, existingEntry);
|
||||
|
|
|
@ -30,7 +30,6 @@ import java.net.URI;
|
|||
|
||||
import org.apache.hc.client5.http.cache.HeaderConstants;
|
||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.client5.http.utils.URIUtils;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
|
@ -99,7 +98,7 @@ class CacheInvalidatorBase {
|
|||
}
|
||||
|
||||
static boolean responseDateOlderThanEntryDate(final HttpResponse response, final HttpCacheEntry entry) {
|
||||
return DateUtils.isBefore(response, entry, HttpHeaders.DATE);
|
||||
return DateSupport.isBefore(response, entry, HttpHeaders.DATE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
|||
import org.apache.hc.client5.http.cache.Resource;
|
||||
import org.apache.hc.client5.http.cache.ResourceFactory;
|
||||
import org.apache.hc.client5.http.cache.ResourceIOException;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.HttpRequest;
|
||||
|
@ -132,7 +131,7 @@ class CacheUpdateHandler {
|
|||
}
|
||||
|
||||
private Header[] mergeHeaders(final HttpCacheEntry entry, final HttpResponse response) {
|
||||
if (DateUtils.isAfter(entry, response, HttpHeaders.DATE)) {
|
||||
if (DateSupport.isAfter(entry, response, HttpHeaders.DATE)) {
|
||||
return entry.getHeaders();
|
||||
}
|
||||
final HeaderGroup headerGroup = new HeaderGroup();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.impl.cache;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
@ -64,11 +65,11 @@ class CacheValidityPolicy {
|
|||
return TimeValue.ZERO_MILLISECONDS;
|
||||
}
|
||||
|
||||
final Date expiry = DateUtils.parseDate(entry, HeaderConstants.EXPIRES);
|
||||
final Instant expiry = DateUtils.parseStandardDate(entry, HeaderConstants.EXPIRES);
|
||||
if (expiry == null) {
|
||||
return TimeValue.ZERO_MILLISECONDS;
|
||||
}
|
||||
final long diff = expiry.getTime() - dateValue.getTime();
|
||||
final long diff = expiry.toEpochMilli() - dateValue.getTime();
|
||||
return TimeValue.ofSeconds(diff / 1000);
|
||||
}
|
||||
|
||||
|
@ -98,10 +99,10 @@ class CacheValidityPolicy {
|
|||
public TimeValue getHeuristicFreshnessLifetime(final HttpCacheEntry entry,
|
||||
final float coefficient, final TimeValue defaultLifetime) {
|
||||
final Date dateValue = entry.getDate();
|
||||
final Date lastModifiedValue = DateUtils.parseDate(entry, HeaderConstants.LAST_MODIFIED);
|
||||
final Instant lastModifiedValue = DateUtils.parseStandardDate(entry, HeaderConstants.LAST_MODIFIED);
|
||||
|
||||
if (dateValue != null && lastModifiedValue != null) {
|
||||
final long diff = dateValue.getTime() - lastModifiedValue.getTime();
|
||||
final long diff = dateValue.getTime() - lastModifiedValue.toEpochMilli();
|
||||
if (diff < 0) {
|
||||
return TimeValue.ZERO_MILLISECONDS;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.impl.cache;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||
|
@ -105,7 +106,7 @@ class CachedHttpResponseGenerator {
|
|||
// - Date, unless its omission is required by section 14.8.1
|
||||
Header dateHeader = entry.getFirstHeader(HttpHeaders.DATE);
|
||||
if (dateHeader == null) {
|
||||
dateHeader = new BasicHeader(HttpHeaders.DATE, DateUtils.formatDate(new Date()));
|
||||
dateHeader = new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(Instant.now()));
|
||||
}
|
||||
response.addHeader(dateHeader);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.impl.cache;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
@ -278,7 +279,8 @@ class CachedResponseSuitabilityChecker {
|
|||
final boolean hasLastModifiedValidator = hasSupportedLastModifiedValidator(request);
|
||||
|
||||
final boolean etagValidatorMatches = (hasEtagValidator) && etagValidatorMatches(request, entry);
|
||||
final boolean lastModifiedValidatorMatches = (hasLastModifiedValidator) && lastModifiedValidatorMatches(request, entry, now);
|
||||
final boolean lastModifiedValidatorMatches = (hasLastModifiedValidator) && lastModifiedValidatorMatches(request, entry,
|
||||
DateUtils.toInstant(now));
|
||||
|
||||
if ((hasEtagValidator && hasLastModifiedValidator)
|
||||
&& !(etagValidatorMatches && lastModifiedValidatorMatches)) {
|
||||
|
@ -332,16 +334,16 @@ class CachedResponseSuitabilityChecker {
|
|||
* @param now right NOW in time
|
||||
* @return boolean Does the last modified header match
|
||||
*/
|
||||
private boolean lastModifiedValidatorMatches(final HttpRequest request, final HttpCacheEntry entry, final Date now) {
|
||||
final Date lastModified = DateUtils.parseDate(entry, HeaderConstants.LAST_MODIFIED);
|
||||
private boolean lastModifiedValidatorMatches(final HttpRequest request, final HttpCacheEntry entry, final Instant now) {
|
||||
final Instant lastModified = DateUtils.parseStandardDate(entry, HeaderConstants.LAST_MODIFIED);
|
||||
if (lastModified == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (final Header h : request.getHeaders(HeaderConstants.IF_MODIFIED_SINCE)) {
|
||||
final Date ifModifiedSince = DateUtils.parseDate(h.getValue());
|
||||
final Instant ifModifiedSince = DateUtils.parseStandardDate(h.getValue());
|
||||
if (ifModifiedSince != null) {
|
||||
if (ifModifiedSince.after(now) || lastModified.after(ifModifiedSince)) {
|
||||
if (ifModifiedSince.isAfter(now) || lastModified.isAfter(ifModifiedSince)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -351,8 +353,8 @@ class CachedResponseSuitabilityChecker {
|
|||
|
||||
private boolean hasValidDateField(final HttpRequest request, final String headerName) {
|
||||
for(final Header h : request.getHeaders(headerName)) {
|
||||
final Date date = DateUtils.parseDate(h.getValue());
|
||||
return date != null;
|
||||
final Instant instant = DateUtils.parseStandardDate(h.getValue());
|
||||
return instant != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ import org.apache.hc.client5.http.classic.ExecChainHandler;
|
|||
import org.apache.hc.client5.http.impl.ExecSupport;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.schedule.SchedulingStrategy;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.ContentType;
|
||||
|
@ -413,7 +412,7 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
|
|||
final HttpCacheEntry cacheEntry;
|
||||
if (cacheConfig.isFreshnessCheckEnabled()) {
|
||||
final HttpCacheEntry existingEntry = responseCache.getCacheEntry(target, request);
|
||||
if (DateUtils.isAfter(existingEntry, backendResponse, HttpHeaders.DATE)) {
|
||||
if (DateSupport.isAfter(existingEntry, backendResponse, HttpHeaders.DATE)) {
|
||||
LOG.debug("Backend already contains fresher cache entry");
|
||||
cacheEntry = existingEntry;
|
||||
} else {
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.apache.hc.client5.http.cache.HeaderConstants;
|
|||
import org.apache.hc.client5.http.cache.HttpCacheContext;
|
||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||
import org.apache.hc.client5.http.cache.ResourceIOException;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.HeaderElement;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
|
@ -333,7 +332,7 @@ public class CachingExecBase {
|
|||
// Date header, so we can't tell if they are out of order
|
||||
// according to the origin clock; thus we can skip the
|
||||
// unconditional retry recommended in 13.2.6 of RFC 2616.
|
||||
return DateUtils.isBefore(backendResponse, cacheEntry, HttpHeaders.DATE);
|
||||
return DateSupport.isBefore(backendResponse, cacheEntry, HttpHeaders.DATE);
|
||||
}
|
||||
|
||||
boolean shouldSendNotModifiedResponse(final HttpRequest request, final HttpCacheEntry responseEntry) {
|
||||
|
|
116
httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DateSupport.java
vendored
Normal file
116
httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DateSupport.java
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.hc.client5.http.impl.cache;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.MessageHeaders;
|
||||
|
||||
/**
|
||||
* HTTP cache date support utilities.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
@Internal
|
||||
public final class DateSupport {
|
||||
|
||||
/**
|
||||
* Tests if the first message is after (newer) than second one
|
||||
* using the given message header for comparison.
|
||||
*
|
||||
* @param message1 the first message
|
||||
* @param message2 the second message
|
||||
* @param headerName header name
|
||||
*
|
||||
* @return {@code true} if both messages contain a header with the given name
|
||||
* and the value of the header from the first message is newer that of
|
||||
* the second message.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static boolean isAfter(
|
||||
final MessageHeaders message1,
|
||||
final MessageHeaders message2,
|
||||
final String headerName) {
|
||||
if (message1 != null && message2 != null) {
|
||||
final Header dateHeader1 = message1.getFirstHeader(headerName);
|
||||
if (dateHeader1 != null) {
|
||||
final Header dateHeader2 = message2.getFirstHeader(headerName);
|
||||
if (dateHeader2 != null) {
|
||||
final Instant date1 = DateUtils.parseStandardDate(dateHeader1.getValue());
|
||||
if (date1 != null) {
|
||||
final Instant date2 = DateUtils.parseStandardDate(dateHeader2.getValue());
|
||||
if (date2 != null) {
|
||||
return date1.isAfter(date2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the first message is before (older) than the second one
|
||||
* using the given message header for comparison.
|
||||
*
|
||||
* @param message1 the first message
|
||||
* @param message2 the second message
|
||||
* @param headerName header name
|
||||
*
|
||||
* @return {@code true} if both messages contain a header with the given name
|
||||
* and the value of the header from the first message is older that of
|
||||
* the second message.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public static boolean isBefore(
|
||||
final MessageHeaders message1,
|
||||
final MessageHeaders message2,
|
||||
final String headerName) {
|
||||
if (message1 != null && message2 != null) {
|
||||
final Header dateHeader1 = message1.getFirstHeader(headerName);
|
||||
if (dateHeader1 != null) {
|
||||
final Header dateHeader2 = message2.getFirstHeader(headerName);
|
||||
if (dateHeader2 != null) {
|
||||
final Instant date1 = DateUtils.parseStandardDate(dateHeader1.getValue());
|
||||
if (date1 != null) {
|
||||
final Instant date2 = DateUtils.parseStandardDate(dateHeader2.getValue());
|
||||
if (date2 != null) {
|
||||
return date1.isBefore(date2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -26,9 +26,9 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.impl.cache;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
@ -154,7 +154,7 @@ class ResponseCachingPolicy {
|
|||
return false;
|
||||
}
|
||||
|
||||
final Date date = DateUtils.parseDate(response, HttpHeaders.DATE);
|
||||
final Instant date = DateUtils.parseStandardDate(response, HttpHeaders.DATE);
|
||||
if (date == null) {
|
||||
LOG.debug("Invalid / missing Date header");
|
||||
return false;
|
||||
|
@ -292,12 +292,12 @@ class ResponseCachingPolicy {
|
|||
if (expiresHdr == null || dateHdr == null) {
|
||||
return false;
|
||||
}
|
||||
final Date expires = DateUtils.parseDate(expiresHdr.getValue());
|
||||
final Date date = DateUtils.parseDate(dateHdr.getValue());
|
||||
final Instant expires = DateUtils.parseStandardDate(expiresHdr.getValue());
|
||||
final Instant date = DateUtils.parseStandardDate(dateHdr.getValue());
|
||||
if (expires == null || date == null) {
|
||||
return false;
|
||||
}
|
||||
return expires.equals(date) || expires.before(date);
|
||||
return expires.equals(date) || expires.isBefore(date);
|
||||
}
|
||||
|
||||
private boolean from1_0Origin(final HttpResponse response) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
package org.apache.hc.client5.http.impl.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
@ -85,7 +86,7 @@ class ResponseProtocolCompliance {
|
|||
|
||||
private void warningsWithNonMatchingWarnDatesAreRemoved(
|
||||
final HttpResponse response) {
|
||||
final Date responseDate = DateUtils.parseDate(response, HttpHeaders.DATE);
|
||||
final Instant responseDate = DateUtils.parseStandardDate(response, HttpHeaders.DATE);
|
||||
if (responseDate == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -153,7 +154,7 @@ class ResponseProtocolCompliance {
|
|||
|
||||
private void ensure206ContainsDateHeader(final HttpResponse response) {
|
||||
if (response.getFirstHeader(HttpHeaders.DATE) == null) {
|
||||
response.addHeader(HttpHeaders.DATE, DateUtils.formatDate(new Date()));
|
||||
response.addHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(Instant.now()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -265,7 +265,7 @@ class WarningValue {
|
|||
parseError();
|
||||
}
|
||||
offs += m.end();
|
||||
warnDate = DateUtils.parseDate(src.substring(curr+1,offs-1));
|
||||
warnDate = DateUtils.toDate(DateUtils.parseStandardDate(src.substring(curr+1,offs-1)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -359,7 +359,7 @@ class WarningValue {
|
|||
public String toString() {
|
||||
if (warnDate != null) {
|
||||
return String.format("%d %s %s \"%s\"", warnCode,
|
||||
warnAgent, warnText, DateUtils.formatDate(warnDate));
|
||||
warnAgent, warnText, DateUtils.formatStandardDate(DateUtils.toInstant(warnDate)));
|
||||
} else {
|
||||
return String.format("%d %s %s", warnCode, warnAgent, warnText);
|
||||
}
|
||||
|
|
100
httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDateSupport.java
vendored
Normal file
100
httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDateSupport.java
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.hc.client5.http.impl.cache;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
import java.time.ZoneId;
|
||||
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
import org.apache.hc.core5.http.message.HeaderGroup;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DateSupport}.
|
||||
*/
|
||||
public class TestDateSupport {
|
||||
|
||||
private static Instant createInstant(final int year, final Month month, final int day) {
|
||||
return LocalDate.of(year, month, day).atStartOfDay(ZoneId.of("GMT")).toInstant();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBefore() throws Exception {
|
||||
final HeaderGroup message1 = new HeaderGroup();
|
||||
final HeaderGroup message2 = new HeaderGroup();
|
||||
MatcherAssert.assertThat(DateSupport.isBefore(null, null, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
MatcherAssert.assertThat(DateSupport.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "huh?"));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, "eh?"));
|
||||
MatcherAssert.assertThat(DateSupport.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "huh?"));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 26))));
|
||||
MatcherAssert.assertThat(DateSupport.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 25))));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 26))));
|
||||
MatcherAssert.assertThat(DateSupport.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(true));
|
||||
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 27))));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 26))));
|
||||
MatcherAssert.assertThat(DateSupport.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAfter() throws Exception {
|
||||
final HeaderGroup message1 = new HeaderGroup();
|
||||
final HeaderGroup message2 = new HeaderGroup();
|
||||
MatcherAssert.assertThat(DateSupport.isAfter(null, null, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
MatcherAssert.assertThat(DateSupport.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "huh?"));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, "eh?"));
|
||||
MatcherAssert.assertThat(DateSupport.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "huh?"));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 26))));
|
||||
MatcherAssert.assertThat(DateSupport.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 27))));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 26))));
|
||||
MatcherAssert.assertThat(DateSupport.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(true));
|
||||
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 25))));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, DateUtils.formatStandardDate(createInstant(2017, Month.DECEMBER, 26))));
|
||||
MatcherAssert.assertThat(DateSupport.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
}
|
||||
|
||||
}
|
|
@ -56,6 +56,10 @@ public class TestResponseCachingPolicy {
|
|||
private Date tenSecondsFromNow;
|
||||
private Date sixSecondsAgo;
|
||||
|
||||
static String formatDate(final Date date) {
|
||||
return DateUtils.formatStandardDate(DateUtils.toInstant(date));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
now = new Date();
|
||||
|
@ -65,7 +69,7 @@ public class TestResponseCachingPolicy {
|
|||
policy = new ResponseCachingPolicy(0, true, false, false);
|
||||
request = new BasicHttpRequest("GET","/");
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "");
|
||||
response.setHeader("Date", DateUtils.formatDate(new Date()));
|
||||
response.setHeader("Date", formatDate(new Date()));
|
||||
response.setHeader("Content-Length", "0");
|
||||
}
|
||||
|
||||
|
@ -205,7 +209,7 @@ public class TestResponseCachingPolicy {
|
|||
public void testNon206WithExplicitExpiresIsCacheable() {
|
||||
final int status = getRandomStatus();
|
||||
response.setCode(status);
|
||||
response.setHeader("Expires", DateUtils.formatDate(new Date()));
|
||||
response.setHeader("Expires", formatDate(new Date()));
|
||||
Assert.assertTrue(policy.isResponseCacheable("GET", response));
|
||||
}
|
||||
|
||||
|
@ -360,7 +364,7 @@ public class TestResponseCachingPolicy {
|
|||
Assert.assertTrue(policy.isResponseCacheable("GET", response));
|
||||
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "");
|
||||
response.setHeader("Date", DateUtils.formatDate(new Date()));
|
||||
response.setHeader("Date", formatDate(new Date()));
|
||||
response.addHeader("Cache-Control", "no-transform");
|
||||
response.setHeader("Content-Length", "0");
|
||||
|
||||
|
@ -375,7 +379,7 @@ public class TestResponseCachingPolicy {
|
|||
Assert.assertTrue(policy.isResponseCacheable("HEAD", response));
|
||||
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "");
|
||||
response.setHeader("Date", DateUtils.formatDate(new Date()));
|
||||
response.setHeader("Date", formatDate(new Date()));
|
||||
response.addHeader("Cache-Control", "no-transform");
|
||||
response.setHeader("Content-Length", "0");
|
||||
|
||||
|
@ -480,8 +484,8 @@ public class TestResponseCachingPolicy {
|
|||
|
||||
@Test
|
||||
public void testResponsesWithMultipleDateHeadersAreNotCacheable() {
|
||||
response.addHeader("Date", DateUtils.formatDate(now));
|
||||
response.addHeader("Date", DateUtils.formatDate(sixSecondsAgo));
|
||||
response.addHeader("Date", formatDate(now));
|
||||
response.addHeader("Date", formatDate(sixSecondsAgo));
|
||||
Assert.assertFalse(policy.isResponseCacheable("GET", response));
|
||||
}
|
||||
|
||||
|
@ -491,8 +495,8 @@ public class TestResponseCachingPolicy {
|
|||
|
||||
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
|
||||
response.setHeader("Cache-Control", "public");
|
||||
response.addHeader("Date", DateUtils.formatDate(now));
|
||||
response.addHeader("Date", DateUtils.formatDate(sixSecondsAgo));
|
||||
response.addHeader("Date", formatDate(now));
|
||||
response.addHeader("Date", formatDate(sixSecondsAgo));
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -514,8 +518,8 @@ public class TestResponseCachingPolicy {
|
|||
|
||||
@Test
|
||||
public void testResponsesWithMultipleExpiresHeadersAreNotCacheable() {
|
||||
response.addHeader("Expires", DateUtils.formatDate(now));
|
||||
response.addHeader("Expires", DateUtils.formatDate(sixSecondsAgo));
|
||||
response.addHeader("Expires", formatDate(now));
|
||||
response.addHeader("Expires", formatDate(sixSecondsAgo));
|
||||
Assert.assertFalse(policy.isResponseCacheable("GET", response));
|
||||
}
|
||||
|
||||
|
@ -525,8 +529,8 @@ public class TestResponseCachingPolicy {
|
|||
|
||||
request.setHeader("Authorization", StandardAuthScheme.BASIC + " QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
|
||||
response.setHeader("Cache-Control", "public");
|
||||
response.addHeader("Expires", DateUtils.formatDate(now));
|
||||
response.addHeader("Expires", DateUtils.formatDate(sixSecondsAgo));
|
||||
response.addHeader("Expires", formatDate(now));
|
||||
response.addHeader("Expires", formatDate(sixSecondsAgo));
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -587,8 +591,8 @@ public class TestResponseCachingPolicy {
|
|||
@Test
|
||||
public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheable() {
|
||||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -596,8 +600,8 @@ public class TestResponseCachingPolicy {
|
|||
public void testResponsesToHEADWithQueryParamsAndExplicitCachingAreCacheable() {
|
||||
policy = new ResponseCachingPolicy(0, true, false, false);
|
||||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -605,8 +609,8 @@ public class TestResponseCachingPolicy {
|
|||
public void testResponsesToGETWithQueryParamsAndExplicitCachingAreCacheableEvenWhen1_0QueryCachingDisabled() {
|
||||
policy = new ResponseCachingPolicy(0, true, true, false);
|
||||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -614,8 +618,8 @@ public class TestResponseCachingPolicy {
|
|||
public void testResponsesToHEADWithQueryParamsAndExplicitCachingAreCacheableEvenWhen1_0QueryCachingDisabled() {
|
||||
policy = new ResponseCachingPolicy(0, true, true, false);
|
||||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -658,8 +662,8 @@ public class TestResponseCachingPolicy {
|
|||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
|
||||
response.setVersion(HttpVersion.HTTP_1_0);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -669,8 +673,8 @@ public class TestResponseCachingPolicy {
|
|||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
|
||||
response.setVersion(HttpVersion.HTTP_1_0);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -680,8 +684,8 @@ public class TestResponseCachingPolicy {
|
|||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
|
||||
response.setVersion(HttpVersion.HTTP_1_0);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -691,8 +695,8 @@ public class TestResponseCachingPolicy {
|
|||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
|
||||
response.setVersion(HttpVersion.HTTP_1_0);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
|
@ -713,8 +717,8 @@ public class TestResponseCachingPolicy {
|
|||
@Test
|
||||
public void getsWithQueryParametersFrom1_0OriginsViaProxiesAreCacheableWithExpires() {
|
||||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "1.0 someproxy");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -723,8 +727,8 @@ public class TestResponseCachingPolicy {
|
|||
public void headsWithQueryParametersFrom1_0OriginsViaProxiesAreCacheableWithExpires() {
|
||||
policy = new ResponseCachingPolicy(0, true, false, false);
|
||||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "1.0 someproxy");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -733,8 +737,8 @@ public class TestResponseCachingPolicy {
|
|||
public void getsWithQueryParametersFrom1_0OriginsViaProxiesCanNotBeCacheableEvenWithExpires() {
|
||||
policy = new ResponseCachingPolicy(0, true, true, true);
|
||||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "1.0 someproxy");
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -743,8 +747,8 @@ public class TestResponseCachingPolicy {
|
|||
public void headsWithQueryParametersFrom1_0OriginsViaProxiesCanNotBeCacheableEvenWithExpires() {
|
||||
policy = new ResponseCachingPolicy(0, true, true, true);
|
||||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "1.0 someproxy");
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -752,8 +756,8 @@ public class TestResponseCachingPolicy {
|
|||
@Test
|
||||
public void getsWithQueryParametersFrom1_0OriginsViaExplicitProxiesAreCacheableWithExpires() {
|
||||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "HTTP/1.0 someproxy");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -762,8 +766,8 @@ public class TestResponseCachingPolicy {
|
|||
public void headsWithQueryParametersFrom1_0OriginsViaExplicitProxiesAreCacheableWithExpires() {
|
||||
policy = new ResponseCachingPolicy(0, true, false, false);
|
||||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "HTTP/1.0 someproxy");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -772,8 +776,8 @@ public class TestResponseCachingPolicy {
|
|||
public void getsWithQueryParametersFrom1_0OriginsViaExplicitProxiesCanNotBeCacheableEvenWithExpires() {
|
||||
policy = new ResponseCachingPolicy(0, true, true, true);
|
||||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "HTTP/1.0 someproxy");
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -782,8 +786,8 @@ public class TestResponseCachingPolicy {
|
|||
public void headsWithQueryParametersFrom1_0OriginsViaExplicitProxiesCanNotBeCacheableEvenWithExpires() {
|
||||
policy = new ResponseCachingPolicy(0, true, true, true);
|
||||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "HTTP/1.0 someproxy");
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -793,8 +797,8 @@ public class TestResponseCachingPolicy {
|
|||
request = new BasicHttpRequest("GET", "/foo?s=bar");
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
|
||||
response.setVersion(HttpVersion.HTTP_1_0);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "1.1 someproxy");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -805,24 +809,24 @@ public class TestResponseCachingPolicy {
|
|||
request = new BasicHttpRequest("HEAD", "/foo?s=bar");
|
||||
response = new BasicHttpResponse(HttpStatus.SC_OK, "OK");
|
||||
response.setVersion(HttpVersion.HTTP_1_0);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(tenSecondsFromNow));
|
||||
response.setHeader("Via", "1.1 someproxy");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notCacheableIfExpiresEqualsDateAndNoCacheControl() {
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(now));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(now));
|
||||
response.removeHeaders("Cache-Control");
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notCacheableIfExpiresPrecedesDateAndNoCacheControl() {
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Expires", DateUtils.formatDate(sixSecondsAgo));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Expires", formatDate(sixSecondsAgo));
|
||||
response.removeHeaders("Cache-Control");
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -830,7 +834,7 @@ public class TestResponseCachingPolicy {
|
|||
@Test
|
||||
public void test302WithExplicitCachingHeaders() {
|
||||
response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Cache-Control","max-age=300");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -839,7 +843,7 @@ public class TestResponseCachingPolicy {
|
|||
public void test303WithExplicitCachingHeadersUnderDefaultBehavior() {
|
||||
// RFC 2616 says: 303 should not be cached
|
||||
response.setCode(HttpStatus.SC_SEE_OTHER);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Cache-Control","max-age=300");
|
||||
Assert.assertFalse(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -850,7 +854,7 @@ public class TestResponseCachingPolicy {
|
|||
// response headers
|
||||
policy = new ResponseCachingPolicy(0, true, false, true);
|
||||
response.setCode(HttpStatus.SC_SEE_OTHER);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Cache-Control","max-age=300");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -858,7 +862,7 @@ public class TestResponseCachingPolicy {
|
|||
@Test
|
||||
public void test307WithExplicitCachingHeaders() {
|
||||
response.setCode(HttpStatus.SC_TEMPORARY_REDIRECT);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Cache-Control","max-age=300");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
@ -866,7 +870,7 @@ public class TestResponseCachingPolicy {
|
|||
@Test
|
||||
public void otherStatusCodesAreCacheableWithExplicitCachingHeaders() {
|
||||
response.setCode(HttpStatus.SC_NOT_FOUND);
|
||||
response.setHeader("Date", DateUtils.formatDate(now));
|
||||
response.setHeader("Date", formatDate(now));
|
||||
response.setHeader("Cache-Control","max-age=300");
|
||||
Assert.assertTrue(policy.isResponseCacheable(request, response));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.impl.cache;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
|
@ -203,8 +203,8 @@ public class TestWarningValue {
|
|||
Assert.assertEquals(110, impl.getWarnCode());
|
||||
Assert.assertEquals("fred", impl.getWarnAgent());
|
||||
Assert.assertEquals("\"stale\"", impl.getWarnText());
|
||||
final Date target = DateUtils.parseDate("Sun Nov 6 08:49:37 1994");
|
||||
Assert.assertEquals(target, impl.getWarnDate());
|
||||
final Instant target = DateUtils.parseStandardDate("Sun Nov 6 08:49:37 1994");
|
||||
Assert.assertEquals(target, DateUtils.toInstant(impl.getWarnDate()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -213,8 +213,8 @@ public class TestWarningValue {
|
|||
Assert.assertEquals(110, impl.getWarnCode());
|
||||
Assert.assertEquals("fred", impl.getWarnAgent());
|
||||
Assert.assertEquals("\"stale\"", impl.getWarnText());
|
||||
final Date target = DateUtils.parseDate("Sunday, 06-Nov-94 08:49:37 GMT");
|
||||
Assert.assertEquals(target, impl.getWarnDate());
|
||||
final Instant target = DateUtils.parseStandardDate("Sunday, 06-Nov-94 08:49:37 GMT");
|
||||
Assert.assertEquals(target, DateUtils.toInstant(impl.getWarnDate()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -223,8 +223,8 @@ public class TestWarningValue {
|
|||
Assert.assertEquals(110, impl.getWarnCode());
|
||||
Assert.assertEquals("fred", impl.getWarnAgent());
|
||||
Assert.assertEquals("\"stale\"", impl.getWarnText());
|
||||
final Date target = DateUtils.parseDate("Sun, 06 Nov 1994 08:49:37 GMT");
|
||||
Assert.assertEquals(target, impl.getWarnDate());
|
||||
final Instant target = DateUtils.parseStandardDate("Sun, 06 Nov 1994 08:49:37 GMT");
|
||||
Assert.assertEquals(target, DateUtils.toInstant(impl.getWarnDate()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import java.net.URI;
|
|||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
@ -46,6 +45,7 @@ import org.apache.hc.client5.http.config.Configurable;
|
|||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.ContentType;
|
||||
|
@ -70,8 +70,20 @@ import org.apache.hc.core5.util.Timeout;
|
|||
*/
|
||||
public class Request {
|
||||
|
||||
/**
|
||||
* @deprecated This attribute is no longer supported as a part of the public API.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";
|
||||
/**
|
||||
* @deprecated This attribute is no longer supported as a part of the public API.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Locale DATE_LOCALE = Locale.US;
|
||||
/**
|
||||
* @deprecated This attribute is no longer supported as a part of the public API.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final TimeZone TIME_ZONE = TimeZone.getTimeZone("GMT");
|
||||
|
||||
private final ClassicHttpRequest request;
|
||||
|
@ -80,8 +92,6 @@ public class Request {
|
|||
private Timeout responseTimeout;
|
||||
private HttpHost proxy;
|
||||
|
||||
private SimpleDateFormat dateFormatter;
|
||||
|
||||
public static Request create(final Method method, final URI uri) {
|
||||
return new Request(new HttpUriRequestBase(method.name(), uri));
|
||||
}
|
||||
|
@ -246,30 +256,22 @@ public class Request {
|
|||
return this;
|
||||
}
|
||||
|
||||
private SimpleDateFormat getDateFormat() {
|
||||
if (this.dateFormatter == null) {
|
||||
this.dateFormatter = new SimpleDateFormat(DATE_FORMAT, DATE_LOCALE);
|
||||
this.dateFormatter.setTimeZone(TIME_ZONE);
|
||||
}
|
||||
return this.dateFormatter;
|
||||
}
|
||||
|
||||
ClassicHttpRequest getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public Request setDate(final Date date) {
|
||||
this.request.setHeader(HttpHeader.DATE, getDateFormat().format(date));
|
||||
this.request.setHeader(HttpHeader.DATE, DateUtils.formatStandardDate(DateUtils.toInstant(date)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Request setIfModifiedSince(final Date date) {
|
||||
this.request.setHeader(HttpHeader.IF_MODIFIED_SINCE, getDateFormat().format(date));
|
||||
this.request.setHeader(HttpHeader.IF_MODIFIED_SINCE, DateUtils.formatStandardDate(DateUtils.toInstant(date)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Request setIfUnmodifiedSince(final Date date) {
|
||||
this.request.setHeader(HttpHeader.IF_UNMODIFIED_SINCE, getDateFormat().format(date));
|
||||
this.request.setHeader(HttpHeader.IF_UNMODIFIED_SINCE, DateUtils.formatStandardDate(DateUtils.toInstant(date)));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,9 @@ import java.io.InterruptedIOException;
|
|||
import java.net.ConnectException;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -214,10 +214,10 @@ public class DefaultHttpRequestRetryStrategy implements HttpRequestRetryStrategy
|
|||
try {
|
||||
retryAfter = TimeValue.ofSeconds(Long.parseLong(value));
|
||||
} catch (final NumberFormatException ignore) {
|
||||
final Date retryAfterDate = DateUtils.parseDate(value);
|
||||
final Instant retryAfterDate = DateUtils.parseStandardDate(value);
|
||||
if (retryAfterDate != null) {
|
||||
retryAfter =
|
||||
TimeValue.ofMilliseconds(retryAfterDate.getTime() - System.currentTimeMillis());
|
||||
TimeValue.ofMilliseconds(retryAfterDate.toEpochMilli() - System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.impl.cookie;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
|
||||
import org.apache.hc.client5.http.cookie.CommonCookieAttributeHandler;
|
||||
import org.apache.hc.client5.http.cookie.Cookie;
|
||||
|
@ -46,11 +48,30 @@ import org.apache.hc.core5.util.Args;
|
|||
public class BasicExpiresHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
|
||||
|
||||
/** Valid date patterns */
|
||||
private final String[] datePatterns;
|
||||
private final DateTimeFormatter[] datePatterns;
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
public BasicExpiresHandler(final DateTimeFormatter... datePatterns) {
|
||||
this.datePatterns = datePatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #BasicExpiresHandler(DateTimeFormatter...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public BasicExpiresHandler(final String[] datePatterns) {
|
||||
Args.notNull(datePatterns, "Array of date patterns");
|
||||
this.datePatterns = datePatterns.clone();
|
||||
this.datePatterns = new DateTimeFormatter[datePatterns.length];
|
||||
for (int i = 0; i < datePatterns.length; i++) {
|
||||
this.datePatterns[i] = new DateTimeFormatterBuilder()
|
||||
.parseLenient()
|
||||
.parseCaseInsensitive()
|
||||
.appendPattern(datePatterns[i])
|
||||
.toFormatter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -60,12 +81,12 @@ public class BasicExpiresHandler extends AbstractCookieAttributeHandler implemen
|
|||
if (value == null) {
|
||||
throw new MalformedCookieException("Missing value for 'expires' attribute");
|
||||
}
|
||||
final Date expiry = DateUtils.parseDate(value, this.datePatterns);
|
||||
final Instant expiry = DateUtils.parseDate(value, this.datePatterns);
|
||||
if (expiry == null) {
|
||||
throw new MalformedCookieException("Invalid 'expires' attribute: "
|
||||
+ value);
|
||||
}
|
||||
cookie.setExpiryDate(expiry);
|
||||
cookie.setExpiryDate(DateUtils.toDate(expiry));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
*/
|
||||
package org.apache.hc.client5.http.impl.cookie;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.Month;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.BitSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -39,6 +41,7 @@ import org.apache.hc.client5.http.cookie.CommonCookieAttributeHandler;
|
|||
import org.apache.hc.client5.http.cookie.Cookie;
|
||||
import org.apache.hc.client5.http.cookie.MalformedCookieException;
|
||||
import org.apache.hc.client5.http.cookie.SetCookie;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
|
@ -54,8 +57,6 @@ import org.apache.hc.core5.util.Tokenizer;
|
|||
@Contract(threading = ThreadingBehavior.STATELESS)
|
||||
public class LaxExpiresHandler extends AbstractCookieAttributeHandler implements CommonCookieAttributeHandler {
|
||||
|
||||
static final TimeZone UTC = TimeZone.getTimeZone("UTC");
|
||||
|
||||
private static final BitSet DELIMS;
|
||||
static {
|
||||
final BitSet bitSet = new BitSet();
|
||||
|
@ -74,21 +75,21 @@ public class LaxExpiresHandler extends AbstractCookieAttributeHandler implements
|
|||
}
|
||||
DELIMS = bitSet;
|
||||
}
|
||||
private static final Map<String, Integer> MONTHS;
|
||||
private static final Map<String, Month> MONTHS;
|
||||
static {
|
||||
final ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(12);
|
||||
map.put("jan", Calendar.JANUARY);
|
||||
map.put("feb", Calendar.FEBRUARY);
|
||||
map.put("mar", Calendar.MARCH);
|
||||
map.put("apr", Calendar.APRIL);
|
||||
map.put("may", Calendar.MAY);
|
||||
map.put("jun", Calendar.JUNE);
|
||||
map.put("jul", Calendar.JULY);
|
||||
map.put("aug", Calendar.AUGUST);
|
||||
map.put("sep", Calendar.SEPTEMBER);
|
||||
map.put("oct", Calendar.OCTOBER);
|
||||
map.put("nov", Calendar.NOVEMBER);
|
||||
map.put("dec", Calendar.DECEMBER);
|
||||
final ConcurrentHashMap<String, Month> map = new ConcurrentHashMap<>(12);
|
||||
map.put("jan", Month.JANUARY);
|
||||
map.put("feb", Month.FEBRUARY);
|
||||
map.put("mar", Month.MARCH);
|
||||
map.put("apr", Month.APRIL);
|
||||
map.put("may", Month.MAY);
|
||||
map.put("jun", Month.JUNE);
|
||||
map.put("jul", Month.JULY);
|
||||
map.put("aug", Month.AUGUST);
|
||||
map.put("sep", Month.SEPTEMBER);
|
||||
map.put("oct", Month.OCTOBER);
|
||||
map.put("nov", Month.NOVEMBER);
|
||||
map.put("dec", Month.DECEMBER);
|
||||
MONTHS = map;
|
||||
}
|
||||
|
||||
|
@ -114,7 +115,8 @@ public class LaxExpiresHandler extends AbstractCookieAttributeHandler implements
|
|||
final Tokenizer.Cursor cursor = new Tokenizer.Cursor(0, value.length());
|
||||
final StringBuilder content = new StringBuilder();
|
||||
|
||||
int second = 0, minute = 0, hour = 0, day = 0, month = 0, year = 0;
|
||||
int second = 0, minute = 0, hour = 0, day = 0, year = 0;
|
||||
Month month = Month.JANUARY;
|
||||
boolean foundTime = false, foundDayOfMonth = false, foundMonth = false, foundYear = false;
|
||||
try {
|
||||
while (!cursor.atEnd()) {
|
||||
|
@ -147,7 +149,7 @@ public class LaxExpiresHandler extends AbstractCookieAttributeHandler implements
|
|||
final Matcher matcher = MONTH_PATTERN.matcher(content);
|
||||
if (matcher.matches()) {
|
||||
foundMonth = true;
|
||||
month = MONTHS.get(matcher.group(1).toLowerCase(Locale.ROOT)).intValue();
|
||||
month = MONTHS.get(matcher.group(1).toLowerCase(Locale.ROOT));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -176,16 +178,9 @@ public class LaxExpiresHandler extends AbstractCookieAttributeHandler implements
|
|||
throw new MalformedCookieException("Invalid 'expires' attribute: " + value);
|
||||
}
|
||||
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(UTC);
|
||||
c.setTimeInMillis(0L);
|
||||
c.set(Calendar.SECOND, second);
|
||||
c.set(Calendar.MINUTE, minute);
|
||||
c.set(Calendar.HOUR_OF_DAY, hour);
|
||||
c.set(Calendar.DAY_OF_MONTH, day);
|
||||
c.set(Calendar.MONTH, month);
|
||||
c.set(Calendar.YEAR, year);
|
||||
cookie.setExpiryDate(c.getTime());
|
||||
final Instant expiryDate = ZonedDateTime.of(year, month.getValue(), day, hour, minute, second, 0,
|
||||
ZoneId.of("UTC")).toInstant();
|
||||
cookie.setExpiryDate(DateUtils.toDate(expiryDate));
|
||||
}
|
||||
|
||||
private void skipDelims(final CharSequence buf, final Tokenizer.Cursor cursor) {
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.hc.client5.http.cookie.CookieSpec;
|
|||
import org.apache.hc.client5.http.cookie.CookieSpecFactory;
|
||||
import org.apache.hc.client5.http.cookie.MalformedCookieException;
|
||||
import org.apache.hc.client5.http.psl.PublicSuffixMatcher;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
|
@ -88,7 +89,7 @@ public class RFC6265CookieSpecFactory implements CookieSpecFactory {
|
|||
new BasicMaxAgeHandler(),
|
||||
new BasicSecureHandler(),
|
||||
new BasicHttpOnlyHandler(),
|
||||
new BasicExpiresHandler(RFC6265StrictSpec.DATE_PATTERNS));
|
||||
new BasicExpiresHandler(DateUtils.STANDARD_PATTERNS));
|
||||
break;
|
||||
case IE_MEDIUM_SECURITY:
|
||||
this.cookieSpec = new RFC6265LaxSpec(
|
||||
|
@ -105,7 +106,7 @@ public class RFC6265CookieSpecFactory implements CookieSpecFactory {
|
|||
new BasicMaxAgeHandler(),
|
||||
new BasicSecureHandler(),
|
||||
new BasicHttpOnlyHandler(),
|
||||
new BasicExpiresHandler(RFC6265StrictSpec.DATE_PATTERNS));
|
||||
new BasicExpiresHandler(DateUtils.STANDARD_PATTERNS));
|
||||
break;
|
||||
default:
|
||||
this.cookieSpec = new RFC6265LaxSpec(
|
||||
|
|
|
@ -42,19 +42,13 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
|
|||
@Contract(threading = ThreadingBehavior.SAFE)
|
||||
public class RFC6265StrictSpec extends RFC6265CookieSpecBase {
|
||||
|
||||
final static String[] DATE_PATTERNS = {
|
||||
DateUtils.PATTERN_RFC1123,
|
||||
DateUtils.PATTERN_RFC1036,
|
||||
DateUtils.PATTERN_ASCTIME
|
||||
};
|
||||
|
||||
public RFC6265StrictSpec() {
|
||||
super(new BasicPathHandler(),
|
||||
new BasicDomainHandler(),
|
||||
new BasicMaxAgeHandler(),
|
||||
new BasicSecureHandler(),
|
||||
new BasicHttpOnlyHandler(),
|
||||
new BasicExpiresHandler(DATE_PATTERNS));
|
||||
new BasicExpiresHandler(DateUtils.STANDARD_PATTERNS));
|
||||
}
|
||||
|
||||
RFC6265StrictSpec(final CommonCookieAttributeHandler... handlers) {
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
|
||||
package org.apache.hc.client5.http.utils;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.hc.core5.http.Header;
|
||||
|
@ -55,35 +55,192 @@ public final class DateUtils {
|
|||
*/
|
||||
public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
|
||||
|
||||
/**
|
||||
* Date formatter used to parse HTTP date headers in RFC 1123 format.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static final DateTimeFormatter FORMATTER_RFC1123 = new DateTimeFormatterBuilder()
|
||||
.parseLenient()
|
||||
.parseCaseInsensitive()
|
||||
.appendPattern(PATTERN_RFC1123)
|
||||
.toFormatter();
|
||||
|
||||
/**
|
||||
* Date format pattern used to parse HTTP date headers in RFC 1036 format.
|
||||
*/
|
||||
public static final String PATTERN_RFC1036 = "EEE, dd-MMM-yy HH:mm:ss zzz";
|
||||
|
||||
/**
|
||||
* Date formatter used to parse HTTP date headers in RFC 1036 format.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static final DateTimeFormatter FORMATTER_RFC1036 = new DateTimeFormatterBuilder()
|
||||
.parseLenient()
|
||||
.parseCaseInsensitive()
|
||||
.appendPattern(PATTERN_RFC1036)
|
||||
.toFormatter();
|
||||
|
||||
/**
|
||||
* Date format pattern used to parse HTTP date headers in ANSI C
|
||||
* {@code asctime()} format.
|
||||
*/
|
||||
public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
|
||||
|
||||
private static final String[] DEFAULT_PATTERNS = new String[] {
|
||||
PATTERN_RFC1123,
|
||||
PATTERN_RFC1036,
|
||||
PATTERN_ASCTIME
|
||||
/**
|
||||
* Date formatter used to parse HTTP date headers in in ANSI C {@code asctime()} format.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static final DateTimeFormatter FORMATTER_ASCTIME = new DateTimeFormatterBuilder()
|
||||
.parseLenient()
|
||||
.parseCaseInsensitive()
|
||||
.appendPattern(PATTERN_ASCTIME)
|
||||
.toFormatter();
|
||||
|
||||
/**
|
||||
* Standard date formatters: {@link #FORMATTER_RFC1123}, {@link #FORMATTER_RFC1036}, {@link #FORMATTER_ASCTIME}.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static final DateTimeFormatter[] STANDARD_PATTERNS = new DateTimeFormatter[] {
|
||||
FORMATTER_RFC1123,
|
||||
FORMATTER_RFC1036,
|
||||
FORMATTER_ASCTIME
|
||||
};
|
||||
|
||||
private static final Date DEFAULT_TWO_DIGIT_YEAR_START;
|
||||
static final ZoneId GMT_ID = ZoneId.of("GMT");
|
||||
|
||||
public static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
static {
|
||||
final Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeZone(GMT);
|
||||
calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime();
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
public static Date toDate(final Instant instant) {
|
||||
return instant != null ? new Date(instant.toEpochMilli()) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
public static Instant toInstant(final Date date) {
|
||||
return date != null ? Instant.ofEpochMilli(date.getTime()) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
public static LocalDateTime toUTC(final Instant instant) {
|
||||
return instant != null ? instant.atZone(ZoneOffset.UTC).toLocalDateTime() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
public static LocalDateTime toUTC(final Date date) {
|
||||
return toUTC(toInstant(date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the date value using the given date/time formats.
|
||||
*
|
||||
* @param dateValue the instant value to parse
|
||||
* @param dateFormatters the date/time formats to use
|
||||
*
|
||||
* @return the parsed instant or null if input could not be parsed
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static Instant parseDate(final String dateValue, final DateTimeFormatter... dateFormatters) {
|
||||
Args.notNull(dateValue, "Date value");
|
||||
String v = dateValue;
|
||||
// trim single quotes around date if present
|
||||
// see issue #5279
|
||||
if (v.length() > 1 && v.startsWith("'") && v.endsWith("'")) {
|
||||
v = v.substring (1, v.length() - 1);
|
||||
}
|
||||
|
||||
for (final DateTimeFormatter dateFormatter : dateFormatters) {
|
||||
try {
|
||||
return Instant.from(dateFormatter.parse(v));
|
||||
} catch (final DateTimeParseException ignore) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the instant value using the standard date/time formats ({@link #PATTERN_RFC1123},
|
||||
* {@link #PATTERN_RFC1036}, {@link #PATTERN_ASCTIME}).
|
||||
*
|
||||
* @param dateValue the instant value to parse
|
||||
* @param dateFormatters the date/time formats to use
|
||||
*
|
||||
* @return the parsed instant or null if input could not be parsed
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static Instant parseStandardDate(final String dateValue) {
|
||||
return parseDate(dateValue, STANDARD_PATTERNS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an instant value from a header with the given name.
|
||||
*
|
||||
* @param headers message headers
|
||||
* @param headerName header name
|
||||
*
|
||||
* @return the parsed instant or null if input could not be parsed
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static Instant parseStandardDate(final MessageHeaders headers, final String headerName) {
|
||||
if (headers == null) {
|
||||
return null;
|
||||
}
|
||||
final Header header = headers.getFirstHeader(headerName);
|
||||
if (header == null) {
|
||||
return null;
|
||||
}
|
||||
return parseStandardDate(header.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given instant according to the RFC 1123 pattern.
|
||||
*
|
||||
* @param instant Instant to format.
|
||||
* @return An RFC 1123 formatted instant string.
|
||||
*
|
||||
* @see #PATTERN_RFC1123
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static String formatStandardDate(final Instant instant) {
|
||||
return formatDate(instant, FORMATTER_RFC1123);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given date according to the specified pattern.
|
||||
*
|
||||
* @param instant Instant to format.
|
||||
* @param dateTimeFormatter The pattern to use for formatting the instant.
|
||||
* @return A formatted instant string.
|
||||
*
|
||||
* @throws IllegalArgumentException If the given date pattern is invalid.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public static String formatDate(final Instant instant, final DateTimeFormatter dateTimeFormatter) {
|
||||
Args.notNull(instant, "Instant");
|
||||
Args.notNull(dateTimeFormatter, "DateTimeFormatter");
|
||||
return dateTimeFormatter.format(instant.atZone(GMT_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This attribute is no longer supported as a part of the public API.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
/**
|
||||
* Parses a date value. The formats used for parsing the date value are retrieved from
|
||||
* the default http params.
|
||||
|
@ -91,7 +248,10 @@ public final class DateUtils {
|
|||
* @param dateValue the date value to parse
|
||||
*
|
||||
* @return the parsed date or null if input could not be parsed
|
||||
*
|
||||
* @deprecated Use {@link #parseStandardDate(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Date parseDate(final String dateValue) {
|
||||
return parseDate(dateValue, null, null);
|
||||
}
|
||||
|
@ -105,16 +265,12 @@ public final class DateUtils {
|
|||
* @return the parsed date or null if input could not be parsed
|
||||
*
|
||||
* @since 5.0
|
||||
*
|
||||
* @deprecated Use {@link #parseStandardDate(MessageHeaders, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Date parseDate(final MessageHeaders headers, final String headerName) {
|
||||
if (headers == null) {
|
||||
return null;
|
||||
}
|
||||
final Header header = headers.getFirstHeader(headerName);
|
||||
if (header == null) {
|
||||
return null;
|
||||
}
|
||||
return parseDate(header.getValue(), null, null);
|
||||
return toDate(parseStandardDate(headers, headerName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,7 +286,10 @@ public final class DateUtils {
|
|||
* the second message.
|
||||
*
|
||||
* @since 5.0
|
||||
*
|
||||
* @deprecated This method is no longer supported as a part of the public API.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isAfter(
|
||||
final MessageHeaders message1,
|
||||
final MessageHeaders message2,
|
||||
|
@ -166,7 +325,10 @@ public final class DateUtils {
|
|||
* the second message.
|
||||
*
|
||||
* @since 5.0
|
||||
*
|
||||
* @deprecated This method is no longer supported as a part of the public API.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isBefore(
|
||||
final MessageHeaders message1,
|
||||
final MessageHeaders message2,
|
||||
|
@ -190,53 +352,53 @@ public final class DateUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Parses the date value using the given date formats.
|
||||
* Parses the date value using the given date/time formats.
|
||||
*
|
||||
* @param dateValue the date value to parse
|
||||
* @param dateFormats the date formats to use
|
||||
* @param dateFormats the date/time formats to use
|
||||
*
|
||||
* @return the parsed date or null if input could not be parsed
|
||||
*
|
||||
* @deprecated Use {@link #parseDate(String, DateTimeFormatter...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Date parseDate(final String dateValue, final String[] dateFormats) {
|
||||
return parseDate(dateValue, dateFormats, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the date value using the given date formats.
|
||||
* Parses the date value using the given date/time formats.
|
||||
*
|
||||
* @param dateValue the date value to parse
|
||||
* @param dateFormats the date formats to use
|
||||
* @param dateFormats the date/time formats to use
|
||||
* @param startDate During parsing, two digit years will be placed in the range
|
||||
* {@code startDate} to {@code startDate + 100 years}. This value may
|
||||
* be {@code null}. When {@code null} is given as a parameter, year
|
||||
* {@code 2000} will be used.
|
||||
*
|
||||
* @return the parsed date or null if input could not be parsed
|
||||
*
|
||||
* @deprecated Use {@link #parseDate(String, DateTimeFormatter...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Date parseDate(
|
||||
final String dateValue,
|
||||
final String[] dateFormats,
|
||||
final Date startDate) {
|
||||
Args.notNull(dateValue, "Date value");
|
||||
final String[] localDateFormats = dateFormats != null ? dateFormats : DEFAULT_PATTERNS;
|
||||
final Date localStartDate = startDate != null ? startDate : DEFAULT_TWO_DIGIT_YEAR_START;
|
||||
String v = dateValue;
|
||||
// trim single quotes around date if present
|
||||
// see issue #5279
|
||||
if (v.length() > 1 && v.startsWith("'") && v.endsWith("'")) {
|
||||
v = v.substring (1, v.length() - 1);
|
||||
}
|
||||
|
||||
for (final String dateFormat : localDateFormats) {
|
||||
final SimpleDateFormat dateParser = DateFormatHolder.formatFor(dateFormat);
|
||||
dateParser.set2DigitYearStart(localStartDate);
|
||||
final ParsePosition pos = new ParsePosition(0);
|
||||
final Date result = dateParser.parse(v, pos);
|
||||
if (pos.getIndex() != 0) {
|
||||
return result;
|
||||
final DateTimeFormatter[] dateTimeFormatters;
|
||||
if (dateFormats != null) {
|
||||
dateTimeFormatters = new DateTimeFormatter[dateFormats.length];
|
||||
for (int i = 0; i < dateFormats.length; i++) {
|
||||
dateTimeFormatters[i] = new DateTimeFormatterBuilder()
|
||||
.parseLenient()
|
||||
.parseCaseInsensitive()
|
||||
.appendPattern(dateFormats[i])
|
||||
.toFormatter();
|
||||
}
|
||||
} else {
|
||||
dateTimeFormatters = STANDARD_PATTERNS;
|
||||
}
|
||||
return null;
|
||||
return toDate(parseDate(dateValue, dateTimeFormatters));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,15 +408,16 @@ public final class DateUtils {
|
|||
* @return An RFC 1123 formatted date string.
|
||||
*
|
||||
* @see #PATTERN_RFC1123
|
||||
*
|
||||
* @deprecated Use {@link #formatStandardDate(Instant)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String formatDate(final Date date) {
|
||||
return formatDate(date, PATTERN_RFC1123);
|
||||
return formatStandardDate(toInstant(date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given date according to the specified pattern. The pattern
|
||||
* must conform to that used by the {@link SimpleDateFormat simple date
|
||||
* format} class.
|
||||
* Formats the given date according to the specified pattern.
|
||||
*
|
||||
* @param date The date to format.
|
||||
* @param pattern The pattern to use for formatting the date.
|
||||
|
@ -262,72 +425,28 @@ public final class DateUtils {
|
|||
*
|
||||
* @throws IllegalArgumentException If the given date pattern is invalid.
|
||||
*
|
||||
* @see SimpleDateFormat
|
||||
* @deprecated Use {@link #formatDate(Instant, DateTimeFormatter)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String formatDate(final Date date, final String pattern) {
|
||||
Args.notNull(date, "Date");
|
||||
Args.notNull(pattern, "Pattern");
|
||||
final SimpleDateFormat formatter = DateFormatHolder.formatFor(pattern);
|
||||
return formatter.format(date);
|
||||
return DateTimeFormatter.ofPattern(pattern).format(toInstant(date).atZone(GMT_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears thread-local variable containing {@link java.text.DateFormat} cache.
|
||||
*
|
||||
* @since 4.3
|
||||
*
|
||||
* @deprecated Noop method. Do not use.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void clearThreadLocal() {
|
||||
DateFormatHolder.clearThreadLocal();
|
||||
}
|
||||
|
||||
/** This class should not be instantiated. */
|
||||
private DateUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory for {@link SimpleDateFormat}s. The instances are stored in a
|
||||
* threadlocal way because SimpleDateFormat is not threadsafe as noted in
|
||||
* {@link SimpleDateFormat its javadoc}.
|
||||
*
|
||||
*/
|
||||
final static class DateFormatHolder {
|
||||
|
||||
private static final ThreadLocal<SoftReference<Map<String, SimpleDateFormat>>> THREADLOCAL_FORMATS = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* creates a {@link SimpleDateFormat} for the requested format string.
|
||||
*
|
||||
* @param pattern
|
||||
* a non-{@code null} format String according to
|
||||
* {@link SimpleDateFormat}. The format is not checked against
|
||||
* {@code null} since all paths go through
|
||||
* {@link DateUtils}.
|
||||
* @return the requested format. This simple dateformat should not be used
|
||||
* to {@link SimpleDateFormat#applyPattern(String) apply} to a
|
||||
* different pattern.
|
||||
*/
|
||||
public static SimpleDateFormat formatFor(final String pattern) {
|
||||
final SoftReference<Map<String, SimpleDateFormat>> ref = THREADLOCAL_FORMATS.get();
|
||||
Map<String, SimpleDateFormat> formats = ref == null ? null : ref.get();
|
||||
if (formats == null) {
|
||||
formats = new HashMap<>();
|
||||
THREADLOCAL_FORMATS.set(new SoftReference<>(formats));
|
||||
}
|
||||
|
||||
SimpleDateFormat format = formats.get(pattern);
|
||||
if (format == null) {
|
||||
format = new SimpleDateFormat(pattern, Locale.US);
|
||||
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
formats.put(pattern, format);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
public static void clearThreadLocal() {
|
||||
THREADLOCAL_FORMATS.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,8 @@ import java.net.ConnectException;
|
|||
import java.net.NoRouteToHostException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
|
@ -85,7 +86,7 @@ public class TestDefaultHttpRequestRetryStrategy {
|
|||
public void testRetryAfterHeaderAsDate() throws Exception {
|
||||
this.retryStrategy = new DefaultHttpRequestRetryStrategy(3, TimeValue.ZERO_MILLISECONDS);
|
||||
final HttpResponse response = new BasicHttpResponse(503, "Oopsie");
|
||||
response.setHeader(HttpHeaders.RETRY_AFTER, DateUtils.formatDate(new Date(System.currentTimeMillis() + 100000L)));
|
||||
response.setHeader(HttpHeaders.RETRY_AFTER, DateUtils.formatStandardDate(Instant.now().plus(100, ChronoUnit.SECONDS)));
|
||||
|
||||
Assert.assertTrue(this.retryStrategy.getRetryInterval(response, 3, null).compareTo(TimeValue.ZERO_MILLISECONDS) > 0);
|
||||
}
|
||||
|
@ -93,7 +94,7 @@ public class TestDefaultHttpRequestRetryStrategy {
|
|||
@Test
|
||||
public void testRetryAfterHeaderAsPastDate() throws Exception {
|
||||
final HttpResponse response = new BasicHttpResponse(503, "Oopsie");
|
||||
response.setHeader(HttpHeaders.RETRY_AFTER, DateUtils.formatDate(new Date(System.currentTimeMillis() - 100000L)));
|
||||
response.setHeader(HttpHeaders.RETRY_AFTER, DateUtils.formatStandardDate(Instant.now().minus(100, ChronoUnit.SECONDS)));
|
||||
|
||||
Assert.assertEquals(TimeValue.ofMilliseconds(1234L), this.retryStrategy.getRetryInterval(response, 3, null));
|
||||
}
|
||||
|
|
|
@ -27,11 +27,8 @@
|
|||
|
||||
package org.apache.hc.client5.http.impl.cookie;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.hc.client5.http.cookie.Cookie;
|
||||
import org.apache.hc.client5.http.cookie.CookieAttributeHandler;
|
||||
|
@ -327,21 +324,16 @@ public class TestBasicCookieAttribHandlers {
|
|||
@Test
|
||||
public void testBasicExpiresParse() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new BasicExpiresHandler(new String[] {DateUtils.PATTERN_RFC1123});
|
||||
final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123);
|
||||
|
||||
final DateFormat dateformat = new SimpleDateFormat(DateUtils.PATTERN_RFC1123, Locale.US);
|
||||
dateformat.setTimeZone(DateUtils.GMT);
|
||||
|
||||
final Date now = new Date();
|
||||
|
||||
h.parse(cookie, dateformat.format(now));
|
||||
h.parse(cookie, DateUtils.formatStandardDate(Instant.now()));
|
||||
Assert.assertNotNull(cookie.getExpiryDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicExpiresParseInvalid() throws Exception {
|
||||
final BasicClientCookie cookie = new BasicClientCookie("name", "value");
|
||||
final CookieAttributeHandler h = new BasicExpiresHandler(new String[] {DateUtils.PATTERN_RFC1123});
|
||||
final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123);
|
||||
Assert.assertThrows(MalformedCookieException.class, () ->
|
||||
h.parse(cookie, "garbage"));
|
||||
Assert.assertThrows(MalformedCookieException.class, () ->
|
||||
|
@ -351,8 +343,7 @@ public class TestBasicCookieAttribHandlers {
|
|||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testBasicExpiresInvalidInput() throws Exception {
|
||||
Assert.assertThrows(NullPointerException.class, () -> new BasicExpiresHandler(null));
|
||||
final CookieAttributeHandler h = new BasicExpiresHandler(new String[] {DateUtils.PATTERN_RFC1123});
|
||||
final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123);
|
||||
Assert.assertThrows(NullPointerException.class, () -> h.parse(null, null));
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
|
||||
package org.apache.hc.client5.http.impl.cookie;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoField;
|
||||
|
||||
import org.apache.hc.client5.http.cookie.CookieAttributeHandler;
|
||||
import org.apache.hc.client5.http.cookie.MalformedCookieException;
|
||||
import org.apache.hc.client5.http.utils.DateUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -97,18 +98,16 @@ public class TestLaxCookieAttribHandlers {
|
|||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:0:12 8-jan-2012");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate());
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2012, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.JANUARY, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(8, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(1, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(0, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(12, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
|
||||
Assert.assertEquals(2012, expiryDate.get(ChronoField.YEAR));
|
||||
Assert.assertEquals(1, expiryDate.get(ChronoField.MONTH_OF_YEAR));
|
||||
Assert.assertEquals(8, expiryDate.get(ChronoField.DAY_OF_MONTH));
|
||||
Assert.assertEquals(1, expiryDate.get(ChronoField.HOUR_OF_DAY));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.MINUTE_OF_HOUR));
|
||||
Assert.assertEquals(12, expiryDate.get(ChronoField.SECOND_OF_MINUTE));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -157,18 +156,16 @@ public class TestLaxCookieAttribHandlers {
|
|||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "1:59:00blah; 8-feb-2000");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate());
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2000, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.FEBRUARY, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(8, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(1, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(0, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
|
||||
Assert.assertEquals(2000, expiryDate.get(ChronoField.YEAR_OF_ERA));
|
||||
Assert.assertEquals(2, expiryDate.get(ChronoField.MONTH_OF_YEAR));
|
||||
Assert.assertEquals(8, expiryDate.get(ChronoField.DAY_OF_MONTH));
|
||||
Assert.assertEquals(1, expiryDate.get(ChronoField.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, expiryDate.get(ChronoField.MINUTE_OF_HOUR));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.SECOND_OF_MINUTE));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -201,18 +198,16 @@ public class TestLaxCookieAttribHandlers {
|
|||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "12:00:00 8blah;mar;1880");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate());
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(1880, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.MARCH, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(8, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(12, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(0, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(0, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
|
||||
Assert.assertEquals(1880, expiryDate.get(ChronoField.YEAR));
|
||||
Assert.assertEquals(3, expiryDate.get(ChronoField.MONTH_OF_YEAR));
|
||||
Assert.assertEquals(8, expiryDate.get(ChronoField.DAY_OF_MONTH));
|
||||
Assert.assertEquals(12, expiryDate.get(ChronoField.HOUR_OF_DAY));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.MINUTE_OF_HOUR));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.SECOND_OF_MINUTE));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -229,18 +224,16 @@ public class TestLaxCookieAttribHandlers {
|
|||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-ApriLLLLL-2008");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate());
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2008, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.APRIL, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(1, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(23, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(59, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
|
||||
Assert.assertEquals(2008, expiryDate.get(ChronoField.YEAR));
|
||||
Assert.assertEquals(4, expiryDate.get(ChronoField.MONTH_OF_YEAR));
|
||||
Assert.assertEquals(1, expiryDate.get(ChronoField.DAY_OF_MONTH));
|
||||
Assert.assertEquals(23, expiryDate.get(ChronoField.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, expiryDate.get(ChronoField.MINUTE_OF_HOUR));
|
||||
Assert.assertEquals(59, expiryDate.get(ChronoField.SECOND_OF_MINUTE));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -273,18 +266,16 @@ public class TestLaxCookieAttribHandlers {
|
|||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-Apr-2008blah");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate());
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2008, c.get(Calendar.YEAR));
|
||||
Assert.assertEquals(Calendar.APRIL, c.get(Calendar.MONTH));
|
||||
Assert.assertEquals(1, c.get(Calendar.DAY_OF_MONTH));
|
||||
Assert.assertEquals(23, c.get(Calendar.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, c.get(Calendar.MINUTE));
|
||||
Assert.assertEquals(59, c.get(Calendar.SECOND));
|
||||
Assert.assertEquals(0, c.get(Calendar.MILLISECOND));
|
||||
|
||||
Assert.assertEquals(2008, expiryDate.get(ChronoField.YEAR));
|
||||
Assert.assertEquals(4, expiryDate.get(ChronoField.MONTH_OF_YEAR));
|
||||
Assert.assertEquals(1, expiryDate.get(ChronoField.DAY_OF_MONTH));
|
||||
Assert.assertEquals(23, expiryDate.get(ChronoField.HOUR_OF_DAY));
|
||||
Assert.assertEquals(59, expiryDate.get(ChronoField.MINUTE_OF_HOUR));
|
||||
Assert.assertEquals(59, expiryDate.get(ChronoField.SECOND_OF_MINUTE));
|
||||
Assert.assertEquals(0, expiryDate.get(ChronoField.MILLI_OF_SECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -293,12 +284,10 @@ public class TestLaxCookieAttribHandlers {
|
|||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-Apr-70");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate());
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(1970, c.get(Calendar.YEAR));
|
||||
|
||||
Assert.assertEquals(1970, expiryDate.get(ChronoField.YEAR));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -307,12 +296,10 @@ public class TestLaxCookieAttribHandlers {
|
|||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-Apr-99");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate());
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(1999, c.get(Calendar.YEAR));
|
||||
|
||||
Assert.assertEquals(1999, expiryDate.get(ChronoField.YEAR));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -321,12 +308,10 @@ public class TestLaxCookieAttribHandlers {
|
|||
final CookieAttributeHandler h = new LaxExpiresHandler();
|
||||
h.parse(cookie, "23:59:59; 1-Apr-00");
|
||||
|
||||
final Date expiryDate = cookie.getExpiryDate();
|
||||
final LocalDateTime expiryDate = DateUtils.toUTC(cookie.getExpiryDate());
|
||||
Assert.assertNotNull(expiryDate);
|
||||
final Calendar c = Calendar.getInstance();
|
||||
c.setTimeZone(LaxExpiresHandler.UTC);
|
||||
c.setTime(expiryDate);
|
||||
Assert.assertEquals(2000, c.get(Calendar.YEAR));
|
||||
|
||||
Assert.assertEquals(2000, expiryDate.get(ChronoField.YEAR));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,14 +27,17 @@
|
|||
|
||||
package org.apache.hc.client5.http.utils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.hc.core5.http.HttpHeaders;
|
||||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
import org.apache.hc.core5.http.message.HeaderGroup;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -43,103 +46,71 @@ import org.junit.Test;
|
|||
*/
|
||||
public class TestDateUtils {
|
||||
|
||||
private static Date createDate(final int year, final int month, final int day) {
|
||||
final Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeZone(DateUtils.GMT);
|
||||
calendar.setTimeInMillis(0);
|
||||
calendar.set(year, month, day);
|
||||
return calendar.getTime();
|
||||
private static Instant createInstant(final int year, final Month month, final int day) {
|
||||
return LocalDate.of(year, month, day).atStartOfDay(ZoneId.of("GMT")).toInstant();
|
||||
}
|
||||
|
||||
private static Date createDate(final int year, final Month month, final int day) {
|
||||
final Instant instant = createInstant(year, month, day);
|
||||
return new Date(instant.toEpochMilli());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicDateParse() throws Exception {
|
||||
final Date date = createDate(2005, Calendar.OCTOBER, 14);
|
||||
final String[] formats = new String[] { DateUtils.PATTERN_RFC1123 };
|
||||
Assert.assertEquals(date, DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT", formats, null));
|
||||
Assert.assertEquals(date, DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT", formats));
|
||||
Assert.assertEquals(date, DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT"));
|
||||
final Instant instant = createInstant(2005, Month.OCTOBER, 14);
|
||||
Assert.assertEquals(instant, DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT", DateUtils.FORMATTER_RFC1123));
|
||||
Assert.assertEquals(instant, DateUtils.parseDate("Friday, 14 Oct 2005 00:00:00 GMT", DateUtils.FORMATTER_RFC1123));
|
||||
Assert.assertEquals(instant, DateUtils.parseDate("Fri, 14-Oct-2005 00:00:00 GMT", DateUtils.FORMATTER_RFC1036));
|
||||
Assert.assertEquals(instant, DateUtils.parseDate("Friday, 14-Oct-2005 00:00:00 GMT", DateUtils.FORMATTER_RFC1036));
|
||||
Assert.assertEquals(instant.minus(2, ChronoUnit.HOURS),
|
||||
DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 CET", DateUtils.FORMATTER_RFC1123));
|
||||
Assert.assertEquals(instant.minus(2, ChronoUnit.HOURS),
|
||||
DateUtils.parseDate("Fri, 14-Oct-05 00:00:00 CET", DateUtils.FORMATTER_RFC1036));
|
||||
Assert.assertEquals(instant, DateUtils.parseStandardDate("Fri, 14 Oct 2005 00:00:00 GMT"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateParseMessage() throws Exception {
|
||||
final HeaderGroup message1 = new HeaderGroup();
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "Fri, 14 Oct 2005 00:00:00 GMT"));
|
||||
Assert.assertEquals(createDate(2005, Calendar.OCTOBER, 14), DateUtils.parseDate(message1, HttpHeaders.DATE));
|
||||
Assert.assertEquals(createInstant(2005, Month.OCTOBER, 14), DateUtils.parseStandardDate(message1, HttpHeaders.DATE));
|
||||
|
||||
final HeaderGroup message2 = new HeaderGroup();
|
||||
message2.addHeader(new BasicHeader(HttpHeaders.DATE, "Fri, 14 Oct 2005 00:00:00 GMT"));
|
||||
message2.addHeader(new BasicHeader(HttpHeaders.DATE, "Fri, 21 Oct 2005 00:00:00 GMT"));
|
||||
Assert.assertEquals(createDate(2005, Calendar.OCTOBER, 14), DateUtils.parseDate(message2, HttpHeaders.DATE));
|
||||
Assert.assertEquals(createInstant(2005, Month.OCTOBER, 14), DateUtils.parseStandardDate(message2, HttpHeaders.DATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedDate() {
|
||||
Assert.assertNull(DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT", new String[] {}, null));
|
||||
Assert.assertNull(DateUtils.parseDate("Fri, 14 Oct 2005 00:00:00 GMT", new DateTimeFormatter[] {}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidInput() throws Exception {
|
||||
Assert.assertThrows(NullPointerException.class, () -> DateUtils.parseDate(null, null, null));
|
||||
Assert.assertThrows(NullPointerException.class, () -> DateUtils.formatDate(null));
|
||||
Assert.assertThrows(NullPointerException.class, () -> DateUtils.formatDate(new Date(), null));
|
||||
Assert.assertThrows(NullPointerException.class, () -> DateUtils.parseStandardDate(null));
|
||||
Assert.assertThrows(NullPointerException.class, () -> DateUtils.formatStandardDate(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoDigitYearDateParse() throws Exception {
|
||||
final String[] formats = new String[] { DateUtils.PATTERN_RFC1036 };
|
||||
Assert.assertEquals(createDate(2005, Calendar.OCTOBER, 14), DateUtils.parseDate("Friday, 14-Oct-05 00:00:00 GMT", formats, null));
|
||||
Assert.assertEquals(createDate(1905, Calendar.OCTOBER, 14), DateUtils.parseDate("Friday, 14-Oct-05 00:00:00 GMT", formats,
|
||||
createDate(1900, Calendar.JANUARY, 0)));
|
||||
Assert.assertEquals(createInstant(2005, Month.OCTOBER, 14),
|
||||
DateUtils.parseDate("Friday, 14-Oct-05 00:00:00 GMT", DateUtils.FORMATTER_RFC1036));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseQuotedDate() throws Exception {
|
||||
final Date date1 = createDate(2005, Calendar.OCTOBER, 14);
|
||||
final String[] formats = new String[] { DateUtils.PATTERN_RFC1123 };
|
||||
final Date date2 = DateUtils.parseDate("'Fri, 14 Oct 2005 00:00:00 GMT'", formats);
|
||||
Assert.assertEquals(date1, date2);
|
||||
Assert.assertEquals(createInstant(2005, Month.OCTOBER, 14),
|
||||
DateUtils.parseDate("'Fri, 14 Oct 2005 00:00:00 GMT'", DateUtils.FORMATTER_RFC1123));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicDateFormat() throws Exception {
|
||||
final Date date = createDate(2005, Calendar.OCTOBER, 14);
|
||||
Assert.assertEquals("Fri, 14 Oct 2005 00:00:00 GMT", DateUtils.formatDate(date));
|
||||
Assert.assertEquals("Fri, 14 Oct 2005 00:00:00 GMT", DateUtils.formatDate(date, DateUtils.PATTERN_RFC1123));
|
||||
final Instant instant = createInstant(2005, Month.OCTOBER, 14);
|
||||
Assert.assertEquals("Fri, 14 Oct 2005 00:00:00 GMT", DateUtils.formatStandardDate(instant));
|
||||
Assert.assertEquals("Fri, 14 Oct 2005 00:00:00 GMT", DateUtils.formatDate(instant, DateUtils.FORMATTER_RFC1123));
|
||||
Assert.assertEquals("Fri, 14-Oct-05 00:00:00 GMT", DateUtils.formatDate(instant, DateUtils.FORMATTER_RFC1036));
|
||||
Assert.assertEquals("Fri Oct 14 00:00:00 2005", DateUtils.formatDate(instant, DateUtils.FORMATTER_ASCTIME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBefore() throws Exception {
|
||||
final HeaderGroup message1 = new HeaderGroup();
|
||||
final HeaderGroup message2 = new HeaderGroup();
|
||||
MatcherAssert.assertThat(DateUtils.isBefore(null, null, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
MatcherAssert.assertThat(DateUtils.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "huh?"));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, "eh?"));
|
||||
MatcherAssert.assertThat(DateUtils.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "huh?"));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, "Tuesday, 26-Dec-2017 00:00:00 GMT"));
|
||||
MatcherAssert.assertThat(DateUtils.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "Wednesday, 25-Dec-2017 00:00:00 GMT"));
|
||||
MatcherAssert.assertThat(DateUtils.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(true));
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "Thursday, 27-Dec-2017 00:00:00 GMT"));
|
||||
MatcherAssert.assertThat(DateUtils.isBefore(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAfter() throws Exception {
|
||||
final HeaderGroup message1 = new HeaderGroup();
|
||||
final HeaderGroup message2 = new HeaderGroup();
|
||||
MatcherAssert.assertThat(DateUtils.isAfter(null, null, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
MatcherAssert.assertThat(DateUtils.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "huh?"));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, "eh?"));
|
||||
MatcherAssert.assertThat(DateUtils.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "huh?"));
|
||||
message2.setHeader(new BasicHeader(HttpHeaders.DATE, "Tuesday, 26-Dec-2017 00:00:00 GMT"));
|
||||
MatcherAssert.assertThat(DateUtils.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "Thursday, 27-Dec-2017 00:00:00 GMT"));
|
||||
MatcherAssert.assertThat(DateUtils.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(true));
|
||||
message1.setHeader(new BasicHeader(HttpHeaders.DATE, "Wednesday, 25-Dec-2017 00:00:00 GMT"));
|
||||
MatcherAssert.assertThat(DateUtils.isAfter(message1, message2, HttpHeaders.DATE), CoreMatchers.equalTo(false));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue