You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by sv...@apache.org on 2017/05/29 14:01:20 UTC
jclouds git commit: JCLOUDS-1295: Support deprecated date formats in
the Expires header
Repository: jclouds
Updated Branches:
refs/heads/master 28c3c33bf -> db2f86bce
JCLOUDS-1295: Support deprecated date formats in the Expires header
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/db2f86bc
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/db2f86bc
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/db2f86bc
Branch: refs/heads/master
Commit: db2f86bcecfe0d68183a166ad07a7f996d332539
Parents: 28c3c33
Author: Ignasi Barrera <na...@apache.org>
Authored: Fri May 26 10:31:50 2017 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Mon May 29 16:59:42 2017 +0300
----------------------------------------------------------------------
.../java/org/jclouds/date/DateCodecFactory.java | 1 +
.../internal/DateServiceDateCodecFactory.java | 34 +++++++++++++
.../org/jclouds/io/ContentMetadataCodec.java | 41 +++++++++++++---
.../DateServiceDateCodecFactoryTest.java | 19 ++++++++
.../io/DefaultContentMetadataCodecTest.java | 51 ++++++++++++++++++++
5 files changed, 138 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/db2f86bc/core/src/main/java/org/jclouds/date/DateCodecFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/date/DateCodecFactory.java b/core/src/main/java/org/jclouds/date/DateCodecFactory.java
index 19da52f..1fb4ba0 100644
--- a/core/src/main/java/org/jclouds/date/DateCodecFactory.java
+++ b/core/src/main/java/org/jclouds/date/DateCodecFactory.java
@@ -36,4 +36,5 @@ public interface DateCodecFactory {
DateCodec iso8601Seconds();
+ DateCodec asctime();
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/db2f86bc/core/src/main/java/org/jclouds/date/internal/DateServiceDateCodecFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/date/internal/DateServiceDateCodecFactory.java b/core/src/main/java/org/jclouds/date/internal/DateServiceDateCodecFactory.java
index b652596..24e443d 100644
--- a/core/src/main/java/org/jclouds/date/internal/DateServiceDateCodecFactory.java
+++ b/core/src/main/java/org/jclouds/date/internal/DateServiceDateCodecFactory.java
@@ -35,6 +35,7 @@ public class DateServiceDateCodecFactory implements DateCodecFactory {
private final DateCodec rfc1123Codec;
private final DateCodec iso8601Codec;
private final DateCodec iso8601SecondsCodec;
+ private final DateCodec asctime;
@Inject
public DateServiceDateCodecFactory(DateService dateService) {
@@ -43,6 +44,7 @@ public class DateServiceDateCodecFactory implements DateCodecFactory {
this.rfc1123Codec = new DateServiceRfc1123Codec(dateService);
this.iso8601Codec = new DateServiceIso8601Codec(dateService);
this.iso8601SecondsCodec = new DateServiceIso8601SecondsCodec(dateService);
+ this.asctime = new DateServiceAsctimeCodec(dateService);
}
@Singleton
@@ -153,6 +155,33 @@ public class DateServiceDateCodecFactory implements DateCodecFactory {
}
+ @Singleton
+ public static class DateServiceAsctimeCodec implements DateCodec {
+
+ protected final DateService dateService;
+
+ @Inject
+ public DateServiceAsctimeCodec(DateService dateService) {
+ this.dateService = checkNotNull(dateService, "dateService");
+ }
+
+ @Override
+ public Date toDate(String date) throws IllegalArgumentException {
+ return dateService.cDateParse(date);
+ }
+
+ @Override
+ public String toString(Date date) {
+ return dateService.cDateFormat(date);
+ }
+
+ @Override
+ public String toString() {
+ return "asctime()";
+ }
+
+ }
+
@Override
public DateCodec rfc822() {
return rfc822Codec;
@@ -173,4 +202,9 @@ public class DateServiceDateCodecFactory implements DateCodecFactory {
return iso8601SecondsCodec;
}
+ @Override
+ public DateCodec asctime() {
+ return asctime;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/db2f86bc/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java b/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java
index 05de972..242bc5e 100644
--- a/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java
+++ b/core/src/main/java/org/jclouds/io/ContentMetadataCodec.java
@@ -28,6 +28,7 @@ import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
import static com.google.common.net.HttpHeaders.EXPIRES;
import java.util.Date;
+import java.util.List;
import java.util.Map.Entry;
import javax.annotation.Resource;
@@ -38,6 +39,7 @@ import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.common.collect.Multimap;
@@ -73,16 +75,22 @@ public interface ContentMetadataCodec {
protected Logger logger = Logger.NULL;
private final DateCodec httpExpiresDateCodec;
+ private final List<DateCodec> httpExpiresDateDecoders;
@Inject
public DefaultContentMetadataCodec(DateCodecFactory dateCodecs) {
httpExpiresDateCodec = dateCodecs.rfc1123();
+ httpExpiresDateDecoders = ImmutableList.of(dateCodecs.rfc1123(), dateCodecs.asctime());
}
-
+
protected DateCodec getExpiresDateCodec() {
return httpExpiresDateCodec;
}
-
+
+ protected List<DateCodec> getExpiresDateDecoders() {
+ return httpExpiresDateDecoders;
+ }
+
@Override
public Multimap<String, String> toHeaders(ContentMetadata md) {
Builder<String, String> builder = ImmutableMultimap.builder();
@@ -134,14 +142,31 @@ public interface ContentMetadataCodec {
}
}
+ /**
+ * Parses the date from the given Expires header.
+ * <p>
+ * According to the RFC, dates should always come in RFC-1123 format.
+ * However, clients should also support older and deprecated formats for
+ * compatibility, so this method will try to parse an RFC-1123 date, and
+ * fallback to the ANSI C format.
+ *
+ * @see https://tools.ietf.org/html/rfc2616#section-3.3
+ */
public Date parseExpires(String expires) {
- try {
- return (expires != null) ? getExpiresDateCodec().toDate(expires) : null;
- } catch (IllegalArgumentException e) {
- logger.debug("Invalid Expires header (%s); should be in RFC-1123 format; treating as already expired: %s",
- expires, e.getMessage());
- return new Date(0);
+ if (expires == null)
+ return null;
+
+ for (DateCodec decoder : getExpiresDateDecoders()) {
+ try {
+ return decoder.toDate(expires);
+ } catch (IllegalArgumentException ex) {
+ logger.trace("Expires header (%s) is not in the expected %s format", expires, decoder);
+ // Continue trying the other decoders
+ }
}
+
+ logger.debug("Invalid Expires header (%s); should be in RFC-1123 format; treating as already expired", expires);
+ return new Date(0);
}
}
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/db2f86bc/core/src/test/java/org/jclouds/date/internal/DateServiceDateCodecFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/date/internal/DateServiceDateCodecFactoryTest.java b/core/src/test/java/org/jclouds/date/internal/DateServiceDateCodecFactoryTest.java
index 697925a..4a789f2 100644
--- a/core/src/test/java/org/jclouds/date/internal/DateServiceDateCodecFactoryTest.java
+++ b/core/src/test/java/org/jclouds/date/internal/DateServiceDateCodecFactoryTest.java
@@ -33,6 +33,7 @@ public class DateServiceDateCodecFactoryTest {
private DateCodec rfc1123Codec;
private DateCodec iso8601Codec;
private DateCodec iso8601SecondsCodec;
+ private DateCodec asctimeCodec;
@BeforeTest
public void setUp() {
@@ -41,6 +42,7 @@ public class DateServiceDateCodecFactoryTest {
rfc1123Codec = simpleDateCodecFactory.rfc1123();
iso8601Codec = simpleDateCodecFactory.iso8601();
iso8601SecondsCodec = simpleDateCodecFactory.iso8601Seconds();
+ asctimeCodec = simpleDateCodecFactory.asctime();
}
@Test
@@ -110,4 +112,21 @@ public class DateServiceDateCodecFactoryTest {
} catch (IllegalArgumentException e) {
}
}
+
+ @Test
+ public void testCodecForAsctime() {
+ Date date = new Date(1000);
+ assertEquals(asctimeCodec.toDate(asctimeCodec.toString(date)), date);
+
+ assertEquals(asctimeCodec.toDate("Thu Dec 01 16:00:00 GMT 1994"), new Date(786297600000L));
+ }
+
+ @Test
+ public void testCodecForAsctimeThrowsParseExceptionWhenMalformed() {
+ try {
+ asctimeCodec.toDate("-");
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/db2f86bc/core/src/test/java/org/jclouds/io/DefaultContentMetadataCodecTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/io/DefaultContentMetadataCodecTest.java b/core/src/test/java/org/jclouds/io/DefaultContentMetadataCodecTest.java
new file mode 100644
index 0000000..3b18a62
--- /dev/null
+++ b/core/src/test/java/org/jclouds/io/DefaultContentMetadataCodecTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+package org.jclouds.io;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Date;
+
+import org.jclouds.date.internal.DateServiceDateCodecFactory;
+import org.jclouds.date.internal.SimpleDateFormatDateService;
+import org.jclouds.io.ContentMetadataCodec.DefaultContentMetadataCodec;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "DefaultContentMetadataCodecTest")
+public class DefaultContentMetadataCodecTest {
+
+ private final DateServiceDateCodecFactory codecfactory = new DateServiceDateCodecFactory(
+ new SimpleDateFormatDateService());
+
+ public void testCanParseRFC1123Dates() {
+ DefaultContentMetadataCodec codec = new DefaultContentMetadataCodec(codecfactory);
+ Date parsed = codec.parseExpires("Thu, 01 Dec 1994 16:00:00 GMT");
+ assertEquals(parsed, new Date(786297600000L));
+ }
+
+ public void testCanParseAsctimeDates() {
+ DefaultContentMetadataCodec codec = new DefaultContentMetadataCodec(codecfactory);
+ Date parsed = codec.parseExpires("Thu Dec 01 16:00:00 GMT 1994");
+ assertEquals(parsed, new Date(786297600000L));
+ }
+
+ public void testFallbackToExpiredDate() {
+ DefaultContentMetadataCodec codec = new DefaultContentMetadataCodec(codecfactory);
+ Date parsed = codec.parseExpires("1994-12-01T16:00:00.000Z");
+ assertEquals(parsed, new Date(0));
+ }
+}