Skip to content

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

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

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

Conversation

@nevans
Copy link
Copy Markdown
Collaborator

@nevans nevans commented Apr 20, 2026

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant