From 8dda36cf023a5f2addb283971731b0ce031c9467 Mon Sep 17 00:00:00 2001 From: Radu Greab Date: Thu, 1 May 2008 06:15:32 +0000 Subject: [PATCH] New fix for the problem of End-of-data splitted across packets. Previous fix does not work for other cases, for example: packet ends with CRLFdot, next packet starts with CRLF. Danga::Client will send now full text lines to the callback. git-svn-id: https://svn.perl.org/qpsmtpd/trunk@878 958fd67b-6ff1-0310-b445-bb7760255be9 --- lib/Danga/Client.pm | 26 +++++++++++++++++++++++--- lib/Qpsmtpd/PollServer.pm | 9 +-------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/Danga/Client.pm b/lib/Danga/Client.pm index bac0eae..804319a 100644 --- a/lib/Danga/Client.pm +++ b/lib/Danga/Client.pm @@ -54,6 +54,26 @@ sub get_bytes { $self->{callback} = $callback; } +sub process_chunk { + my Danga::Client $self = shift; + my $callback = shift; + + my $last_crlf = rindex($self->{line}, "\r\n"); + + if ($last_crlf != -1) { + if ($last_crlf + 2 == length($self->{line})) { + my $data = $self->{line}; + $self->{line} = ''; + $callback->($data); + } + else { + my $data = substr($self->{line}, 0, $last_crlf + 2); + $self->{line} = substr($self->{line}, $last_crlf + 2); + $callback->($data); + } + } +} + sub get_chunks { my Danga::Client $self = shift; my ($bytes, $callback) = @_; @@ -61,8 +81,7 @@ sub get_chunks { die "get_bytes/get_chunks currently in progress!"; } $self->{read_bytes} = $bytes; - $callback->($self->{line}) if length($self->{line}); - $self->{line} = ''; + $self->process_chunk($callback) if length($self->{line}); $self->{callback} = $callback; $self->{get_chunks} = 1; } @@ -84,7 +103,8 @@ sub event_read { if ($self->{get_chunks}) { my $bref = $self->read($self->{read_bytes}); return $self->close($!) unless defined $bref; - $self->{callback}->($$bref) if length($$bref); + $self->{line} .= $$bref; + $self->process_chunk($self->{callback}) if length($self->{line}); return; } if ($self->{read_bytes} > 0) { diff --git a/lib/Qpsmtpd/PollServer.pm b/lib/Qpsmtpd/PollServer.pm index ff2bdbb..81f0d6d 100644 --- a/lib/Qpsmtpd/PollServer.pm +++ b/lib/Qpsmtpd/PollServer.pm @@ -16,7 +16,6 @@ use fields qw( start_time cmd_timeout conn - prev_crlf _auth _auth_mechanism _auth_state @@ -209,7 +208,6 @@ sub data_respond { $self->{header_lines} = ''; $self->{data_size} = 0; $self->{in_header} = 1; - $self->{prev_crlf} = 0; $self->{max_size} = ($self->config('databytes'))[0] || 0; $self->log(LOGDEBUG, "max_size: $self->{max_size} / size: $self->{data_size}"); @@ -227,18 +225,13 @@ sub got_data { my $done = 0; my $remainder; - if ($data =~ s/\r\n\.\r\n(.*)\z/\r\n/ms - || - ($self->{prev_crlf} && $data =~ s/^\.\r\n(.*)\z//ms) - ) - { + if ($data =~ s/^\.\r\n(.*)\z//ms) { $remainder = $1; $done = 1; } # add a transaction->blocked check back here when we have line by line plugin access... unless (($self->{max_size} and $self->{data_size} > $self->{max_size})) { - $self->{prev_crlf} = $data =~ /\r\n\z/; $data =~ s/\r\n/\n/mg; $data =~ s/^\.\./\./mg;