Skip to content

Commit 330f077

Browse files
committed
Version 2.0
Remove connection setup and all the "transports" except SMTP. 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 330f077

33 files changed

+587
-2866
lines changed

.github/workflows/ci.yml

+2-22
Original file line numberDiff line numberDiff line change
@@ -31,44 +31,24 @@ jobs:
3131
command: check
3232
args: --all --bins --examples --tests
3333

34-
- name: check bench
35-
uses: actions-rs/cargo@v1
36-
if: matrix.rust == 'nightly'
37-
with:
38-
command: check
39-
args: --benches
40-
4134
- name: tests tokio
4235
uses: actions-rs/cargo@v1
4336
with:
4437
command: test
45-
args: --all --no-default-features --features file-transport,smtp-transport,runtime-tokio
46-
47-
- name: tests tokio with socks5
48-
uses: actions-rs/cargo@v1
49-
with:
50-
command: test
51-
args: --all --no-default-features --features file-transport,smtp-transport,runtime-tokio,socks5
38+
args: --all --no-default-features --features runtime-tokio
5239

5340
- name: tests async-std
5441
uses: actions-rs/cargo@v1
5542
with:
5643
command: test
57-
args: --all --no-default-features --features file-transport,smtp-transport,runtime-async-std
44+
args: --all --no-default-features --features runtime-async-std
5845

5946
check_fmt_and_docs:
6047
name: Checking fmt and docs
6148
runs-on: ubuntu-latest
6249
steps:
6350
- uses: actions/checkout@master
6451

65-
- uses: actions-rs/toolchain@v1
66-
with:
67-
profile: minimal
68-
toolchain: nightly
69-
override: true
70-
components: rustfmt
71-
7252
- name: fmt
7353
run: cargo fmt --all -- --check
7454

Cargo.toml

+10-42
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"
@@ -18,25 +18,18 @@ is-it-maintained-issue-resolution = { repository = "async-email/async-smtp" }
1818
is-it-maintained-open-issues = { repository = "async-email/async-smtp" }
1919

2020
[dependencies]
21-
log = "^0.4"
22-
async-trait = "0.1.17"
2321
pin-project = "1"
24-
pin-utils = "0.1.0"
25-
thiserror = "1.0.9"
26-
futures = "0.3.21"
27-
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 }
36-
22+
anyhow = "1"
23+
async-native-tls = { version = "0.4", default-features = false }
3724
async-std = { version = "1.11", features = ["unstable"], optional = true }
25+
base64 = "^0.13"
26+
bufstream = "^0.1"
27+
futures = "0.3.21"
28+
hostname = "0.3.1"
29+
log = "^0.4"
30+
nom = "^7.0"
31+
thiserror = "1"
3832
tokio = { version = "1", features = ["fs", "rt", "time", "net"], optional = true }
39-
async-native-tls = { version = "0.4", default-features = false }
4033

4134

4235
[dev-dependencies]
@@ -46,36 +39,11 @@ criterion = "^0.3"
4639
async-std = { version = "1.11", features = ["unstable", "attributes"] }
4740
tokio = { version = "1", features = ["fs", "rt", "time", "net", "macros"] }
4841

49-
[[bench]]
50-
name = "transport_smtp"
51-
harness = false
52-
5342
[features]
5443
default = [
55-
"file-transport",
56-
"smtp-transport",
57-
"sendmail-transport",
5844
"runtime-tokio"
5945
]
6046

61-
serde-impls = ["serde", "serde_derive"]
62-
file-transport = ["serde-impls", "serde_json"]
63-
smtp-transport = ["bufstream", "base64", "nom", "hostname"]
64-
sendmail-transport = []
6547
native-tls-vendored = ["async-native-tls/vendored"]
66-
socks5 = ["fast-socks5"]
6748
runtime-async-std = ["async-std", "async-native-tls/runtime-async-std"]
6849
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

-73
This file was deleted.

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/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+
}

0 commit comments

Comments
 (0)