IMAP Connector Core
Relevant source files
The following files were used as context for generating this wiki page:
The IMAP Connector Core provides the primary interface for communication between the Mailiner application and IMAP servers. It handles the complexities of IMAP protocols, including session management, message fetching, folder synchronization, and flag updates. Because browsers cannot create direct TCP connections, this component works alongside a WebSocket-to-TCP proxy to facilitate network traffic.
Sources: README.md:10-18, crates/mailiner-imap-connector/src/lib.rs:77-104
Architecture and Session Management
The core architecture centers on the ImapConnector struct, which implements the EmailConnector trait. It manages the IMAP session state through an asynchronous state machine.
Connection States
The connector tracks the lifecycle of an IMAP connection using the ImapSession enum:
- Disconnected: No active connection exists.
- Unauthenticated: A TLS stream is established, but the user is not logged in.
- Authenticating: A login attempt is currently in progress.
- Authenticated: A session is active and ready for commands.
Sources: crates/mailiner-imap-connector/src/lib.rs:70-104
Session Flow
The following diagram illustrates the transition from a disconnected state to an authenticated session:
The connector probes for the SORT capability (RFC 5256) immediately after authentication to determine if server-side sorting is available.
Sources: crates/mailiner-imap-connector/src/lib.rs:163-186, crates/mailiner-imap-connector/src/lib.rs:569-580
Message Handling and Synchronization
The connector manages folder contents by maintaining a ListIndex. This index caches UIDs and sort orders to support efficient UI paging.
Folder Operations
| Operation | Method | Description |
|---|---|---|
| List Folders | list_folders | Retrieves all selectable mailboxes from the server. |
| Sync Counts | folder_counts | Fetches MESSAGES and UNSEEN status for specific folders. |
| Prepare List | prepare_folder_list | Selects a folder and builds a sorted index of message UIDs. |
| Range Fetch | list_envelopes_range | Fetches envelope data for a specific slice of the sorted index. |
Sources: crates/mailiner-core/src/connector.rs:25-50, crates/mailiner-imap-connector/src/lib.rs:647-738
Sorting Logic
If the server supports SORT, the connector offloads sorting to the server. If not, it falls back to basic ARRIVAL order (UID-based).
- Arrival Sort: Uses
UID SEARCH ALLand orders by UID. - Unread Sort: Groups
UNSEENmessages at the top, followed bySEENmessages. - Size/Sender Sort: Requires server-side
SORTcapability.
Sources: crates/mailiner-imap-connector/src/lib.rs:582-645
Data Retrieval and Streaming
The connector uses a progressive retrieval strategy to handle message bodies and large attachments without exhausting browser memory.
BodyStructure and Parsing
The connector fetches BODYSTRUCTURE to understand the MIME hierarchy of a message before downloading content. This structure is cached in a structure_cache keyed by folder and message ID.
Sources: crates/mailiner-imap-connector/src/lib.rs:99-101, crates/mailiner-mime/src/parser/mod.rs:80-92
Progressive Streaming
For large attachments, the connector implements a stream_raw_part method that utilizes IMAP partial fetches (BODY.PEEK[section]<offset.length>).
- Chunk Size: Defaults to 512 KiB to balance RTT efficiency and memory usage.
- Safety Limit: A hard cap of 100 MiB is enforced to prevent browser crashes from malicious or excessively large files.
Sources: crates/mailiner-imap-connector/src/lib.rs:550-567, crates/mailiner-app/src/download.rs:11-13
Message Modification
The connector supports standard IMAP state changes including flag updates and message movement.
Flag Management
The update_envelope_flags method maps typed EnvelopeFlag values to IMAP atoms:
EnvelopeFlag::Read->\SeenEnvelopeFlag::Flagged->\FlaggedEnvelopeFlag::Deleted->\DeletedEnvelopeFlag::Starred->\Starred(Custom atom)
Sources: crates/mailiner-imap-connector/src/lib.rs:518-526, crates/mailiner-imap-connector/src/lib.rs:818-842
Moving and Deletion
Message movement uses the UID MOVE command where available. If the server does not support MOVE, the connector executes a fallback sequence:
UID COPYto destination.+FLAGS.SILENT (\Deleted)on source.EXPUNGE(orUID EXPUNGEif supported).
Sources: crates/mailiner-imap-connector/src/lib.rs:872-902
Error Handling
IMAP-specific errors are captured in the ImapError enum and converted to generic MailinerError types for the UI.
| ImapError Variant | Resulting MailinerError |
|---|---|
Connection(msg) | Connector(msg) |
Authentication(msg) | Auth(msg) |
Tls(msg) | Tls(msg) |
InvalidData(msg) | InvalidData(msg) |
Sources: crates/mailiner-imap-connector/src/lib.rs:43-68
The IMAP Connector Core ensures that high-level email operations are reliably translated into valid IMAP command sequences while maintaining a performant, memory-efficient footprint suitable for WebAssembly environments.