Skip to content

Commit c4f3ea3

Browse files
committed
Version 2.0
Remove all the "transports" except for SMTP and connection setup code. Now the user is responsible for providing a stream with TLS, read and write timeouts, buffering, SOCKS5 etc. This makes it possible to have proper read and write timeouts instead of per-command timeouts, use alternative TLS implementations such as Rustls and use SMTP over other proxies, such as HTTP CONNECT, without modifying the library.
1 parent 671a74c commit c4f3ea3

31 files changed

+548
-2574
lines changed

Cargo.toml

+7-31
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
name = "async-smtp"
4-
version = "0.6.0"
4+
version = "2.0.0"
55
description = "SMTP client"
66
readme = "README.md"
77
homepage = "https://github.com/async-email/async-smtp"
@@ -22,17 +22,14 @@ log = "^0.4"
2222
async-trait = "0.1.17"
2323
pin-project = "1"
2424
pin-utils = "0.1.0"
25-
thiserror = "1.0.9"
25+
anyhow = "1"
26+
thiserror = "1"
2627
futures = "0.3.21"
2728

28-
nom = { version = "^7.0", optional = true }
29-
bufstream = { version = "^0.1", optional = true }
30-
base64 = { version = "^0.13", optional = true }
31-
hostname = { version = "0.3.1", optional = true }
32-
serde = { version = "^1.0", optional = true }
33-
serde_json = { version = "^1.0", optional = true }
34-
serde_derive = { version = "^1.0", optional = true }
35-
fast-socks5 = { version = "^0.8", optional = true }
29+
nom = "^7.0"
30+
bufstream = "^0.1"
31+
base64 = "^0.13"
32+
hostname = "0.3.1"
3633

3734
async-std = { version = "1.11", features = ["unstable"], optional = true }
3835
tokio = { version = "1", features = ["fs", "rt", "time", "net"], optional = true }
@@ -52,30 +49,9 @@ harness = false
5249

5350
[features]
5451
default = [
55-
"file-transport",
56-
"smtp-transport",
57-
"sendmail-transport",
5852
"runtime-tokio"
5953
]
6054

61-
serde-impls = ["serde", "serde_derive"]
62-
file-transport = ["serde-impls", "serde_json"]
63-
smtp-transport = ["bufstream", "base64", "nom", "hostname"]
64-
sendmail-transport = []
6555
native-tls-vendored = ["async-native-tls/vendored"]
66-
socks5 = ["fast-socks5"]
6756
runtime-async-std = ["async-std", "async-native-tls/runtime-async-std"]
6857
runtime-tokio = ["tokio", "async-native-tls/runtime-tokio"]
69-
70-
71-
[[example]]
72-
name = "smtp"
73-
required-features = ["smtp-transport"]
74-
75-
[[example]]
76-
name = "smtp_gmail"
77-
required-features = ["smtp-transport"]
78-
79-
[[example]]
80-
name = "socks5"
81-
required-features = ["smtp-transport", "socks5"]

benches/transport_smtp.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use async_smtp::{
2-
smtp::ConnectionReuseParameters, ClientSecurity, EmailAddress, Envelope, SendableEmail,
3-
ServerAddress, SmtpClient, Transport,
2+
ClientSecurity, EmailAddress, Envelope, SendableEmail, ServerAddress, SmtpClient, Transport,
43
};
54
use criterion::{black_box, criterion_group, criterion_main, Criterion};
65

