Compare commits

..

3 Commits

Author SHA1 Message Date
Alexis Mousset
47cad567b0 Prepare 0.10.0-rc.3 (#629) 2021-05-22 19:52:38 +02:00
Alexis Mousset
b0e2fc9bca fix(transport-smtp): Fix transparency codec (#627)
It fails to add transparency when a period is preceded by two
successive CRLF.

Co-authored-by: Paolo Barbolini <paolo@paolo565.org>
2021-05-22 19:41:29 +02:00
Alexis Mousset
1d8249165c Makes more things private and add missing docs (#621) 2021-05-19 18:51:03 +02:00
13 changed files with 48 additions and 17 deletions

View File

@@ -1,7 +1,7 @@
[package]
name = "lettre"
# remember to update html_root_url and README.md (Cargo.toml example and deps.rs badge)
version = "0.10.0-rc.2"
version = "0.10.0-rc.3"
description = "Email client"
readme = "README.md"
homepage = "https://lettre.rs"

View File

@@ -28,8 +28,8 @@
</div>
<div align="center">
<a href="https://deps.rs/crate/lettre/0.10.0-rc.2">
<img src="https://deps.rs/crate/lettre/0.10.0-rc.2/status.svg"
<a href="https://deps.rs/crate/lettre/0.10.0-rc.3">
<img src="https://deps.rs/crate/lettre/0.10.0-rc.3/status.svg"
alt="dependency status" />
</a>
</div>
@@ -71,7 +71,7 @@ To use this library, add the following to your `Cargo.toml`:
```toml
[dependencies]
lettre = "0.10.0-rc.2"
lettre = "0.10.0-rc.3"
```
```rust,no_run

View File

@@ -95,7 +95,7 @@
//! [Tokio 1.x]: https://docs.rs/tokio/1
//! [async-std 1.x]: https://docs.rs/async-std/1
#![doc(html_root_url = "https://docs.rs/crate/lettre/0.10.0-rc.2")]
#![doc(html_root_url = "https://docs.rs/crate/lettre/0.10.0-rc.3")]
#![doc(html_favicon_url = "https://lettre.rs/favicon.ico")]
#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/15113230?v=4")]
#![forbid(unsafe_code)]

View File

@@ -26,6 +26,9 @@ mod mailbox;
mod special;
mod textual;
/// Represents an email header
///
/// Email header as defined in [RFC5322](https://datatracker.ietf.org/doc/html/rfc5322) and extensions.
pub trait Header: Clone {
fn name() -> HeaderName;

View File

@@ -10,6 +10,9 @@ pub struct MimeVersion {
minor: u8,
}
/// MIME version 1.0
///
/// Should be used in all MIME messages.
pub const MIME_VERSION_1_0: MimeVersion = MimeVersion::new(1, 0);
impl MimeVersion {

View File

@@ -4,6 +4,7 @@ use crate::transport::smtp::error::{self, Error};
use std::fmt::{self, Debug, Display, Formatter};
/// Accepted authentication mechanisms
///
/// Trying LOGIN last as it is deprecated.
pub const DEFAULT_MECHANISMS: &[Mechanism] = &[Mechanism::Plain, Mechanism::Login];

View File

@@ -298,7 +298,7 @@ impl AsyncSmtpConnection {
return if response.is_positive() {
Ok(response)
} else {
Err(error::code(response.code))
Err(error::code(response.code()))
}
}
Err(nom::Err::Failure(e)) => {

View File

@@ -276,7 +276,7 @@ impl SmtpConnection {
return if response.is_positive() {
Ok(response)
} else {
Err(error::code(response.code))
Err(error::code(response.code()))
};
}
Err(nom::Err::Failure(e)) => {

View File

@@ -78,7 +78,15 @@ impl ClientCodec {
match self.escape_count {
0 => self.escape_count = if *byte == b'\r' { 1 } else { 0 },
1 => self.escape_count = if *byte == b'\n' { 2 } else { 0 },
2 => self.escape_count = if *byte == b'.' { 3 } else { 0 },
2 => {
self.escape_count = if *byte == b'.' {
3
} else if *byte == b'\r' {
1
} else {
0
}
}
_ => unreachable!(),
}
if self.escape_count == 3 {
@@ -111,6 +119,7 @@ mod test {
let mut buf: Vec<u8> = vec![];
codec.encode(b"test\r\n", &mut buf);
codec.encode(b"test\r\n\r\n", &mut buf);
codec.encode(b".\r\n", &mut buf);
codec.encode(b"\r\ntest", &mut buf);
codec.encode(b"te\r\n.\r\nst", &mut buf);
@@ -121,7 +130,7 @@ mod test {
codec.encode(b"test", &mut buf);
assert_eq!(
String::from_utf8(buf).unwrap(),
"test\r\n..\r\n\r\ntestte\r\n..\r\nsttesttest.test\n.test\ntest"
"test\r\ntest\r\n\r\n..\r\n\r\ntestte\r\n..\r\nsttesttest.test\n.test\ntest"
);
}

View File

@@ -72,6 +72,7 @@ impl ClientId {
/// Supported ESMTP keywords
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum Extension {
/// 8BITMIME keyword
///
@@ -107,11 +108,11 @@ pub struct ServerInfo {
/// Server name
///
/// The name given in the server banner
pub name: String,
name: String,
/// ESMTP features supported by the server
///
/// It contains the features supported by the server and known by the `Extension` module.
pub features: HashSet<Extension>,
features: HashSet<Extension>,
}
impl Display for ServerInfo {
@@ -135,7 +136,7 @@ impl ServerInfo {
let mut features: HashSet<Extension> = HashSet::new();
for line in response.message.as_slice() {
for line in response.message() {
if line.is_empty() {
continue;
}
@@ -197,6 +198,11 @@ impl ServerInfo {
}
None
}
/// The name given in the server banner
pub fn name(&self) -> &str {
self.name.as_ref()
}
}
/// A `MAIL FROM` extension parameter

View File

@@ -148,7 +148,7 @@ pub mod extension;
mod pool;
pub mod response;
mod transport;
pub mod util;
pub(super) mod util;
// Registered port numbers:
// https://www.iana.
@@ -164,7 +164,7 @@ pub const SUBMISSION_PORT: u16 = 587;
pub const SUBMISSIONS_PORT: u16 = 465;
/// Default timeout
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
#[derive(Debug, Clone)]
struct SmtpInfo {

View File

@@ -137,10 +137,10 @@ impl Code {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Response {
/// Response code
pub code: Code,
code: Code,
/// Server response string (optional)
/// Handle multiline responses
pub message: Vec<String>,
message: Vec<String>,
}
impl FromStr for Response {
@@ -180,6 +180,16 @@ impl Response {
pub fn first_line(&self) -> Option<&str> {
self.message.first().map(String::as_str)
}
/// Response code
pub fn code(&self) -> Code {
self.code
}
/// Server response string (array of lines)
pub fn message(&self) -> impl Iterator<Item = &str> {
self.message.iter().map(String::as_str)
}
}
// Parsers (originally from tokio-smtp)

View File

@@ -4,7 +4,6 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
/// Encode a string as xtext
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct XText<'a>(pub &'a str);
impl<'a> Display for XText<'a> {