feat(headers): add Expires header
This commit is contained in:
		| @@ -1,8 +1,8 @@ | |||||||
| use header::{Header, HeaderFormat}; |  | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{mod, Show}; | ||||||
| use super::util::from_one_raw_str; |  | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use time::{Tm, strptime}; | use time::Tm; | ||||||
|  | use header::{Header, HeaderFormat}; | ||||||
|  | use super::util::{from_one_raw_str, tm_from_str}; | ||||||
|  |  | ||||||
| // Egh, replace as soon as something better than time::Tm exists. | // Egh, replace as soon as something better than time::Tm exists. | ||||||
| /// The `Date` header field. | /// The `Date` header field. | ||||||
| @@ -21,17 +21,10 @@ impl Header for Date { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| impl HeaderFormat for Date { | impl HeaderFormat for Date { | ||||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||||
|         self.fmt(fmt) |         let tm = **self; | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl fmt::Show for Date { |  | ||||||
|     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |  | ||||||
|         let Date(ref tm) = *self; |  | ||||||
|         // bummer that tm.strftime allocates a string. It would nice if it |  | ||||||
|         // returned a Show instead, since I don't need the String here |  | ||||||
|         match tm.tm_utcoff { |         match tm.tm_utcoff { | ||||||
|             0 => tm.rfc822().fmt(fmt), |             0 => tm.rfc822().fmt(fmt), | ||||||
|             _ => tm.to_utc().rfc822().fmt(fmt) |             _ => tm.to_utc().rfc822().fmt(fmt) | ||||||
| @@ -40,34 +33,8 @@ impl fmt::Show for Date { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl FromStr for Date { | impl FromStr for Date { | ||||||
|     //    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. |  | ||||||
|     fn from_str(s: &str) -> Option<Date> { |     fn from_str(s: &str) -> Option<Date> { | ||||||
|         strptime(s, "%a, %d %b %Y %T %Z").or_else(|_| { |         tm_from_str(s).map(Date) | ||||||
|             strptime(s, "%A, %d-%b-%y %T %Z") |  | ||||||
|         }).or_else(|_| { |  | ||||||
|             strptime(s, "%c") |  | ||||||
|         }).ok().map(|tm| Date(tm)) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								src/header/common/expires.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/header/common/expires.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | use std::fmt::{mod, Show}; | ||||||
|  | use std::str::FromStr; | ||||||
|  | use time::Tm; | ||||||
|  | use header::{Header, HeaderFormat}; | ||||||
|  | use super::util::{from_one_raw_str, tm_from_str}; | ||||||
|  |  | ||||||
|  | /// The `Expires` header field. | ||||||
|  | #[deriving(PartialEq, Clone)] | ||||||
|  | pub struct Expires(pub Tm); | ||||||
|  |  | ||||||
|  | deref!(Expires -> Tm) | ||||||
|  |  | ||||||
|  | impl Header for Expires { | ||||||
|  |     fn header_name(_: Option<Expires>) -> &'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; | ||||||
|  |         match tm.tm_utcoff { | ||||||
|  |             0 => tm.rfc822().fmt(fmt), | ||||||
|  |             _ => tm.to_utc().rfc822().fmt(fmt) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl FromStr for Expires { | ||||||
|  |     fn from_str(s: &str) -> Option<Expires> { | ||||||
|  |         tm_from_str(s).map(Expires) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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!(asctime, Expires, { vec![b"Sun Nov  6 08:49:37 1994".to_vec()] }) | ||||||
| @@ -96,6 +96,9 @@ pub mod content_type; | |||||||
| /// Exposes the Date header. | /// Exposes the Date header. | ||||||
| pub mod date; | pub mod date; | ||||||
|  |  | ||||||
|  | /// Exposes the Expires header. | ||||||
|  | pub mod expires; | ||||||
|  |  | ||||||
| /// Exposes the Host header. | /// Exposes the Host header. | ||||||
| pub mod host; | pub mod host; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| use std::str::{FromStr, from_utf8}; | use std::str::{FromStr, from_utf8}; | ||||||
| use std::fmt::{mod, Show}; | use std::fmt::{mod, Show}; | ||||||
|  | use time::{Tm, strptime}; | ||||||
|  |  | ||||||
| /// 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: FromStr>(raw: &[Vec<u8>]) -> Option<T> { | pub fn from_one_raw_str<T: FromStr>(raw: &[Vec<u8>]) -> Option<T> { | ||||||
| @@ -43,3 +44,34 @@ pub fn fmt_comma_delimited<T: Show>(fmt: &mut fmt::Formatter, parts: &[T]) -> fm | |||||||
|     } |     } | ||||||
|     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<Tm> { | ||||||
|  |     strptime(s, "%a, %d %b %Y %T %Z").or_else(|_| { | ||||||
|  |         strptime(s, "%A, %d-%b-%y %T %Z") | ||||||
|  |     }).or_else(|_| { | ||||||
|  |         strptime(s, "%c") | ||||||
|  |     }).ok() | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user