Skip to content

V6: Idle connection breaks due to NOOP command being sent during active IDLE session #558

Open
@booklet-mikolajczak

Description

@booklet-mikolajczak

Hi!

After updating from 5.5.0 to 6.1.0 Idle connection stopped working.
When using the idle() method, the library tries to read stream line by using getConnection():

public function idle(callable $callback, int $timeout = 300): void {
    ...
    $idle_client->getConnection()->idle();
    ...
    while (true) {
        try {
            // This polymorphic call is fine - Protocol::idle() will throw an exception beforehand
            $line = $idle_client->getConnection()->nextLine(Response::empty());
        }

getConnection() call connected() in ImapProtocol

public function connected(): bool {
    if ((bool)$this->stream) {
        try {
            $this->requestAndResponse('NOOP'); // <--
            return true;
        } catch (ImapServerErrorException|RuntimeException) {
            return false;
        }
    }
    return false;
}

which leads to sending a NOOP command during an active IDLE session.

TAG5 IDLE
+ idling
TAG6 NOOP       <-- This shouldn't happen during IDLE
TAG5 BAD Could not parse command

This breaks the IDLE functionality and prevents receiving real-time updates.

According to the IMAP protocol specification (RFC 2177), when a client is in IDLE mode, the only valid command that can be sent is DONE to terminate the IDLE state. Any other commands (including NOOP) will cause protocol errors.

This would probably require adding an additional is_idle_mode attribute to the Protocol class to prevent send NOOP to check connection status.

I tested on Gmail servers

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions