Skip to content

✨ Support LITERAL+ and LITERAL- non-synchronizing literals (RFC7888)#649

Merged
nevans merged 5 commits into
masterfrom
add-support-for-non-synchronizing-literals
Apr 20, 2026
Merged

✨ Support LITERAL+ and LITERAL- non-synchronizing literals (RFC7888)#649
nevans merged 5 commits into
masterfrom
add-support-for-non-synchronizing-literals

Conversation

@nevans

@nevans nevans commented Apr 20, 2026

Copy link
Copy Markdown
Collaborator

Non-synchronizing literals avoid the latency of waiting for the server to allow continuation. Non-synchronizing literals are only sent when the server's capabilities have been already been cached and include either LITERAL+ [RFC7888], LITERAL- [RFC7888], or IMAP4rev2 [RFC9051].

However, if a client sends a non-synchronizing literal that is too large for the server, the server may need to close the connection. Because LITERAL+ does not directly indicate the server's limits, it's best to avoid sending very large non-synchronized literals. This also adds Config#max_non_synchronizing_literal: the maximum bytesize for non-synchronizing literals. To disable non-synchronizing literals, set the value to -1.

For LITERAL+, config.max_non_synchronizing_literal is the only limit on whether a literal value is sent as a non-synchronizing literal. For LITERAL- and IMAP4rev2, non-synchronizing literals must also be smaller than 4096 bytes.

By default, config.max_non_synchronizing_literal is set to 16 KiB. But servers are much more likely to support LITERAL- than LITERAL+, so the practical limit will be 4096.

nevans added 5 commits April 17, 2026 11:26
This tests literal sending a lot more thoroughly.  Most importantly,
this tests both continuation rejection and continuation request.

Added `literal_acceptor` proc to FakeServer, which returns if server
accepts specific literal continuation, and can be varied per test.
This is internal only, for now.  It is only used by `Literal` and
`Literal8`, and only when `non_synchronizing` is _explicitly_ set to
`true` or `false`.

`CommandData` only has a single `#data` attr, so this updates `Literal`
to no longer inherit from `CommandData`.

`non_synchronizing` is optional.  The intent is to make it tri-state:
* `true`  -> force non-synchronizing `LITERAL+`/`LITERAL-` behavior
* `false` -> force normal synchronizing literal behavior
* `nil`   -> dynamic behavior, based on capabilities and literal size

The `nil` behavior will be implemented in a separate commit.
I thought rdoc had fixed their endless method definition bugs with the
upgrade to using prism?
This also adds a new config attribute: `max_non_synchronizing_literal`.
By default, it is set rather conservatively to 16 KiB.  But servers are
much more likely to support `LITERAL-` than `LITERAL+`, so the practical
limit will be 4096.
@nevans nevans added enhancement New feature or request IMAP4rev2 Requirement for IMAP4rev2, RFC9051 labels Apr 20, 2026
@nevans
nevans merged commit 35528f7 into master Apr 20, 2026
39 checks passed
@nevans
nevans deleted the add-support-for-non-synchronizing-literals branch April 20, 2026 13:34
nevans added a commit that referenced this pull request Apr 22, 2026
…non-synchronizing-literals

♻️  Improve internal literal sending (partially backports #616, #649)
nevans added a commit that referenced this pull request Apr 22, 2026
…non-synchronizing-literals

♻️  Improve internal literal sending (partially backports #358, #616, #649)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request IMAP4rev2 Requirement for IMAP4rev2, RFC9051

1 participant