refactor(header): Implement HttpDate, a wrapper for dates
				
					
				
			Using `time::Tm` directly in HTTP header fields requires special handling to parse and format the header values., this stops us from using the header macros. By wrapping `time::Time` in a `HttpDate`, we can use the `FromStr` and `Display` traits of `HttpDate` like for most other values. BREAKING_CHANGE: All code using one of the `Date`, `Expires`, `If-Modified-Since`, `If-Unmodified-Since`, `Last-Modified` header fields needs to wrap `time::Tm` with `HttpDate`. Removed `FromStr` trait of `Date`, `If-Modified-Sice` and `If-Unmodified-Sice`, implementing the trait here is inconsistent with other headers.
This commit is contained in:
		| @@ -1,45 +1,10 @@ | |||||||
| use std::fmt; | use header::HttpDate; | ||||||
| use std::str::FromStr; |  | ||||||
| use time::Tm; |  | ||||||
| use header::{Header, HeaderFormat}; |  | ||||||
| use header::parsing::from_one_raw_str; |  | ||||||
| use header::parsing::tm_from_str; |  | ||||||
|  |  | ||||||
| // Egh, replace as soon as something better than time::Tm exists. |  | ||||||
| /// The `Date` header field. | /// The `Date` header field. | ||||||
| #[derive(Copy, PartialEq, Clone, Debug)] | #[derive(Copy, PartialEq, Clone, Debug)] | ||||||
| pub struct Date(pub Tm); | pub struct Date(pub HttpDate); | ||||||
|  |  | ||||||
| deref!(Date => Tm); | impl_header!(Date, "Date", HttpDate); | ||||||
|  |  | ||||||
| impl Header for Date { |  | ||||||
|     fn header_name() -> &'static str { |  | ||||||
|         "Date" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Date> { |  | ||||||
|         from_one_raw_str(raw) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| impl HeaderFormat for Date { |  | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         let tm = self.0; |  | ||||||
|         let tm = match tm.tm_utcoff { |  | ||||||
|             0 => tm, |  | ||||||
|             _ => tm.to_utc(), |  | ||||||
|         }; |  | ||||||
|         fmt::Display::fmt(&tm.rfc822(), fmt) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl FromStr for Date { |  | ||||||
|     type Err = (); |  | ||||||
|     fn from_str(s: &str) -> Result<Date, ()> { |  | ||||||
|         tm_from_str(s).map(Date).ok_or(()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bench_header!(imf_fixdate, Date, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | bench_header!(imf_fixdate, Date, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | ||||||
| bench_header!(rfc_850, Date, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | bench_header!(rfc_850, Date, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | ||||||
|   | |||||||
| @@ -1,44 +1,9 @@ | |||||||
| use std::fmt; | use header::HttpDate; | ||||||
| use std::str::FromStr; |  | ||||||
| use time::Tm; |  | ||||||
| use header::{Header, HeaderFormat}; |  | ||||||
| use header::parsing::from_one_raw_str; |  | ||||||
| use header::parsing::tm_from_str; |  | ||||||
|  |  | ||||||
| /// The `Expires` header field. | /// The `Expires` header field. | ||||||
| #[derive(Copy, PartialEq, Clone, Debug)] | #[derive(Copy, PartialEq, Clone, Debug)] | ||||||
| pub struct Expires(pub Tm); | pub struct Expires(pub HttpDate); | ||||||
|  | impl_header!(Expires, "Expires", HttpDate); | ||||||
| deref!(Expires => Tm); |  | ||||||
|  |  | ||||||
| impl Header for Expires { |  | ||||||
|     fn header_name() -> &'static str { |  | ||||||
|         "Expires" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Expires> { |  | ||||||
|         from_one_raw_str(raw) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| impl HeaderFormat for Expires { |  | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         let tm = self.0; |  | ||||||
|         let tm = match tm.tm_utcoff { |  | ||||||
|             0 => tm, |  | ||||||
|             _ => tm.to_utc(), |  | ||||||
|         }; |  | ||||||
|         fmt::Display::fmt(&tm.rfc822(), fmt) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl FromStr for Expires { |  | ||||||
|     type Err = (); |  | ||||||
|     fn from_str(s: &str) -> Result<Expires, ()> { |  | ||||||
|         tm_from_str(s).map(Expires).ok_or(()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bench_header!(imf_fixdate, Expires, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | bench_header!(imf_fixdate, Expires, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | ||||||
| bench_header!(rfc_850, Expires, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | bench_header!(rfc_850, Expires, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | ||||||
|   | |||||||
| @@ -1,44 +1,9 @@ | |||||||
| use std::fmt; | use header::HttpDate; | ||||||
| use std::str::FromStr; |  | ||||||
| use time::Tm; |  | ||||||
| use header::{Header, HeaderFormat}; |  | ||||||
| use header::parsing::from_one_raw_str; |  | ||||||
| use header::parsing::tm_from_str; |  | ||||||
|  |  | ||||||
| /// The `If-Modified-Since` header field. | /// The `If-Modified-Since` header field. | ||||||
| #[derive(Copy, PartialEq, Clone, Debug)] | #[derive(Copy, PartialEq, Clone, Debug)] | ||||||
| pub struct IfModifiedSince(pub Tm); | pub struct IfModifiedSince(pub HttpDate); | ||||||
|  | impl_header!(IfModifiedSince, "If-Modified-Since", HttpDate); | ||||||
| deref!(IfModifiedSince => Tm); |  | ||||||
|  |  | ||||||
| impl Header for IfModifiedSince { |  | ||||||
|     fn header_name() -> &'static str { |  | ||||||
|         "If-Modified-Since" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<IfModifiedSince> { |  | ||||||
|         from_one_raw_str(raw) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| impl HeaderFormat for IfModifiedSince { |  | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         let tm = self.0; |  | ||||||
|         let tm = match tm.tm_utcoff { |  | ||||||
|             0 => tm, |  | ||||||
|             _ => tm.to_utc(), |  | ||||||
|         }; |  | ||||||
|         fmt::Display::fmt(&tm.rfc822(), fmt) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl FromStr for IfModifiedSince { |  | ||||||
|     type Err = (); |  | ||||||
|     fn from_str(s: &str) -> Result<IfModifiedSince, ()> { |  | ||||||
|         tm_from_str(s).map(IfModifiedSince).ok_or(()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bench_header!(imf_fixdate, IfModifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | bench_header!(imf_fixdate, IfModifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | ||||||
| bench_header!(rfc_850, IfModifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | bench_header!(rfc_850, IfModifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | ||||||
|   | |||||||
| @@ -1,44 +1,10 @@ | |||||||
| use std::fmt; | use header::HttpDate; | ||||||
| use std::str::FromStr; |  | ||||||
| use time::Tm; |  | ||||||
| use header::{Header, HeaderFormat}; |  | ||||||
| use header::parsing::from_one_raw_str; |  | ||||||
| use header::parsing::tm_from_str; |  | ||||||
|  |  | ||||||
| /// The `If-Unmodified-Since` header field. | /// The `If-Unmodified-Since` header field. | ||||||
| #[derive(Copy, PartialEq, Clone, Debug)] | #[derive(Copy, PartialEq, Clone, Debug)] | ||||||
| pub struct IfUnmodifiedSince(pub Tm); | pub struct IfUnmodifiedSince(pub HttpDate); | ||||||
|  |  | ||||||
| deref!(IfUnmodifiedSince => Tm); | impl_header!(IfUnmodifiedSince, "If-Unmodified-Since", HttpDate); | ||||||
|  |  | ||||||
| impl Header for IfUnmodifiedSince { |  | ||||||
|     fn header_name() -> &'static str { |  | ||||||
|         "If-Unmodified-Since" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<IfUnmodifiedSince> { |  | ||||||
|         from_one_raw_str(raw) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| impl HeaderFormat for IfUnmodifiedSince { |  | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         let tm = self.0; |  | ||||||
|         let tm = match tm.tm_utcoff { |  | ||||||
|             0 => tm, |  | ||||||
|             _ => tm.to_utc(), |  | ||||||
|         }; |  | ||||||
|         fmt::Display::fmt(&tm.rfc822(), fmt) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl FromStr for IfUnmodifiedSince { |  | ||||||
|     type Err = (); |  | ||||||
|     fn from_str(s: &str) -> Result<IfUnmodifiedSince, ()> { |  | ||||||
|         tm_from_str(s).map(IfUnmodifiedSince).ok_or(()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bench_header!(imf_fixdate, IfUnmodifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | bench_header!(imf_fixdate, IfUnmodifiedSince, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | ||||||
| bench_header!(rfc_850, IfUnmodifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | bench_header!(rfc_850, IfUnmodifiedSince, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | ||||||
|   | |||||||
| @@ -1,44 +1,10 @@ | |||||||
| use std::fmt; | use header::HttpDate; | ||||||
| use std::str::FromStr; |  | ||||||
| use time::Tm; |  | ||||||
| use header::{Header, HeaderFormat}; |  | ||||||
| use header::parsing::from_one_raw_str; |  | ||||||
| use header::parsing::tm_from_str; |  | ||||||
|  |  | ||||||
| /// The `LastModified` header field. | /// The `LastModified` header field. | ||||||
| #[derive(Copy, PartialEq, Clone, Debug)] | #[derive(Copy, PartialEq, Clone, Debug)] | ||||||
| pub struct LastModified(pub Tm); | pub struct LastModified(pub HttpDate); | ||||||
|  |  | ||||||
| deref!(LastModified => Tm); | impl_header!(LastModified, "Last-Modified", HttpDate); | ||||||
|  |  | ||||||
| impl Header for LastModified { |  | ||||||
|     fn header_name() -> &'static str { |  | ||||||
|         "Last-Modified" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<LastModified> { |  | ||||||
|         from_one_raw_str(raw) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| impl HeaderFormat for LastModified { |  | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         let tm = self.0; |  | ||||||
|         let tm = match tm.tm_utcoff { |  | ||||||
|             0 => tm, |  | ||||||
|             _ => tm.to_utc(), |  | ||||||
|         }; |  | ||||||
|         fmt::Display::fmt(&tm.rfc822(), fmt) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl FromStr for LastModified { |  | ||||||
|     type Err = (); |  | ||||||
|     fn from_str(s: &str) -> Result<LastModified, ()> { |  | ||||||
|         tm_from_str(s).map(LastModified).ok_or(()) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bench_header!(imf_fixdate, LastModified, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | bench_header!(imf_fixdate, LastModified, { vec![b"Sun, 07 Nov 1994 08:48:37 GMT".to_vec()] }); | ||||||
| bench_header!(rfc_850, LastModified, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | bench_header!(rfc_850, LastModified, { vec![b"Sunday, 06-Nov-94 08:49:37 GMT".to_vec()] }); | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ use unicase::UniCase; | |||||||
| use self::internals::Item; | use self::internals::Item; | ||||||
| use error::HttpResult; | use error::HttpResult; | ||||||
|  |  | ||||||
| pub use self::shared::{Charset, Encoding, EntityTag, Quality, QualityItem, qitem, q}; | pub use self::shared::{Charset, Encoding, EntityTag, HttpDate, Quality, QualityItem, qitem, q}; | ||||||
| pub use self::common::*; | pub use self::common::*; | ||||||
|  |  | ||||||
| mod common; | mod common; | ||||||
|   | |||||||
| @@ -2,7 +2,6 @@ | |||||||
|  |  | ||||||
| use std::str; | use std::str; | ||||||
| use std::fmt; | use std::fmt; | ||||||
| use time; |  | ||||||
|  |  | ||||||
| /// Reads a single raw string when parsing a header | /// Reads a single raw string when parsing a header | ||||||
| pub fn from_one_raw_str<T: str::FromStr>(raw: &[Vec<u8>]) -> Option<T> { | pub fn from_one_raw_str<T: str::FromStr>(raw: &[Vec<u8>]) -> Option<T> { | ||||||
| @@ -51,74 +50,3 @@ pub fn fmt_comma_delimited<T: fmt::Display>(fmt: &mut fmt::Formatter, parts: &[T | |||||||
|     } |     } | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Get a Tm from HTTP date formats. |  | ||||||
| //    Prior to 1995, there were three different formats commonly used by |  | ||||||
| //   servers to communicate timestamps.  For compatibility with old |  | ||||||
| //   implementations, all three are defined here.  The preferred format is |  | ||||||
| //   a fixed-length and single-zone subset of the date and time |  | ||||||
| //   specification used by the Internet Message Format [RFC5322]. |  | ||||||
| // |  | ||||||
| //     HTTP-date    = IMF-fixdate / obs-date |  | ||||||
| // |  | ||||||
| //   An example of the preferred format is |  | ||||||
| // |  | ||||||
| //     Sun, 06 Nov 1994 08:49:37 GMT    ; IMF-fixdate |  | ||||||
| // |  | ||||||
| //   Examples of the two obsolete formats are |  | ||||||
| // |  | ||||||
| //     Sunday, 06-Nov-94 08:49:37 GMT   ; obsolete RFC 850 format |  | ||||||
| //     Sun Nov  6 08:49:37 1994         ; ANSI C's asctime() format |  | ||||||
| // |  | ||||||
| //   A recipient that parses a timestamp value in an HTTP header field |  | ||||||
| //   MUST accept all three HTTP-date formats.  When a sender generates a |  | ||||||
| //   header field that contains one or more timestamps defined as |  | ||||||
| //   HTTP-date, the sender MUST generate those timestamps in the |  | ||||||
| //   IMF-fixdate format. |  | ||||||
| pub fn tm_from_str(s: &str) -> Option<time::Tm> { |  | ||||||
|     time::strptime(s, "%a, %d %b %Y %T %Z").or_else(|_| { |  | ||||||
|         time::strptime(s, "%A, %d-%b-%y %T %Z") |  | ||||||
|     }).or_else(|_| { |  | ||||||
|         time::strptime(s, "%c") |  | ||||||
|     }).ok() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(test)] |  | ||||||
| mod tests { |  | ||||||
|     use time::Tm; |  | ||||||
|     use super::tm_from_str; |  | ||||||
|  |  | ||||||
|     const NOV_07: Tm = Tm { |  | ||||||
|         tm_nsec: 0, |  | ||||||
|         tm_sec: 37, |  | ||||||
|         tm_min: 48, |  | ||||||
|         tm_hour: 8, |  | ||||||
|         tm_mday: 7, |  | ||||||
|         tm_mon: 10, |  | ||||||
|         tm_year: 94, |  | ||||||
|         tm_wday: 0, |  | ||||||
|         tm_isdst: 0, |  | ||||||
|         tm_yday: 0, |  | ||||||
|         tm_utcoff: 0, |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_imf_fixdate() { |  | ||||||
|         assert_eq!(tm_from_str("Sun, 07 Nov 1994 08:48:37 GMT"), |  | ||||||
|                    Some(NOV_07)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_rfc_850() { |  | ||||||
|         assert_eq!(tm_from_str("Sunday, 07-Nov-94 08:48:37 GMT"), |  | ||||||
|                    Some(NOV_07)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_asctime() { |  | ||||||
|         assert_eq!(tm_from_str("Sun Nov  7 08:48:37 1994"), |  | ||||||
|                    Some(NOV_07)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										91
									
								
								src/header/shared/httpdate.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/header/shared/httpdate.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  | use std::str::FromStr; | ||||||
|  | use std::fmt::{self, Display}; | ||||||
|  |  | ||||||
|  | use time; | ||||||
|  |  | ||||||
|  | /// A `time::Time` with HTTP formatting and parsing | ||||||
|  | /// | ||||||
|  | //   Prior to 1995, there were three different formats commonly used by | ||||||
|  | //   servers to communicate timestamps.  For compatibility with old | ||||||
|  | //   implementations, all three are defined here.  The preferred format is | ||||||
|  | //   a fixed-length and single-zone subset of the date and time | ||||||
|  | //   specification used by the Internet Message Format [RFC5322]. | ||||||
|  | // | ||||||
|  | //     HTTP-date    = IMF-fixdate / obs-date | ||||||
|  | // | ||||||
|  | //   An example of the preferred format is | ||||||
|  | // | ||||||
|  | //     Sun, 06 Nov 1994 08:49:37 GMT    ; IMF-fixdate | ||||||
|  | // | ||||||
|  | //   Examples of the two obsolete formats are | ||||||
|  | // | ||||||
|  | //     Sunday, 06-Nov-94 08:49:37 GMT   ; obsolete RFC 850 format | ||||||
|  | //     Sun Nov  6 08:49:37 1994         ; ANSI C's asctime() format | ||||||
|  | // | ||||||
|  | //   A recipient that parses a timestamp value in an HTTP header field | ||||||
|  | //   MUST accept all three HTTP-date formats.  When a sender generates a | ||||||
|  | //   header field that contains one or more timestamps defined as | ||||||
|  | //   HTTP-date, the sender MUST generate those timestamps in the | ||||||
|  | //   IMF-fixdate format. | ||||||
|  | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] | ||||||
|  | pub struct HttpDate(pub time::Tm); | ||||||
|  |  | ||||||
|  | impl FromStr for HttpDate { | ||||||
|  |     type Err = (); | ||||||
|  |     fn from_str(s: &str) -> Result<Self, ()> { | ||||||
|  |         match time::strptime(s, "%a, %d %b %Y %T %Z").or_else(|_| { | ||||||
|  |             time::strptime(s, "%A, %d-%b-%y %T %Z") | ||||||
|  |             }).or_else(|_| { | ||||||
|  |                 time::strptime(s, "%c") | ||||||
|  |                 }) { | ||||||
|  |                     Ok(t) => Ok(HttpDate(t)), | ||||||
|  |                     Err(_) => Err(()), | ||||||
|  |                     } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl Display for HttpDate { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         let tm = self.0; | ||||||
|  |         let tm = match tm.tm_utcoff { | ||||||
|  |             0 => tm, | ||||||
|  |             _ => tm.to_utc(), | ||||||
|  |         }; | ||||||
|  |         fmt::Display::fmt(&tm.rfc822(), f) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use time::Tm; | ||||||
|  |     use super::HttpDate; | ||||||
|  |  | ||||||
|  |     const NOV_07: HttpDate = HttpDate(Tm { | ||||||
|  |         tm_nsec: 0, | ||||||
|  |         tm_sec: 37, | ||||||
|  |         tm_min: 48, | ||||||
|  |         tm_hour: 8, | ||||||
|  |         tm_mday: 7, | ||||||
|  |         tm_mon: 10, | ||||||
|  |         tm_year: 94, | ||||||
|  |         tm_wday: 0, | ||||||
|  |         tm_isdst: 0, | ||||||
|  |         tm_yday: 0, | ||||||
|  |         tm_utcoff: 0, | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_imf_fixdate() { | ||||||
|  |         assert_eq!("Sun, 07 Nov 1994 08:48:37 GMT".parse(), Ok(NOV_07)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_rfc_850() { | ||||||
|  |         assert_eq!("Sunday, 07-Nov-94 08:48:37 GMT".parse(), Ok(NOV_07)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_asctime() { | ||||||
|  |         assert_eq!("Sun Nov  7 08:48:37 1994".parse(), Ok(NOV_07)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,9 +1,11 @@ | |||||||
| pub use self::charset::Charset; | pub use self::charset::Charset; | ||||||
| pub use self::encoding::Encoding; | pub use self::encoding::Encoding; | ||||||
| pub use self::entity::EntityTag; | pub use self::entity::EntityTag; | ||||||
|  | pub use self::httpdate::HttpDate; | ||||||
| pub use self::quality_item::{Quality, QualityItem, qitem, q}; | pub use self::quality_item::{Quality, QualityItem, qitem, q}; | ||||||
|  |  | ||||||
| mod charset; | mod charset; | ||||||
| mod encoding; | mod encoding; | ||||||
| mod entity; | mod entity; | ||||||
|  | mod httpdate; | ||||||
| mod quality_item; | mod quality_item; | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ impl<'a> Response<'a, Fresh> { | |||||||
|         try!(write!(&mut self.body, "{} {}{}{}", self.version, self.status, CR as char, LF as char)); |         try!(write!(&mut self.body, "{} {}{}{}", self.version, self.status, CR as char, LF as char)); | ||||||
|  |  | ||||||
|         if !self.headers.has::<header::Date>() { |         if !self.headers.has::<header::Date>() { | ||||||
|             self.headers.set(header::Date(now_utc())); |             self.headers.set(header::Date(header::HttpDate(now_utc()))); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user