@@ -45,7 +44,6 @@ fn bench_reuse_send(c: &mut Criterion) {
4544
ClientSecurity::None,
4645
)
4746
})
48-
.connection_reuse(ConnectionReuseParameters::ReuseUnlimited)
4947
.into_transport();
5048
c.bench_function("send email with connection reuse", move |b| {
5149
b.iter(|| {

examples/smtp.rs

-29
This file was deleted.

examples/smtp_gmail.rs

-37
This file was deleted.

examples/socks5.rs

-38
This file was deleted.

rustfmt.toml

-1
This file was deleted.

src/smtp/authentication.rs src/authentication.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Provides limited SASL authentication mechanisms
22
3-
use crate::smtp::error::Error;
3+
use crate::error::Error;
44
use std::fmt::{self, Display, Formatter};
55

66
/// Accepted authentication mechanisms on an encrypted connection
@@ -31,10 +31,6 @@ impl<S: Into<String>, T: Into<String>> IntoCredentials for (S, T) {
3131

3232
/// Contains user credentials
3333
#[derive(PartialEq, Eq, Clone, Hash, Debug)]
34-
#[cfg_attr(
35-
feature = "serde-impls",
36-
derive(serde_derive::Serialize, serde_derive::Deserialize)
37-
)]
3834
pub struct Credentials {
3935
authentication_identity: String,
4036
secret: String,
@@ -52,20 +48,16 @@ impl Credentials {
5248

5349
/// Represents authentication mechanisms
5450
#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
55-
#[cfg_attr(
56-
feature = "serde-impls",
57-
derive(serde_derive::Serialize, serde_derive::Deserialize)
58-
)]
5951
pub enum Mechanism {
6052
/// PLAIN authentication mechanism
61-
/// RFC 4616: https://tools.ietf.org/html/rfc4616
53+
/// RFC 4616: <https://tools.ietf.org/html/rfc4616>
6254
Plain,
6355
/// LOGIN authentication mechanism
6456
/// Obsolete but needed for some providers (like office365)
65-
/// https://www.ietf.org/archive/id/draft-murchison-sasl-login-00.txt
57+
/// <https://www.ietf.org/archive/id/draft-murchison-sasl-login-00.txt>
6658
Login,
6759
/// Non-standard XOAUTH2 mechanism
68-
/// https://developers.google.com/gmail/imap/xoauth2-protocol
60+
/// <https://developers.google.com/gmail/imap/xoauth2-protocol>
6961
Xoauth2,
7062
}
7163

src/smtp/client/codec.rs src/client/codec.rs

+25-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ use futures::io;
77

88
/// The codec used for transparency
99
#[derive(Default, Clone, Copy, Debug)]
10-
#[cfg_attr(
11-
feature = "serde-impls",
12-
derive(serde_derive::Serialize, serde_derive::Deserialize)
13-
)]
1410
pub struct ClientCodec {
1511
escape_count: u8,
1612
}
@@ -68,3 +64,28 @@ impl ClientCodec {
6864
}
6965
}
7066
}
67+
68+
#[cfg(test)]
69+
mod test {
70+
use super::*;
71+
use crate::async_test;
72+
73+
async_test! { test_codec, {
74+
let mut codec = ClientCodec::new();
75+
let mut buf: Vec<u8> = vec![];
76+
77+
assert!(codec.encode(b"test\r\n", &mut buf).await.is_ok());
78+
assert!(codec.encode(b".\r\n", &mut buf).await.is_ok());
79+
assert!(codec.encode(b"\r\ntest", &mut buf).await.is_ok());
80+
assert!(codec.encode(b"te\r\n.\r\nst", &mut buf).await.is_ok());
81+
assert!(codec.encode(b"test", &mut buf).await.is_ok());
82+
assert!(codec.encode(b"test.", &mut buf).await.is_ok());
83+
assert!(codec.encode(b"test\n", &mut buf).await.is_ok());
84+
assert!(codec.encode(b".test\n", &mut buf).await.is_ok());
85+
assert!(codec.encode(b"test", &mut buf).await.is_ok());
86+
assert_eq!(
87+
String::from_utf8(buf).unwrap(),
88+
"test\r\n..\r\n\r\ntestte\r\n..\r\nsttesttest.test\n.test\ntest"
89+
);
90+
}}
91+
}

src/smtp/client/mock.rs src/client/mock.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![allow(missing_docs)]
2-
31
use std::pin::Pin;
42
use std::task::{Context, Poll};
53

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
//! SMTP client
22
33
mod codec;
4-
mod inner;
54
pub mod mock;
6-
pub mod net;
75

86
pub use self::codec::*;
9-
pub use self::inner::*;

0 commit comments

Comments
 (0)