Seal header contents (#591)
This commit is contained in:
@@ -112,7 +112,7 @@ impl TryFrom<&Headers> for Envelope {
|
|||||||
fn try_from(headers: &Headers) -> Result<Self, Self::Error> {
|
fn try_from(headers: &Headers) -> Result<Self, Self::Error> {
|
||||||
let from = match headers.get::<header::Sender>() {
|
let from = match headers.get::<header::Sender>() {
|
||||||
// If there is a Sender, use it
|
// If there is a Sender, use it
|
||||||
Some(header::Sender(a)) => Some(a.email.clone()),
|
Some(sender) => Some(Mailbox::from(sender.clone()).email),
|
||||||
// ... else try From
|
// ... else try From
|
||||||
None => match headers.get::<header::From>() {
|
None => match headers.get::<header::From>() {
|
||||||
Some(header::From(a)) => {
|
Some(header::From(a)) => {
|
||||||
|
|||||||
14
src/lib.rs
14
src/lib.rs
@@ -122,10 +122,6 @@ mod executor;
|
|||||||
pub mod message;
|
pub mod message;
|
||||||
pub mod transport;
|
pub mod transport;
|
||||||
|
|
||||||
#[cfg(feature = "builder")]
|
|
||||||
#[macro_use]
|
|
||||||
extern crate hyperx;
|
|
||||||
|
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
pub use self::executor::AsyncStd1Executor;
|
pub use self::executor::AsyncStd1Executor;
|
||||||
#[cfg(all(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))]
|
#[cfg(all(any(feature = "tokio02", feature = "tokio1", feature = "async-std1")))]
|
||||||
@@ -208,9 +204,9 @@ mod test {
|
|||||||
let to = Mailboxes::new().with("amousset@example.com".parse().unwrap());
|
let to = Mailboxes::new().with("amousset@example.com".parse().unwrap());
|
||||||
|
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
headers.set(header::From(from));
|
headers.set(header::From::from(from));
|
||||||
headers.set(header::Sender(sender));
|
headers.set(header::Sender::from(sender));
|
||||||
headers.set(header::To(to));
|
headers.set(header::To::from(to));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Envelope::try_from(&headers).unwrap(),
|
Envelope::try_from(&headers).unwrap(),
|
||||||
@@ -228,8 +224,8 @@ mod test {
|
|||||||
let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());
|
let sender = Mailbox::new(None, "kayo2@example.com".parse().unwrap());
|
||||||
|
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
headers.set(header::From(from));
|
headers.set(header::From::from(from));
|
||||||
headers.set(header::Sender(sender));
|
headers.set(header::Sender::from(sender));
|
||||||
|
|
||||||
assert!(Envelope::try_from(&headers).is_err(),);
|
assert!(Envelope::try_from(&headers).is_err(),);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,6 @@ use std::{
|
|||||||
str::{from_utf8, FromStr},
|
str::{from_utf8, FromStr},
|
||||||
};
|
};
|
||||||
|
|
||||||
header! {
|
|
||||||
/// `Content-Id` header, defined in [RFC2045](https://tools.ietf.org/html/rfc2045#section-7)
|
|
||||||
(ContentId, "Content-ID") => [String]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `Content-Transfer-Encoding` of the body
|
/// `Content-Transfer-Encoding` of the body
|
||||||
///
|
///
|
||||||
/// The `Message` builder takes care of choosing the most
|
/// The `Message` builder takes care of choosing the most
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ macro_rules! mailbox_header {
|
|||||||
($(#[$doc:meta])*($type_name: ident, $header_name: expr)) => {
|
($(#[$doc:meta])*($type_name: ident, $header_name: expr)) => {
|
||||||
$(#[$doc])*
|
$(#[$doc])*
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct $type_name(pub Mailbox);
|
pub struct $type_name(Mailbox);
|
||||||
|
|
||||||
impl Header for $type_name {
|
impl Header for $type_name {
|
||||||
fn header_name() -> &'static str {
|
fn header_name() -> &'static str {
|
||||||
@@ -39,6 +39,20 @@ macro_rules! mailbox_header {
|
|||||||
f.fmt_line(&self.0.recode_name(utf8_b::encode))
|
f.fmt_line(&self.0.recode_name(utf8_b::encode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<Mailbox> for $type_name {
|
||||||
|
#[inline]
|
||||||
|
fn from(mailbox: Mailbox) -> Self {
|
||||||
|
Self(mailbox)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<$type_name> for Mailbox {
|
||||||
|
#[inline]
|
||||||
|
fn from(this: $type_name) -> Mailbox {
|
||||||
|
this.0
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +60,7 @@ macro_rules! mailboxes_header {
|
|||||||
($(#[$doc:meta])*($type_name: ident, $header_name: expr)) => {
|
($(#[$doc:meta])*($type_name: ident, $header_name: expr)) => {
|
||||||
$(#[$doc])*
|
$(#[$doc])*
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct $type_name(pub Mailboxes);
|
pub struct $type_name(pub(crate) Mailboxes);
|
||||||
|
|
||||||
impl MailboxesHeader for $type_name {
|
impl MailboxesHeader for $type_name {
|
||||||
fn join_mailboxes(&mut self, other: Self) {
|
fn join_mailboxes(&mut self, other: Self) {
|
||||||
@@ -74,6 +88,20 @@ macro_rules! mailboxes_header {
|
|||||||
format_mailboxes(self.0.iter(), f)
|
format_mailboxes(self.0.iter(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<Mailboxes> for $type_name {
|
||||||
|
#[inline]
|
||||||
|
fn from(mailboxes: Mailboxes) -> Self {
|
||||||
|
Self(mailboxes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<$type_name> for Mailboxes {
|
||||||
|
#[inline]
|
||||||
|
fn from(this: $type_name) -> Mailboxes {
|
||||||
|
this.0
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,19 +4,29 @@ use hyperx::{
|
|||||||
};
|
};
|
||||||
use std::{fmt::Result as FmtResult, str::from_utf8};
|
use std::{fmt::Result as FmtResult, str::from_utf8};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
/// Message format version, defined in [RFC2045](https://tools.ietf.org/html/rfc2045#section-4)
|
/// Message format version, defined in [RFC2045](https://tools.ietf.org/html/rfc2045#section-4)
|
||||||
pub struct MimeVersion {
|
pub struct MimeVersion {
|
||||||
pub major: u8,
|
major: u8,
|
||||||
pub minor: u8,
|
minor: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const MIME_VERSION_1_0: MimeVersion = MimeVersion { major: 1, minor: 0 };
|
pub const MIME_VERSION_1_0: MimeVersion = MimeVersion::new(1, 0);
|
||||||
|
|
||||||
impl MimeVersion {
|
impl MimeVersion {
|
||||||
pub fn new(major: u8, minor: u8) -> Self {
|
pub const fn new(major: u8, minor: u8) -> Self {
|
||||||
MimeVersion { major, minor }
|
MimeVersion { major, minor }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub const fn major(self) -> u8 {
|
||||||
|
self.major
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub const fn minor(self) -> u8 {
|
||||||
|
self.minor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MimeVersion {
|
impl Default for MimeVersion {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ macro_rules! text_header {
|
|||||||
($(#[$attr:meta])* Header($type_name: ident, $header_name: expr )) => {
|
($(#[$attr:meta])* Header($type_name: ident, $header_name: expr )) => {
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
$(#[$attr])*
|
$(#[$attr])*
|
||||||
pub struct $type_name(pub String);
|
pub struct $type_name(String);
|
||||||
|
|
||||||
impl Header for $type_name {
|
impl Header for $type_name {
|
||||||
fn header_name() -> &'static str {
|
fn header_name() -> &'static str {
|
||||||
@@ -31,6 +31,20 @@ macro_rules! text_header {
|
|||||||
fmt_text(&self.0, f)
|
fmt_text(&self.0, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<String> for $type_name {
|
||||||
|
#[inline]
|
||||||
|
fn from(text: String) -> Self {
|
||||||
|
Self(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<str> for $type_name {
|
||||||
|
#[inline]
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +83,11 @@ text_header!(
|
|||||||
/// defined in [draft-melnikov-email-user-agent-00](https://tools.ietf.org/html/draft-melnikov-email-user-agent-00#section-3)
|
/// defined in [draft-melnikov-email-user-agent-00](https://tools.ietf.org/html/draft-melnikov-email-user-agent-00#section-3)
|
||||||
Header(UserAgent, "User-Agent")
|
Header(UserAgent, "User-Agent")
|
||||||
);
|
);
|
||||||
|
text_header! {
|
||||||
|
/// `Content-Id` header,
|
||||||
|
/// defined in [RFC2045](https://tools.ietf.org/html/rfc2045#section-7)
|
||||||
|
Header(ContentId, "Content-ID")
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_text(raw: &[u8]) -> HyperResult<String> {
|
fn parse_text(raw: &[u8]) -> HyperResult<String> {
|
||||||
if let Ok(src) = from_utf8(raw) {
|
if let Ok(src) = from_utf8(raw) {
|
||||||
|
|||||||
@@ -167,7 +167,7 @@
|
|||||||
//! disposition: header::DispositionType::Inline,
|
//! disposition: header::DispositionType::Inline,
|
||||||
//! parameters: vec![],
|
//! parameters: vec![],
|
||||||
//! })
|
//! })
|
||||||
//! .header(header::ContentId("<123>".into()))
|
//! .header(header::ContentId::from(String::from("<123>")))
|
||||||
//! .body(image_body),
|
//! .body(image_body),
|
||||||
//! ),
|
//! ),
|
||||||
//! ),
|
//! ),
|
||||||
@@ -318,7 +318,8 @@ impl MessageBuilder {
|
|||||||
///
|
///
|
||||||
/// Shortcut for `self.header(header::Subject(subject.into()))`.
|
/// Shortcut for `self.header(header::Subject(subject.into()))`.
|
||||||
pub fn subject<S: Into<String>>(self, subject: S) -> Self {
|
pub fn subject<S: Into<String>>(self, subject: S) -> Self {
|
||||||
self.header(header::Subject(subject.into()))
|
let s: String = subject.into();
|
||||||
|
self.header(header::Subject::from(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set `Mime-Version` header to 1.0
|
/// Set `Mime-Version` header to 1.0
|
||||||
@@ -336,7 +337,7 @@ impl MessageBuilder {
|
|||||||
///
|
///
|
||||||
/// Shortcut for `self.header(header::Sender(mbox))`.
|
/// Shortcut for `self.header(header::Sender(mbox))`.
|
||||||
pub fn sender(self, mbox: Mailbox) -> Self {
|
pub fn sender(self, mbox: Mailbox) -> Self {
|
||||||
self.header(header::Sender(mbox))
|
self.header(header::Sender::from(mbox))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set or add mailbox to `From` header
|
/// Set or add mailbox to `From` header
|
||||||
@@ -345,7 +346,7 @@ impl MessageBuilder {
|
|||||||
///
|
///
|
||||||
/// Shortcut for `self.mailbox(header::From(mbox))`.
|
/// Shortcut for `self.mailbox(header::From(mbox))`.
|
||||||
pub fn from(self, mbox: Mailbox) -> Self {
|
pub fn from(self, mbox: Mailbox) -> Self {
|
||||||
self.mailbox(header::From(mbox.into()))
|
self.mailbox(header::From::from(Mailboxes::from(mbox)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set or add mailbox to `ReplyTo` header
|
/// Set or add mailbox to `ReplyTo` header
|
||||||
@@ -381,13 +382,13 @@ impl MessageBuilder {
|
|||||||
/// Set or add message id to [`In-Reply-To`
|
/// Set or add message id to [`In-Reply-To`
|
||||||
/// header](https://tools.ietf.org/html/rfc5322#section-3.6.4)
|
/// header](https://tools.ietf.org/html/rfc5322#section-3.6.4)
|
||||||
pub fn in_reply_to(self, id: String) -> Self {
|
pub fn in_reply_to(self, id: String) -> Self {
|
||||||
self.header(header::InReplyTo(id))
|
self.header(header::InReplyTo::from(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set or add message id to [`References`
|
/// Set or add message id to [`References`
|
||||||
/// header](https://tools.ietf.org/html/rfc5322#section-3.6.4)
|
/// header](https://tools.ietf.org/html/rfc5322#section-3.6.4)
|
||||||
pub fn references(self, id: String) -> Self {
|
pub fn references(self, id: String) -> Self {
|
||||||
self.header(header::References(id))
|
self.header(header::References::from(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set [Message-Id
|
/// Set [Message-Id
|
||||||
@@ -399,7 +400,7 @@ impl MessageBuilder {
|
|||||||
/// `<UUID@HOSTNAME>`.
|
/// `<UUID@HOSTNAME>`.
|
||||||
pub fn message_id(self, id: Option<String>) -> Self {
|
pub fn message_id(self, id: Option<String>) -> Self {
|
||||||
match id {
|
match id {
|
||||||
Some(i) => self.header(header::MessageId(i)),
|
Some(i) => self.header(header::MessageId::from(i)),
|
||||||
None => {
|
None => {
|
||||||
#[cfg(feature = "hostname")]
|
#[cfg(feature = "hostname")]
|
||||||
let hostname = hostname::get()
|
let hostname = hostname::get()
|
||||||
@@ -409,7 +410,7 @@ impl MessageBuilder {
|
|||||||
#[cfg(not(feature = "hostname"))]
|
#[cfg(not(feature = "hostname"))]
|
||||||
let hostname = DEFAULT_MESSAGE_ID_DOMAIN.to_string();
|
let hostname = DEFAULT_MESSAGE_ID_DOMAIN.to_string();
|
||||||
|
|
||||||
self.header(header::MessageId(
|
self.header(header::MessageId::from(
|
||||||
// https://tools.ietf.org/html/rfc5322#section-3.6.4
|
// https://tools.ietf.org/html/rfc5322#section-3.6.4
|
||||||
format!("<{}@{}>", Uuid::new_v4(), hostname),
|
format!("<{}@{}>", Uuid::new_v4(), hostname),
|
||||||
))
|
))
|
||||||
@@ -420,7 +421,7 @@ impl MessageBuilder {
|
|||||||
/// Set [User-Agent
|
/// Set [User-Agent
|
||||||
/// header](https://tools.ietf.org/html/draft-melnikov-email-user-agent-004)
|
/// header](https://tools.ietf.org/html/draft-melnikov-email-user-agent-004)
|
||||||
pub fn user_agent(self, id: String) -> Self {
|
pub fn user_agent(self, id: String) -> Self {
|
||||||
self.header(header::UserAgent(id))
|
self.header(header::UserAgent::from(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Force specific envelope (by default it is derived from headers)
|
/// Force specific envelope (by default it is derived from headers)
|
||||||
@@ -595,7 +596,7 @@ mod test {
|
|||||||
.header(header::To(
|
.header(header::To(
|
||||||
vec!["Pony O.P. <pony@domain.tld>".parse().unwrap()].into(),
|
vec!["Pony O.P. <pony@domain.tld>".parse().unwrap()].into(),
|
||||||
))
|
))
|
||||||
.header(header::Subject("яңа ел белән!".into()))
|
.header(header::Subject::from(String::from("яңа ел белән!")))
|
||||||
.body(String::from("Happy new year!"))
|
.body(String::from("Happy new year!"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -641,7 +642,7 @@ mod test {
|
|||||||
disposition: header::DispositionType::Inline,
|
disposition: header::DispositionType::Inline,
|
||||||
parameters: vec![],
|
parameters: vec![],
|
||||||
})
|
})
|
||||||
.header(header::ContentId("<123>".into()))
|
.header(header::ContentId::from(String::from("<123>")))
|
||||||
.body(img),
|
.body(img),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user