Subject: | NOOP should return status, all should handle untagged BYE |
Date: | Sun, 12 May 2019 09:26:49 -0400 |
To: | bug-Net-IMAP-Simple [...] rt.cpan.org |
From: | Timothe Litt <tlhackque [...] cpan.org> |
Subject: | NOOP should return status, all should handle untagged BYE |
To: | bug-Net-IMAP-Simple [...] rt.cpan.org |
From: | Timothe Litt <tlhackque [...] cpan.org> |
While NOOP 'always succeeds', it also can return status indicating errors.
'BAD' is possible per the IMAP spec - but that really shouldn't happen
since N:I:S generates a valid command.
More interesting is the case of the server closing the connection(e.g, when
one is late sending the NOOP, when the IMAP server is restarted, or the
connection is administratively disconnected).
Currently, noop() always returns true. It should return undef (and set
an error) when it fails.
Returning status is simple: add a 'final' callback that returns 1.
|sub noop {||
|| my $self = shift;||
|| return $self->_process_cmd(||
|| cmd => [ "NOOP" ],||
|| final => sub { 1 },||
|| );||
||}|
_process_cmd() will then handle returning the error or OK status.
BYE is an untagged response that can come at any time (see 7.1.5 in RFC
3501).
In theory, it can arrive with a tagged completion, but at present,
_cmd_ok does
not handle this gracefully - it simply returns undef, indicating
failure. Any
completion is ignored.
While handling an accompanying completion would be a bit involved,
_cmd_ok() should at least capture the reason for an (untagged) BYE. This
can be done with one line of code:
|} elsif ( $res =~ m/^\*\s+/ ) {||
|
|}|
becomes
|} elsif ( $res =~ m/^\*\s+/ ) {
$self->_seterrstr( $1 ) if( $res =~ /^\*\s+BYE\s+(.*?)\r?$/i );
}|
||
This debugger session demonstrates the result.
A noop is sent, the connection is administratively closed from the
server side,
and another noop is sent.
The first NOOP returns success, the second returns undef, and errstr is
set with the server's reason.
| DB<2> x $mbx->debug(1)||
||0 1||
|| DB<3> x scalar $mbx->noop, $mbx->{_errstr}||
||[...in sub _send_cmd] 1 NOOP\r\n||
||[...in sub _process_cmd] 1 OK NOOP completed (0.001 + 0.000 secs).\r\n||
||[...in sub _cmd_ok] 1 OK NOOP completed (0.001 + 0.000 secs).\r\n||
||0 1||
||1 ||undef||
|| DB<4> x scalar $mbx->noop, $mbx->{_errstr}||
||[...in sub _send_cmd] 2 NOOP\r\n||
||[...in sub _process_cmd] * BYE Server shutting down.\r\n||
||[...in sub _seterrstr] Server shutting down.||
||[...in sub _cmd_ok] * BYE Server shutting down.\r\n||
||0 undef||
||1 ||'Server shutting down.'||
||
|
Message body not shown because it is not plain text.