-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Allow Request#getDateHeader to parse dates in RFC 9651 Structured Field Values format #1054
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -50,8 +50,9 @@ private FastHttpDateFormat() { | |||||
| private static final ConcurrentDateFormat FORMAT_RFC5322; | ||||||
| private static final ConcurrentDateFormat FORMAT_OBSOLETE_RFC850; | ||||||
| private static final ConcurrentDateFormat FORMAT_OBSOLETE_ASCTIME; | ||||||
| private static final TryParseDateToTimestamp FORMAT_RFC9651; | ||||||
|
|
||||||
| private static final ConcurrentDateFormat[] httpParseFormats; | ||||||
| private static final TryParseDateToTimestamp[] httpParseFormats; | ||||||
|
|
||||||
| static { | ||||||
| // All the formats that use a timezone use GMT | ||||||
|
|
@@ -60,9 +61,20 @@ private FastHttpDateFormat() { | |||||
| FORMAT_RFC5322 = new ConcurrentDateFormat(DATE_RFC5322, Locale.US, tz); | ||||||
| FORMAT_OBSOLETE_RFC850 = new ConcurrentDateFormat(DATE_OBSOLETE_RFC850, Locale.US, tz); | ||||||
| FORMAT_OBSOLETE_ASCTIME = new ConcurrentDateFormat(DATE_OBSOLETE_ASCTIME, Locale.US, tz); | ||||||
| FORMAT_RFC9651 = dateString -> { | ||||||
| if(dateString == null || !dateString.startsWith("@")) { | ||||||
| return -1; | ||||||
| } | ||||||
| try { | ||||||
| // An RFC 9651 timestamp is in seconds, not milliseconds. | ||||||
| return Long.parseLong(dateString.substring(1)) * 1_000; | ||||||
| } catch (NumberFormatException e) { | ||||||
| return -1; | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| httpParseFormats = | ||||||
| new ConcurrentDateFormat[] { FORMAT_RFC5322, FORMAT_OBSOLETE_RFC850, FORMAT_OBSOLETE_ASCTIME }; | ||||||
| new TryParseDateToTimestamp[] { FORMAT_RFC5322, FORMAT_OBSOLETE_RFC850, FORMAT_OBSOLETE_ASCTIME, FORMAT_RFC9651 }; | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
|
|
@@ -146,13 +158,9 @@ public static long parseDate(String value) { | |||||
|
|
||||||
| long date = -1; | ||||||
| for (int i = 0; (date == -1) && (i < httpParseFormats.length); i++) { | ||||||
| try { | ||||||
| date = httpParseFormats[i].parse(value).getTime(); | ||||||
| updateParseCache(value, Long.valueOf(date)); | ||||||
| } catch (ParseException e) { | ||||||
| // Ignore | ||||||
| } | ||||||
| date = httpParseFormats[i].tryParseDate(value); | ||||||
| } | ||||||
| updateParseCache(value, Long.valueOf(date)); | ||||||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now this is also called for values that failed to parse. Not sure if that’s better or worse. IMHO it makes sense to also cache these, since they’re the most expensive to calculate as they have to be tried (and rejected) by all the parsers. |
||||||
|
|
||||||
| return date; | ||||||
| } | ||||||
|
|
@@ -185,5 +193,14 @@ private static void updateParseCache(String key, Long value) { | |||||
| parseCache.put(key, value); | ||||||
| } | ||||||
|
|
||||||
|
|
||||||
| @FunctionalInterface | ||||||
| interface TryParseDateToTimestamp { | ||||||
| /** | ||||||
| * Tries to parse the given string as a date and returns it as a timestamp. | ||||||
| * | ||||||
| * @param dateString the string representation of the date trying to be parsed | ||||||
| * @return the number of *milli*seconds since January 1, 1970, 00:00:00 GMT or -1 if parsing failed | ||||||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| */ | ||||||
| long tryParseDate(String dateString); | ||||||
| } | ||||||
| } | ||||||
Uh oh!
There was an error while loading. Please reload this page.