OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library http_parser.http_date; | 5 library http_parser.http_date; |
6 | 6 |
7 import 'package:string_scanner/string_scanner.dart'; | 7 import 'package:string_scanner/string_scanner.dart'; |
8 | 8 |
9 const _WEEKDAYS = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; | 9 const _WEEKDAYS = const ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; |
10 const _MONTHS = const ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", | 10 const _MONTHS = const ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", |
11 "Sep", "Oct", "Nov", "Dec"]; | 11 "Sep", "Oct", "Nov", "Dec"]; |
12 | 12 |
13 final _shortWeekdayRegExp = new RegExp(r"Mon|Tue|Wed|Thu|Fri|Sat|Sun"); | 13 final _shortWeekdayRegExp = new RegExp(r"Mon|Tue|Wed|Thu|Fri|Sat|Sun"); |
14 final _longWeekdayRegExp = | 14 final _longWeekdayRegExp = |
15 new RegExp(r"Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday"); | 15 new RegExp(r"Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday"); |
16 final _monthRegExp = | 16 final _monthRegExp = |
17 new RegExp(r"Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec"); | 17 new RegExp(r"Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec"); |
18 final _digitRegExp = new RegExp(r"\d+"); | 18 final _digitRegExp = new RegExp(r"\d+"); |
19 | 19 |
20 /// Return a HTTP-formatted string representation of [date]. | 20 /// Return a HTTP-formatted string representation of [date]. |
21 /// | 21 /// |
22 /// This follows [RFC 822](http://tools.ietf.org/html/rfc822) as updated by [RFC | 22 /// This follows [RFC 822](http://tools.ietf.org/html/rfc822) as updated by [RFC |
23 /// 1123](http://tools.ietf.org/html/rfc1123). | 23 /// 1123](http://tools.ietf.org/html/rfc1123). |
24 String formatHttpDate(DateTime date) { | 24 String formatHttpDate(DateTime date) { |
25 date = date.toUtc(); | 25 date = date.toUtc(); |
26 var buffer = new StringBuffer() | 26 var buffer = new StringBuffer() |
27 ..write(_WEEKDAYS[date.weekday - 1]) | 27 ..write(_WEEKDAYS[date.weekday - 1]) |
28 ..write(", ") | 28 ..write(", ") |
29 ..write(date.day <= 9 ? "0" : "") | 29 ..write(date.day <= 9 ? "0" : "") |
30 ..write(date.day.toString()) | 30 ..write(date.day.toString()) |
31 ..write(" ") | 31 ..write(" ") |
32 ..write(_MONTHS[date.month - 1]) | 32 ..write(_MONTHS[date.month - 1]) |
33 ..write(" ") | 33 ..write(" ") |
34 ..write(date.year.toString()) | 34 ..write(date.year.toString()) |
35 ..write(date.hour <= 9 ? " 0" : " ") | 35 ..write(date.hour <= 9 ? " 0" : " ") |
36 ..write(date.hour.toString()) | 36 ..write(date.hour.toString()) |
37 ..write(date.minute <= 9 ? ":0" : ":") | 37 ..write(date.minute <= 9 ? ":0" : ":") |
38 ..write(date.minute.toString()) | 38 ..write(date.minute.toString()) |
39 ..write(date.second <= 9 ? ":0" : ":") | 39 ..write(date.second <= 9 ? ":0" : ":") |
40 ..write(date.second.toString()) | 40 ..write(date.second.toString()) |
41 ..write(" GMT"); | 41 ..write(" GMT"); |
42 return buffer.toString(); | 42 return buffer.toString(); |
43 } | 43 } |
44 | 44 |
45 /// Parses an HTTP-formatted date into a UTC [DateTime]. | 45 /// Parses an HTTP-formatted date into a UTC [DateTime]. |
46 /// | 46 /// |
47 /// This follows [RFC | 47 /// This follows [RFC |
48 /// 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3). It will | 48 /// 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3). It will |
49 /// throw a [FormatException] if [date] is invalid. | 49 /// throw a [FormatException] if [date] is invalid. |
50 DateTime parseHttpDate(String date) { | 50 DateTime parseHttpDate(String date) { |
51 try { | 51 try { |
(...skipping 29 matching lines...) Expand all Loading... |
81 scanner.expect(" GMT"); | 81 scanner.expect(" GMT"); |
82 scanner.expectDone(); | 82 scanner.expectDone(); |
83 | 83 |
84 return _makeDateTime(year, month, day, time); | 84 return _makeDateTime(year, month, day, time); |
85 } | 85 } |
86 | 86 |
87 // asctime follows the weekday with a space. | 87 // asctime follows the weekday with a space. |
88 scanner.expect(" "); | 88 scanner.expect(" "); |
89 var month = _parseMonth(scanner); | 89 var month = _parseMonth(scanner); |
90 scanner.expect(" "); | 90 scanner.expect(" "); |
91 var day = scanner.scan(" ") ? | 91 var day = scanner.scan(" ") ? _parseInt(scanner, 1) : _parseInt(scanner, 2); |
92 _parseInt(scanner, 1) : | |
93 _parseInt(scanner, 2); | |
94 scanner.expect(" "); | 92 scanner.expect(" "); |
95 var time = _parseTime(scanner); | 93 var time = _parseTime(scanner); |
96 scanner.expect(" "); | 94 scanner.expect(" "); |
97 var year = _parseInt(scanner, 4); | 95 var year = _parseInt(scanner, 4); |
98 scanner.expectDone(); | 96 scanner.expectDone(); |
99 | 97 |
100 return _makeDateTime(year, month, day, time); | 98 return _makeDateTime(year, month, day, time); |
101 } on FormatException catch (error) { | 99 } on FormatException catch (error) { |
102 throw new FormatException('Invalid HTTP date "$date": ${error.message}'); | 100 throw new FormatException('Invalid HTTP date "$date": ${error.message}'); |
103 } | 101 } |
(...skipping 30 matching lines...) Expand all Loading... |
134 if (seconds >= 60) scanner.error("seconds may not be greater than 60."); | 132 if (seconds >= 60) scanner.error("seconds may not be greater than 60."); |
135 | 133 |
136 return new DateTime(1, 1, 1, hours, minutes, seconds); | 134 return new DateTime(1, 1, 1, hours, minutes, seconds); |
137 } | 135 } |
138 | 136 |
139 /// Returns a UTC [DateTime] from the given components. | 137 /// Returns a UTC [DateTime] from the given components. |
140 /// | 138 /// |
141 /// Validates that [day] is a valid day for [month]. If it's not, throws a | 139 /// Validates that [day] is a valid day for [month]. If it's not, throws a |
142 /// [FormatException]. | 140 /// [FormatException]. |
143 DateTime _makeDateTime(int year, int month, int day, DateTime time) { | 141 DateTime _makeDateTime(int year, int month, int day, DateTime time) { |
144 var dateTime = new DateTime.utc( | 142 var dateTime = |
145 year, month, day, time.hour, time.minute, time.second); | 143 new DateTime.utc(year, month, day, time.hour, time.minute, time.second); |
146 | 144 |
147 // If [day] was too large, it will cause [month] to overflow. | 145 // If [day] was too large, it will cause [month] to overflow. |
148 if (dateTime.month != month) { | 146 if (dateTime.month != month) { |
149 throw new FormatException("invalid day '$day' for month '$month'."); | 147 throw new FormatException("invalid day '$day' for month '$month'."); |
150 } | 148 } |
151 return dateTime; | 149 return dateTime; |
152 } | 150 } |
OLD | NEW |