mirror of
https://github.com/fafhrd91/actix-web
synced 2025-06-25 22:49:21 +02:00
Upgrade time
to 0.2.5 (#1254)
* Use `OffsetDateTime` instead of `PrimitiveDateTime` * Parse time strings with `PrimitiveDateTime::parse` instead of `OffsetDateTime::parse` * Remove unused `time` dependency from actix-multipart * Fix a few errors with time related tests from the `time` upgrade * Implement logic to convert a RFC 850 two-digit year into a full length year, and organize time parsing related functions * Upgrade `time` to 0.2.2 * Correctly parse C's asctime time format using time 0.2's new format patterns * Update CHANGES.md * Use `time` without any of its deprecated functions * Enforce a UTC time offset when converting an `OffsetDateTime` into a Header value * Use the more readable version of `Duration::seconds(0)`, `Duration::zero()` * Remove unneeded conversion of time::Duration to std::time::Duration * Use `OffsetDateTime::as_seconds_f64` instead of manually calculating the amount of seconds from nanoseconds * Replace a few additional instances of `Duration::seconds(0)` with `Duration::zero()` * Truncate any nanoseconds from a supplied `Duration` within `Cookie::set_max_age` to ensure two Cookies with the same amount whole seconds equate to one another * Fix the actix-http:🍪:do_not_panic_on_large_max_ages test * Convert `Cookie::max_age` and `Cookie::expires` examples to `time` 0.2 Mainly minor changes. Type inference can be used alongside the new `time::parse` method, such that the type doesn't need to be specified. This will be useful if a refactoring takes place that changes the type. There are also new macros, which are used where possible. One change that is not immediately obvious, in `HttpDate`, there was an unnecessary conditional. As the time crate allows for negative durations (and can perform arithmetic with such), the if/else can be removed entirely. Time v0.2.3 also has some bug fixes, which is why I am not using a more general v0.2 in Cargo.toml. v0.2.3 has been yanked, as it was backwards imcompatible. This version reverts the breaking change, while still supporting rustc back to 1.34.0. * Add missing `time::offset` macro import * Fix type confusion when using `time::parse` followed by `using_offset` * Update `time` to 0.2.5 * Update CHANGES.md Co-authored-by: Jacob Pratt <the.z.cuber@gmail.com>
This commit is contained in:
@ -1,59 +1,46 @@
|
||||
use std::fmt::{self, Display};
|
||||
use std::io::Write;
|
||||
use std::str::FromStr;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use bytes::{buf::BufMutExt, BytesMut};
|
||||
use http::header::{HeaderValue, InvalidHeaderValue};
|
||||
use time::{PrimitiveDateTime, OffsetDateTime, offset};
|
||||
|
||||
use crate::error::ParseError;
|
||||
use crate::header::IntoHeaderValue;
|
||||
use crate::time_parser;
|
||||
|
||||
/// A timestamp with HTTP formatting and parsing
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct HttpDate(time::Tm);
|
||||
pub struct HttpDate(OffsetDateTime);
|
||||
|
||||
impl FromStr for HttpDate {
|
||||
type Err = ParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<HttpDate, ParseError> {
|
||||
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(ParseError::Header),
|
||||
match time_parser::parse_http_date(s) {
|
||||
Some(t) => Ok(HttpDate(t.using_offset(offset!(UTC)))),
|
||||
None => Err(ParseError::Header)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl 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.format("%a, %d %b %Y %H:%M:%S GMT"), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<time::Tm> for HttpDate {
|
||||
fn from(tm: time::Tm) -> HttpDate {
|
||||
HttpDate(tm)
|
||||
impl From<OffsetDateTime> for HttpDate {
|
||||
fn from(dt: OffsetDateTime) -> HttpDate {
|
||||
HttpDate(dt)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SystemTime> for HttpDate {
|
||||
fn from(sys: SystemTime) -> HttpDate {
|
||||
let tmspec = match sys.duration_since(UNIX_EPOCH) {
|
||||
Ok(dur) => {
|
||||
time::Timespec::new(dur.as_secs() as i64, dur.subsec_nanos() as i32)
|
||||
}
|
||||
Err(err) => {
|
||||
let neg = err.duration();
|
||||
time::Timespec::new(
|
||||
-(neg.as_secs() as i64),
|
||||
-(neg.subsec_nanos() as i32),
|
||||
)
|
||||
}
|
||||
};
|
||||
HttpDate(time::at_utc(tmspec))
|
||||
HttpDate(PrimitiveDateTime::from(sys).using_offset(offset!(UTC)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,56 +49,45 @@ impl IntoHeaderValue for HttpDate {
|
||||
|
||||
fn try_into(self) -> Result<HeaderValue, Self::Error> {
|
||||
let mut wrt = BytesMut::with_capacity(29).writer();
|
||||
write!(wrt, "{}", self.0.rfc822()).unwrap();
|
||||
write!(wrt, "{}", self.0.to_offset(offset!(UTC)).format("%a, %d %b %Y %H:%M:%S GMT")).unwrap();
|
||||
HeaderValue::from_maybe_shared(wrt.get_mut().split().freeze())
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
let dt = date.0;
|
||||
let epoch = OffsetDateTime::unix_epoch();
|
||||
|
||||
UNIX_EPOCH + (dt - epoch)
|
||||
}
|
||||
}
|
||||
|
||||
#[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 time::{PrimitiveDateTime, date, time, offset};
|
||||
|
||||
#[test]
|
||||
fn test_date() {
|
||||
let nov_07 = HttpDate(PrimitiveDateTime::new(
|
||||
date!(1994-11-07),
|
||||
time!(8:48:37)
|
||||
).using_offset(offset!(UTC)));
|
||||
|
||||
assert_eq!(
|
||||
"Sun, 07 Nov 1994 08:48:37 GMT".parse::<HttpDate>().unwrap(),
|
||||
NOV_07
|
||||
nov_07
|
||||
);
|
||||
assert_eq!(
|
||||
"Sunday, 07-Nov-94 08:48:37 GMT"
|
||||
.parse::<HttpDate>()
|
||||
.unwrap(),
|
||||
NOV_07
|
||||
nov_07
|
||||
);
|
||||
assert_eq!(
|
||||
"Sun Nov 7 08:48:37 1994".parse::<HttpDate>().unwrap(),
|
||||
NOV_07
|
||||
nov_07
|
||||
);
|
||||
assert!("this-is-no-date".parse::<HttpDate>().is_err());
|
||||
}
|
||||
|
Reference in New Issue
Block a user