1010 */
1111package io .vertx .httpproxy .impl ;
1212
13- import java .text .SimpleDateFormat ;
14- import java .time .DayOfWeek ;
15- import java .util .Date ;
16- import java .util .Locale ;
17- import java .util .TimeZone ;
13+ import java .time .*;
14+ import java .time .format .DateTimeFormatter ;
15+ import java .time .format .DateTimeFormatterBuilder ;
16+ import java .util .*;
1817
1918/**
2019 * @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
2120 */
2221public class ParseUtils {
2322
24- public static Date parseHeaderDate (String value ) {
23+ public static final DateTimeFormatter RFC_850_DATE_TIME = new DateTimeFormatterBuilder ()
24+ .appendPattern ("EEEE, dd-MMM-yy HH:mm:ss" )
25+ .parseLenient ()
26+ .appendLiteral (" GMT" )
27+ .toFormatter (Locale .US )
28+ .withZone (ZoneId .of ("UTC" ));
29+
30+ public static final DateTimeFormatter ASC_TIME = new DateTimeFormatterBuilder ()
31+ .appendPattern ("EEE MMM d HH:mm:ss yyyy" )
32+ .parseLenient ()
33+ .toFormatter (Locale .US )
34+ .withZone (ZoneId .of ("UTC" ));
35+
36+ public static Instant parseHeaderDate (String value ) {
2537 try {
2638 return parseHttpDate (value );
2739 } catch (Exception e ) {
2840 return null ;
2941 }
3042 }
3143
32- public static Date parseWarningHeaderDate (String value ) {
44+ public static Instant parseWarningHeaderDate (String value ) {
3345 // warn-code
3446 int index = value .indexOf (' ' );
3547 if (index > 0 ) {
@@ -43,110 +55,27 @@ public static Date parseWarningHeaderDate(String value) {
4355 int len = value .length ();
4456 if (index + 2 < len && value .charAt (index + 1 ) == '"' && value .charAt (len - 1 ) == '"' ) {
4557 // Space for 2 double quotes
46- String date = value .substring (index + 2 , len - 1 );
47- try {
48- return parseHttpDate (date );
49- } catch (Exception ignore ) {
50- }
58+ return parseHeaderDate (value .substring (index + 2 , len - 1 ));
5159 }
5260 }
5361 }
5462 }
5563 return null ;
5664 }
5765
58- private static SimpleDateFormat RFC_1123_DATE_TIME () {
59- SimpleDateFormat format = new SimpleDateFormat ("EEE, dd MMM yyyy HH:mm:ss z" , Locale .US );
60- format .setTimeZone (TimeZone .getTimeZone ("GMT" ));
61- return format ;
66+ public static String formatHttpDate (Instant date ) {
67+ return DateTimeFormatter .RFC_1123_DATE_TIME .format (OffsetDateTime .ofInstant (date , ZoneOffset .UTC ));
6268 }
6369
64- private static SimpleDateFormat RFC_850_DATE_TIME () {
65- SimpleDateFormat format = new SimpleDateFormat ("EEEEEEEEE, dd-MMM-yy HH:mm:ss zzz" , Locale .US );
66- format .setTimeZone (TimeZone .getTimeZone ("GMT" ));
67- return format ;
68- }
69-
70- private static SimpleDateFormat ASC_TIME () {
71- SimpleDateFormat format = new SimpleDateFormat ("EEE MMM dd HH:mm:ss yyyy" , Locale .US );
72- format .setTimeZone (TimeZone .getTimeZone ("GMT" ));
73- return format ;
74- }
75-
76- public static String formatHttpDate (Date date ) {
77- return RFC_1123_DATE_TIME ().format (date );
78- }
79-
80- // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
81- public static Date parseHttpDate (String value ) throws Exception {
82- int sep = 0 ;
83- while (true ) {
84- if (sep < value .length ()) {
85- char c = value .charAt (sep );
86- if (c == ',' ) {
87- String s = value .substring (0 , sep );
88- if (parseWkday (s ) != null ) {
89- // rfc1123-date
90- return RFC_1123_DATE_TIME ().parse (value );
91- } else if (parseWeekday (s ) != null ) {
92- // rfc850-date
93- return RFC_850_DATE_TIME ().parse (value );
94- }
95- return null ;
96- } else if (c == ' ' ) {
97- String s = value .substring (0 , sep );
98- if (parseWkday (s ) != null ) {
99- // asctime-date
100- return ASC_TIME ().parse (value );
101- }
102- return null ;
103- }
104- sep ++;
105- } else {
106- return null ;
107- }
108- }
109- }
110-
111- private static DayOfWeek parseWkday (String value ) {
112- switch (value ) {
113- case "Mon" :
114- return DayOfWeek .MONDAY ;
115- case "Tue" :
116- return DayOfWeek .TUESDAY ;
117- case "Wed" :
118- return DayOfWeek .WEDNESDAY ;
119- case "Thu" :
120- return DayOfWeek .THURSDAY ;
121- case "Fri" :
122- return DayOfWeek .FRIDAY ;
123- case "Sat" :
124- return DayOfWeek .SATURDAY ;
125- case "Sun" :
126- return DayOfWeek .SUNDAY ;
127- default :
128- return null ;
70+ // https://www.rfc-editor.org/rfc/rfc9110#http.date
71+ public static Instant parseHttpDate (String value ) throws Exception {
72+ int pos = value .indexOf (',' );
73+ if (pos == 3 ) { // e.g. Sun, 06 Nov 1994 08:49:37 GMT
74+ return DateTimeFormatter .RFC_1123_DATE_TIME .parse (value , Instant ::from );
12975 }
130- }
131-
132- private static DayOfWeek parseWeekday (String value ) {
133- switch (value ) {
134- case "Monday" :
135- return DayOfWeek .MONDAY ;
136- case "Tuesday" :
137- return DayOfWeek .TUESDAY ;
138- case "Wednesday" :
139- return DayOfWeek .WEDNESDAY ;
140- case "Thursday" :
141- return DayOfWeek .THURSDAY ;
142- case "Friday" :
143- return DayOfWeek .FRIDAY ;
144- case "Saturday" :
145- return DayOfWeek .SATURDAY ;
146- case "Sunday" :
147- return DayOfWeek .SUNDAY ;
148- default :
149- return null ;
76+ if (pos == -1 ) { // e.g. Sun Nov 6 08:49:37 1994
77+ return ASC_TIME .parse (value , Instant ::from );
15078 }
79+ return RFC_850_DATE_TIME .parse (value , Instant ::from ); // e.g. Sunday, 06-Nov-94 08:49:37 GMT
15180 }
15281}
0 commit comments