1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! Transport abstraction for SMTP I/O.
//!
//! The SMTP state machine in this crate is environment-independent. Adapter
//! crates (e.g. `wasm-smtp-cloudflare`) connect a runtime-native socket to
//! the state machine by implementing [`Transport`].
//!
//! ## Contract
//!
//! Implementations wrap a connected, byte-oriented stream. The trait
//! intentionally exposes only the minimum surface needed by the SMTP state
//! machine:
//!
//! - [`read`](Transport::read) returns the number of bytes filled into the
//! buffer, or `Ok(0)` to signal that the peer cleanly closed the connection.
//! - [`write_all`](Transport::write_all) must perform short-write retries
//! internally and only return after every byte has been accepted, or after
//! a fatal error.
//! - [`close`](Transport::close) releases the connection. The transport must
//! not be used for further I/O once `close` has returned.
//!
//! Errors of any kind originating below SMTP must be converted to
//! [`IoError`] at this boundary, which keeps adapter-specific types out of
//! the core public API.
//!
//! ## TLS
//!
//! Two TLS models are supported, selected by the transport:
//!
//! - **Implicit TLS** (port 465): the transport is already TLS-secured before
//! the SMTP state machine sees it. Plain [`Transport`] is sufficient.
//! - **STARTTLS** (port 587 / 25): the transport is initially plaintext and
//! is upgraded to TLS in-place after the `STARTTLS` SMTP command. Such
//! transports must additionally implement [`StartTlsCapable`].
//!
//! The TLS handshake itself, in either model, is the transport
//! implementation's responsibility.
use crateIoError;
/// Async byte-oriented transport contract used by [`crate::SmtpClient`].
///
/// See the [module-level documentation](self) for the contract.
// Single-threaded WASM runtimes (the primary target) do not need a `Send`
// bound on the returned futures. Adapter crates that target multi-threaded
// runtimes can wrap their transport in a type that adds a `Send` bound at
// the call site.
/// Marker for a [`Transport`] that can be upgraded to TLS in-place after
/// connection.
///
/// This is what enables the SMTP `STARTTLS` flow (RFC 3207). The plaintext
/// SMTP greeting and the initial `EHLO` are exchanged in cleartext; the
/// client then issues `STARTTLS`, awaits a `220` reply, and asks the
/// transport to upgrade. From that point on the byte stream is TLS-secured
/// and the SMTP state machine continues as if it had always been so (with
/// a second `EHLO` per RFC 3207 §4.2).
///
/// Transports that are connected with Implicit TLS (port 465) need not
/// implement this trait — they are already secure at construction time.