Hi Paul,
So actually I think the * BYE or * qr/.*backoff.*/i or something may
need to be tested for.
The problem is that at least in my case (I am working with MAPI,
Office365 IMAP server) the server uses this response either to inform
that the sock has been shut down, or that the client is throttled and
needs to back off.
What currently happens is that Net::IMAP::Simple is unaware that the
sock it wants to print to has been shut down, tries to print something
into it, and perl quietly(!) SIGPIPES and exits, not dies, but just
exits with SIGPIPE errno.
Right now I built a wrapper of sorts (sorry, I can't share more at this
point):
readline_callback => sub {
push(@{$self->{imap_responses}}, $_[0])
if $_[0] =~ /^(\d+|\*) /i;
}
sub errstr ($) {
my $self = shift;
my $errstr = $Net::IMAP::Simple::errstr
|| $self->{imap_responses}[-1]
|| 'Unknown error';
$errstr;
}
sub handle_failure ($$) {
my $self = shift;
my $cmd = shift;
my $args = shift;
$self->log_it("$cmd $args failed: " . $self->errstr);
if ($self->errstr =~ /backoff.* (\d+) millise/i) {
my $tosleep = ($1+100000)*1000;
$self->log_it("Throttling encountered, backing off");
my $sock = $self->{imap}->_sock();
$self->disconnect();
$sock = undef;
usleep $tosleep;
}
else {
sleep $self->{config}{command_failure_sleep};
}
}
sub disconnect ($) {
my $self = shift;
if ($self->{imap} && $self->{imap}->_sock &&
$self->{imap}->_sock->connected) {
$self->{imap}->_sock->shutdown(2);
sleep 1;
}
}
sub get_status ($) {
my $self = shift;
$self->{imap_responses}
&& @{$self->{imap_responses}}
&& $self->{imap_responses}[-1] =~
/^$self->{imap}{count} OK /
}
And when I execute a command, I test:
if (! $sock || ! $sock->connected) {
$imap = $self->reconnect($type, $retries+1);
unshift(@commands, 'login') unless $command eq
'login';
}
Thanks for your time and effort,
R.
On 8/10/18 7:03 AM, Paul Miller via RT wrote:
Show quoted text> <URL:
https://rt.cpan.org/Ticket/Display.html?id=125883 >
>
> Hrm. I'm not sure what can be done about that. I'm thinking about it. Since you've had time to think about it... have you had any ideas?
>
> BTW, sorry for the late reply. I didn't notice this in a timely fashion.
>
> On Wed Jul 18 15:55:03 2018, ROMM wrote:
>> Hi guys,
>>
>> Great work, but in the version 1.2209 (and as I checked, in 1.2212)
>> there is a problem handling out in _cmd_ok (line 1182 in 1.2209):
>>
>> sub _cmd_ok {
>> my ( $self, $res ) = @_;
>> my $id = $self->_count;
>>
>> $self->_debug( caller, __LINE__, '_cmd_ok', $res ) if $self->{debug};
>>
>> if ( $res =~ /^$id\s+OK/i ) {
>> return 1;
>>
>> } elsif ( $res =~ /^$id\s+(?:NO|BAD)(?:\s+(.+))?/i ) {
>> $self->_seterrstr( $1 || 'unknown error' );
>> return 0;
>>
>> } elsif ( $res =~ m/^\*\s+/ ) {
>>
>> }else {
>> $self->_seterrstr("warning unknown return string (id=$id): $res");
>> }
>>
>> return;
>> }
>>
>> Unfortunately, Outlook365 IMAP implementation has been noticed to
>> arbitrarily close the connection sending:
>> [...re/perl5/Net/IMAP/Simple.pm line 1126 in sub _process_cmd] * BYE
>> Connection is closed. 13\r\n
>> [...re/perl5/Net/IMAP/Simple.pm line 1277 in sub _cmd_ok] * BYE
>> Connection is closed. 13\r\n
>> which are thus unparsed and not taken care of. After that you can
>> continue to pump commands into IMAP pipeline and after about a fifty
>> such commands the script will die without a reason.
>>
>> I don't know what the patch should be, but at least some _seterrstr
>> should be called.
>>
>> Thanks,
>> Roman.
>