This patch makes sure that hook_disconnect and hook_reset_transaction plugins are run at the end of all transactions, including those where the remote end hung up unexpectedly or we timed out the connection.
My previous changes were a bit more complex than they had to be, had no effect on apache or async, and further testing indicated that they did not affect timed out connections. This patch is tested to work for both hang-ups and timeouts from prefork, and should work for the rest of the server modes -- EXCEPT that I couldn't figure out where to modify timeout behavior for the apache mode. Does anyone have any ideas on that one? --- lib/Apache/Qpsmtpd.pm | 1 + lib/Qpsmtpd.pm | 8 ++++++++ lib/Qpsmtpd/PollServer.pm | 1 + lib/Qpsmtpd/SMTP.pm | 6 +----- lib/Qpsmtpd/TcpServer.pm | 1 + lib/Qpsmtpd/TcpServer/Prefork.pm | 1 + 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/Apache/Qpsmtpd.pm b/lib/Apache/Qpsmtpd.pm index 0433324..b3ca5b6 100644 --- a/lib/Apache/Qpsmtpd.pm +++ b/lib/Apache/Qpsmtpd.pm @@ -127,6 +127,7 @@ sub read_input { or $self->respond(502, "command unrecognized: '$data'"); last if $self->{_quitting}; } + $self>disconnect; } sub respond { diff --git a/lib/Qpsmtpd.pm b/lib/Qpsmtpd.pm index 6c8d075..4d8c333 100644 --- a/lib/Qpsmtpd.pm +++ b/lib/Qpsmtpd.pm @@ -600,6 +600,14 @@ sub auth_mechanism { return (defined $self->{_auth_mechanism} ? $self->{_auth_mechanism} : "" ); } +sub disconnect { + my $self = shift; + return if $self->connection->notes('disconnected'); # We only disconnect once + $self->run_hooks("disconnect"); + $self->reset_transaction; + $self->connection->notes(disconnected => 1); +} + 1; __END__ diff --git a/lib/Qpsmtpd/PollServer.pm b/lib/Qpsmtpd/PollServer.pm index 9d91af7..854dee8 100644 --- a/lib/Qpsmtpd/PollServer.pm +++ b/lib/Qpsmtpd/PollServer.pm @@ -164,6 +164,7 @@ sub disconnect { sub close { my Qpsmtpd::PollServer $self = shift; + $self->disconnect; $self->run_hooks_no_respond("post-connection"); $self->connection->reset; $self->SUPER::close; diff --git a/lib/Qpsmtpd/SMTP.pm b/lib/Qpsmtpd/SMTP.pm index a820a12..258282c 100644 --- a/lib/Qpsmtpd/SMTP.pm +++ b/lib/Qpsmtpd/SMTP.pm @@ -575,11 +575,7 @@ sub quit_respond { $self->disconnect(); } -sub disconnect { - my $self = shift; - $self->run_hooks("disconnect"); - $self->reset_transaction; -} +sub disconnect { shift->SUPER::disconnect(@_) } sub data { my $self = shift; diff --git a/lib/Qpsmtpd/TcpServer.pm b/lib/Qpsmtpd/TcpServer.pm index df9da9a..cdcb77c 100644 --- a/lib/Qpsmtpd/TcpServer.pm +++ b/lib/Qpsmtpd/TcpServer.pm @@ -100,6 +100,7 @@ sub read_input { alarm $timeout; } alarm(0); + $self->disconnect; } sub respond { diff --git a/lib/Qpsmtpd/TcpServer/Prefork.pm b/lib/Qpsmtpd/TcpServer/Prefork.pm index 28f60dc..9c37fac 100644 --- a/lib/Qpsmtpd/TcpServer/Prefork.pm +++ b/lib/Qpsmtpd/TcpServer/Prefork.pm @@ -35,6 +35,7 @@ sub read_input { or $self->respond(502, "command unrecognized: '$_'"); alarm $timeout; } + $self->disconnect; }; if ($@ =~ /^disconnect_tcpserver/) { die "disconnect_tcpserver"; -- 1.5.6.3