diff --git a/ohkami/Cargo.toml b/ohkami/Cargo.toml index 209ae068..a76e563e 100644 --- a/ohkami/Cargo.toml +++ b/ohkami/Cargo.toml @@ -58,8 +58,8 @@ DEBUG = [ # "testing", # "nightly", # #"websocket", -# "rt_tokio", +# #"rt_tokio", # #"rt_async-std", -# #"rt_worker", +# "rt_worker", # "DEBUG", #] \ No newline at end of file diff --git a/ohkami/src/lib.rs b/ohkami/src/lib.rs index 104423cd..54dc2da9 100644 --- a/ohkami/src/lib.rs +++ b/ohkami/src/lib.rs @@ -95,7 +95,34 @@ pub mod testing; pub mod utils { pub use crate::fangs::util::FangAction; - pub use ::ohkami_lib::unix_timestamp; + + #[cfg(not(feature="rt_worker"))] + /// ``` + /// # let _ = + /// { + /// std::time::SystemTime::now() + /// .duration_since(std::time::UNIX_EPOCH) + /// .unwrap() + /// .as_secs() + /// } + /// # ; + /// ``` + #[inline] pub fn unix_timestamp() -> u64 { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs() + } + + #[cfg(feature="rt_worker")] + /// ```ignore + /// { + /// JS's `Date.now() / 1000` as Rust's u64 + /// } + /// ``` + #[inline] pub fn unix_timestamp() -> u64 { + (worker::js_sys::Date::now() / 1000.) as _ + } } // #[cfg(feature="websocket")] diff --git a/ohkami/src/ohkami/mod.rs b/ohkami/src/ohkami/mod.rs index 0ceee00b..26d77205 100644 --- a/ohkami/src/ohkami/mod.rs +++ b/ohkami/src/ohkami/mod.rs @@ -15,7 +15,7 @@ use router::TrieRouter; #[cfg(any(feature="rt_tokio",feature="rt_async-std"))] use crate::{__rt__, Session}; #[cfg(feature="rt_async-std")] use crate::__rt__::StreamExt as _; -#[cfg(feature="websocket")] use crate::websocket::reserve_upgrade; +// #[cfg(feature="websocket")] use crate::websocket::reserve_upgrade; /// # Ohkami - a robust wolf who serves your web app @@ -326,7 +326,9 @@ impl Ohkami { let router = router.into_radix(); #[cfg(feature="DEBUG")] ::worker::console_debug!("Done `TrieRouter::into_radix` (without compressions)"); - router.handle(&mut ohkami_req).await + let mut res = router.handle(&mut ohkami_req).await; + res.complete(); + res } Err(e) => {#[cfg(feature="DEBUG")] ::worker::console_debug!("`take_over` returned an error response: {e:?}"); e diff --git a/ohkami/src/request/_test_parse.rs b/ohkami/src/request/_test_parse.rs index 5b6fe7ff..c2b22b8d 100644 --- a/ohkami/src/request/_test_parse.rs +++ b/ohkami/src/request/_test_parse.rs @@ -94,10 +94,9 @@ fn metadataize(input: &str) -> Box<[u8; BUF_SIZE]> { payload: Some(CowSlice::Ref(Slice::from_bytes( br#"{"name":"kanarus","age":20}"# ))), - store: Store::init(), + store: Store::init(), }); - #[cfg(feature="custom-header")] { const CASE_3: &str = "\ POST /foo.php?query=1&q2=xxx HTTP/1.1\r\n\ @@ -119,10 +118,10 @@ fn metadataize(input: &str) -> Box<[u8; BUF_SIZE]> { __buf__: metadataize(CASE_3), method: Method::POST, path: Path::from_literal("/foo.php"), - query: Some(Box::new(QueryParams::from([ + query: Some(QueryParams::from([ ("query", "1"), ("q2", "xxx"), - ]))), + ])), headers: RequestHeaders::from_iters( [ (RequestHeader::Host, "localhost"), @@ -139,9 +138,9 @@ fn metadataize(input: &str) -> Box<[u8; BUF_SIZE]> { ("X-Request-Id", "300"), ] ), - payload: Some(CowSlice::Own(Vec::from("first_name=John&last_name=Doe&action=Submit"))), + payload: Some(CowSlice::Own(Vec::from("first_name=John&last_name=Doe&action=Submit").into())), store: Store::init(), - #[cfg(feature="websocket")] upgrade_id: None, + // #[cfg(feature="websocket")] upgrade_id: None, }); } } diff --git a/ohkami/src/response/_test.rs b/ohkami/src/response/_test.rs index 6cf1eb44..58c34dcb 100644 --- a/ohkami/src/response/_test.rs +++ b/ohkami/src/response/_test.rs @@ -22,7 +22,9 @@ async fn test_response_into_bytes() { }; } - let __now__ = ohkami_lib::imf_fixdate_now(); + let __now__ = ::ohkami_lib::imf_fixdate( + std::time::Duration::from_secs(crate::utils::unix_timestamp()) + ); let res = Response::NoContent(); let res_bytes = res.into_bytes(); diff --git a/ohkami/src/response/mod.rs b/ohkami/src/response/mod.rs index 2eb7ec05..7429c380 100644 --- a/ohkami/src/response/mod.rs +++ b/ohkami/src/response/mod.rs @@ -118,10 +118,10 @@ pub struct Response { impl Response { /// Complete HTTP spec #[inline(always)] - fn complete(&mut self) { - /* `wasm32-unkown-unkown` target doesn't support `time` */ - #[cfg(not(feature="rt_worker"))] - self.headers.set().Date(::ohkami_lib::imf_fixdate_now()); + pub(crate) fn complete(&mut self) { + self.headers.set().Date(::ohkami_lib::imf_fixdate( + std::time::Duration::from_secs(crate::utils::unix_timestamp()) + )); if self.content.is_none() && !matches!(self.status, Status::NoContent) { self.headers.set().ContentLength("0"); diff --git a/ohkami_lib/Cargo.toml b/ohkami_lib/Cargo.toml index e803abd8..1da9d69b 100644 --- a/ohkami_lib/Cargo.toml +++ b/ohkami_lib/Cargo.toml @@ -15,5 +15,4 @@ license = "MIT" [dependencies] serde = { workspace = true } byte_reader = { workspace = true } - percent-encoding = { version = "2.3" } \ No newline at end of file diff --git a/ohkami_lib/src/lib.rs b/ohkami_lib/src/lib.rs index 9dcc8ae0..c6c54928 100644 --- a/ohkami_lib/src/lib.rs +++ b/ohkami_lib/src/lib.rs @@ -3,7 +3,7 @@ pub mod base64; pub mod mime; mod time; -pub use time::{unix_timestamp, imf_fixdate_now}; +pub use time::imf_fixdate; mod slice; pub use slice::{Slice, CowSlice}; diff --git a/ohkami_lib/src/time.rs b/ohkami_lib/src/time.rs index e9a6bd6d..5231d908 100644 --- a/ohkami_lib/src/time.rs +++ b/ohkami_lib/src/time.rs @@ -1,39 +1,20 @@ //! Most parts are based on [chrono](https://github.com/chronotope/chrono); MIT. -use std::time::{SystemTime, UNIX_EPOCH}; - - -/// ``` -/// # let _ = -/// { -/// std::time::SystemTime::now() -/// .duration_since(std::time::UNIX_EPOCH) -/// .unwrap() -/// .as_secs() -/// } -/// # ; -/// ``` -#[inline] pub fn unix_timestamp() -> u64 { - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_secs() -} +use std::time::Duration; /// Current datetime by **IMF-fixdate** format like `Sun, 06 Nov 1994 08:49:37 GMT`, used in `Date` header. /// /// (referenceļ¼š[https://datatracker.ietf.org/doc/html/rfc9110#name-date-time-formats](https://datatracker.ietf.org/doc/html/rfc9110#name-date-time-formats)) -#[inline(always)] pub fn imf_fixdate_now() -> String { - let system_now = SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before Unix epoch"); - UTCDateTime::now_from_system(system_now).into_imf_fixdate() +#[inline(always)] pub fn imf_fixdate(duration_since_unix_epoch: Duration) -> String { + UTCDateTime::from_duration_since_unix_epoch(duration_since_unix_epoch).into_imf_fixdate() } struct UTCDateTime { date: Date, time: Time, } impl UTCDateTime { - #[inline] fn now_from_system(system_now: std::time::Duration) -> Self { + #[inline] fn from_duration_since_unix_epoch(system_now: Duration) -> Self { let (secs, nsecs) = (system_now.as_secs() as i64, system_now.subsec_nanos()); let days = secs.div_euclid(86_400); @@ -46,7 +27,7 @@ struct UTCDateTime { } fn into_imf_fixdate(self) -> String { - const IMF_FIXDATE_LEN: usize = "Sun, 06 Nov 1994 08:49:37 GMT".len(); + const IMF_FIXDATE_LEN: usize = str::len("Sun, 06 Nov 1994 08:49:37 GMT"); const SHORT_WEEKDAYS: [&str; 7] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; const SHORT_MONTHS: [&str; 12] = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; @@ -390,7 +371,9 @@ enum Weekday { String::from_utf8(output_bytes).unwrap() } - let (cn, n) = (correct_now(), super::imf_fixdate_now()); + use std::time::{SystemTime, UNIX_EPOCH}; + let system_now = SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before Unix epoch"); + let (cn, n) = (correct_now(), super::imf_fixdate(system_now)); assert_eq!(cn, n); } }