feat: add WASM support via web-time (#1037)

Support WASM environments by using web-time.
This was tested on a Cloudflare worker environment.
This commit is contained in:
Abid Omar
2025-02-17 15:53:19 +07:00
committed by GitHub
parent 3e9b1876d9
commit 5748af4c98
6 changed files with 44 additions and 2 deletions
Generated
+11
View File
@@ -1233,6 +1233,7 @@ dependencies = [
"url",
"uuid",
"walkdir",
"web-time",
"webpki-roots",
]
@@ -2442,6 +2443,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "web-time"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "webpki-roots"
version = "0.26.7"
+6
View File
@@ -75,6 +75,9 @@ ed25519-dalek = { version = "2", optional = true }
# email formats
email_address = { version = "0.2.1", default-features = false }
# webtime for wasm support
web-time = { version = "1.1.0", optional = true }
[dev-dependencies]
pretty_assertions = "1"
criterion = "0.5"
@@ -122,6 +125,9 @@ tokio1-boring-tls = ["tokio1", "boring-tls", "dep:tokio1_boring"]
dkim = ["dep:base64", "dep:sha2", "dep:rsa", "dep:ed25519-dalek"]
# wasm support
web = ["dep:web-time"]
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(lettre_ignore_tls_mismatch)'] }
+1
View File
@@ -107,6 +107,7 @@
//! * **tracing**: Logging using the `tracing` crate
//! * **mime03**: Allow creating a [`ContentType`] from an existing [mime 0.3] `Mime` struct
//! * **dkim**: Add support for signing email with DKIM
//! * **web**: WebAssembly support using the `web-time` crate for time operations
//!
//! [`SMTP`]: crate::transport::smtp
//! [`sendmail`]: crate::transport::sendmail
+7
View File
@@ -346,6 +346,13 @@ fn dkim_canonicalize_headers<'a>(
/// Sign with Dkim a message by adding Dkim-Signature header created with configuration expressed by
/// `dkim_config`
pub fn dkim_sign(message: &mut Message, dkim_config: &DkimConfig) {
#[cfg(feature = "web")]
dkim_sign_fixed_time(
message,
dkim_config,
crate::message::to_std_systemtime(web_time::SystemTime::now()),
);
#[cfg(not(feature = "web"))]
dkim_sign_fixed_time(message, dkim_config, SystemTime::now());
}
+6 -1
View File
@@ -21,7 +21,12 @@ impl Date {
///
/// Shortcut for `Date::new(SystemTime::now())`
pub fn now() -> Self {
Self::new(SystemTime::now())
#[cfg(not(feature = "web"))]
return Self::new(SystemTime::now());
#[cfg(feature = "web")]
return Self::new(crate::message::to_std_systemtime(
web_time::SystemTime::now(),
));
}
}
+13 -1
View File
@@ -277,7 +277,10 @@ impl MessageBuilder {
/// Shortcut for `self.date(SystemTime::now())`, it is automatically inserted
/// if no date has been provided.
pub fn date_now(self) -> Self {
self.date(SystemTime::now())
#[cfg(not(feature = "web"))]
return self.date(SystemTime::now());
#[cfg(feature = "web")]
return self.date(to_std_systemtime(web_time::SystemTime::now()));
}
/// Set or add mailbox to `ReplyTo` header
@@ -623,8 +626,17 @@ fn make_message_id() -> String {
iter::repeat_with(fastrand::alphanumeric).take(36).collect()
}
#[cfg(feature = "web")]
pub(crate) fn to_std_systemtime(time: web_time::SystemTime) -> std::time::SystemTime {
let duration = time
.duration_since(web_time::SystemTime::UNIX_EPOCH)
.unwrap();
std::time::SystemTime::UNIX_EPOCH + duration
}
#[cfg(test)]
mod test {
use std::time::{Duration, SystemTime};
use pretty_assertions::assert_eq;