Skip to content

Commit

Permalink
Replace time with httpdate
Browse files Browse the repository at this point in the history
  • Loading branch information
quodlibetor authored and seanmonstar committed Sep 17, 2021
1 parent 2d9a5c4 commit 4bf199f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ bitflags = "1.0"
bytes = "1"
mime = "0.3.14"
sha-1 = "0.9"
time = "0.1.34"
httpdate = "1"

[features]
nightly = []
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ extern crate bitflags;
extern crate bytes;
extern crate headers_core;
extern crate http;
extern crate httpdate;
extern crate mime;
extern crate sha1;
#[cfg(all(test, feature = "nightly"))]
extern crate test;
extern crate time;

pub use headers_core::{Error, Header};

Expand Down
76 changes: 27 additions & 49 deletions src/util/http_date.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::fmt;
use std::str::FromStr;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::time::SystemTime;

use bytes::Bytes;
use http::header::HeaderValue;
use time;
use httpdate;

use super::IterExt;

Expand Down Expand Up @@ -32,7 +32,7 @@ use super::IterExt;
// HTTP-date, the sender MUST generate those timestamps in the
// IMF-fixdate format.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct HttpDate(time::Tm);
pub(crate) struct HttpDate(httpdate::HttpDate);

impl HttpDate {
pub(crate) fn from_val(val: &HeaderValue) -> Option<Self> {
Expand Down Expand Up @@ -74,96 +74,74 @@ impl<'a> From<&'a HttpDate> for HeaderValue {
impl FromStr for HttpDate {
type Err = Error;
fn from_str(s: &str) -> Result<HttpDate, Error> {
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"))
.map(HttpDate)
.map_err(|_| Error(()))
Ok(HttpDate(s.parse().map_err(|_| Error(()))?))
}
}

impl fmt::Debug for HttpDate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0.to_utc().rfc822(), f)
fmt::Display::fmt(&self.0, f)
}
}

impl fmt::Display for HttpDate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0.to_utc().rfc822(), f)
fmt::Display::fmt(&self.0, f)
}
}

impl From<SystemTime> for HttpDate {
fn from(sys: SystemTime) -> HttpDate {
let tmspec = match sys.duration_since(UNIX_EPOCH) {
Ok(dur) => {
// subsec nanos always dropped
time::Timespec::new(dur.as_secs() as i64, 0)
}
Err(err) => {
let neg = err.duration();
// subsec nanos always dropped
time::Timespec::new(-(neg.as_secs() as i64), 0)
}
};
HttpDate(time::at_utc(tmspec))
HttpDate(sys.into())
}
}

impl From<HttpDate> for SystemTime {
fn from(date: HttpDate) -> SystemTime {
let spec = date.0.to_timespec();
if spec.sec >= 0 {
UNIX_EPOCH + Duration::new(spec.sec as u64, spec.nsec as u32)
} else {
UNIX_EPOCH - Duration::new(spec.sec as u64, spec.nsec as u32)
}
SystemTime::from(date.0)
}
}

#[cfg(test)]
mod tests {
use super::HttpDate;
use time::Tm;

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,
});

use std::time::{Duration, UNIX_EPOCH};

// The old tests had Sunday, but 1994-11-07 is a Monday.
// See https://github.com/pyfisch/httpdate/pull/6#issuecomment-846881001
fn nov_07() -> HttpDate {
HttpDate((UNIX_EPOCH + Duration::new(784198117, 0)).into())
}

#[test]
fn test_display_is_imf_fixdate() {
assert_eq!("Mon, 07 Nov 1994 08:48:37 GMT", &nov_07().to_string());
}

#[test]
fn test_imf_fixdate() {
assert_eq!(
"Sun, 07 Nov 1994 08:48:37 GMT".parse::<HttpDate>().unwrap(),
NOV_07
"Mon, 07 Nov 1994 08:48:37 GMT".parse::<HttpDate>().unwrap(),
nov_07()
);
}

#[test]
fn test_rfc_850() {
assert_eq!(
"Sunday, 07-Nov-94 08:48:37 GMT"
"Monday, 07-Nov-94 08:48:37 GMT"
.parse::<HttpDate>()
.unwrap(),
NOV_07
nov_07()
);
}

#[test]
fn test_asctime() {
assert_eq!(
"Sun Nov 7 08:48:37 1994".parse::<HttpDate>().unwrap(),
NOV_07
"Mon Nov 7 08:48:37 1994".parse::<HttpDate>().unwrap(),
nov_07()
);
}

Expand Down

0 comments on commit 4bf199f

Please sign in to comment.