Skip to content

COR-273 - Report a refusal over the IMAP session limit as its own error - #120

Merged
dbezverkhnii merged 1 commit into
spark2from
fix/COR-273-imap-session-limit-refusal
Oct 7, 2026
Merged

dbezverkhnii merged 1 commit into
spark2from
fix/COR-273-imap-session-limit-refusal

Conversation

@dbezverkhnii

@dbezverkhnii dbezverkhnii commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Yahoo and AOL cap the simultaneous sessions per mailbox (5 and 8, measured) and refuse one more login with an untagged * BYE followed by the tagged refusal — N NO [LIMIT] AUTHENTICATE Rate limit hit. for XOAUTH2, N NO [LIMIT] LOGIN Rate limit hit. for a password. libetpan stops at the BYE with MAILIMAP_ERROR_STREAM, so the login reported ErrorConnection, and the client retried at once — one more login against the same limit.

  • The tagged refusal is still in imap_stream_buffer after the BYE. On a stream error the login looks there for NO [LIMIT] (the RFC 5530 code, not the text after it, which echoes the login command) and reports the new ErrorIMAPTooManySimultaneousConnections, the counterpart of Gmail's ErrorGmailTooManySimultaneousConnections. Spark handles both the same way: it narrows the account's connections for a while instead of retrying.
  • The code is appended after ErrorCanceled in the C++, C and Swift enums, so no existing value moves. Like ErrorCanceled, it has no ObjC constant and no localized description.
  • Nothing else in the login changes: a bare BYE stays ErrorConnection, Gmail's texts and wrong credentials keep their codes.

The C++ changed, so the Windows prebuilt needs a rebuild for this revision before a tag.

Tests: IMAPLoginTests against LeaseTestTCPEndpoint, which can now answer a command with a refusal and close the socket. * BYE + NO [LIMIT] gives the new code (it gave ErrorConnection before the fix); a bare BYE, Gmail's text and [AUTHENTICATIONFAILED] keep theirs. Checked in Spark against Yahoo and AOL with two devices on one account.

🤖 Generated with Claude Code


Note

Medium Risk
Touches IMAP login error classification on stream failures; mis-detection could change client retry/backoff behavior, though scope is narrow (substring on buffered stream after BYE).

Overview
Adds ErrorIMAPTooManySimultaneousConnections (C/C++/Swift) so Yahoo/AOL session-cap refusals are not reported as generic connection failures.

When libetpan returns MAILIMAP_ERROR_STREAM after an untagged * BYE, IMAPSession::login inspects imap_stream_buffer for the tagged NO [LIMIT] (RFC 5530) and returns the new code—parallel to Gmail’s ErrorGmailTooManySimultaneousConnections. A bare BYE, Gmail “too many connections” text, and AUTHENTICATIONFAILED behavior is unchanged.

LeaseTestTCPEndpoint gains configurable refusals (custom reply + optional socket close). IMAPLoginTests cover * BYE + [LIMIT], Gmail text, auth failure, and BYE-only cases for LOGIN and XOAUTH2.

Reviewed by Cursor Bugbot for commit 0c35c53. Bugbot is set up for automated code reviews on this repo. Configure here.

…R-273

Yahoo and AOL refuse a login over their limit of simultaneous sessions with
`* BYE` and then `NO [LIMIT]`. libetpan stops at the BYE with a stream error,
so the refusal came out as ErrorConnection and the client retried at once,
against the same limit. The tagged refusal is still in the stream buffer;
the login now reports it as ErrorIMAPTooManySimultaneousConnections, the
counterpart of Gmail's ErrorGmailTooManySimultaneousConnections.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dbezverkhnii

Copy link
Copy Markdown
Collaborator Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 0c35c53. Configure here.

@dbezverkhnii
dbezverkhnii marked this pull request as ready for review October 7, 2026 16:25
@dbezverkhnii
dbezverkhnii merged commit db3edc8 into spark2 Oct 7, 2026
9 of 10 checks passed
@dbezverkhnii
dbezverkhnii deleted the fix/COR-273-imap-session-limit-refusal branch October 7, 2026 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant