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
This commit is contained in:
parent
90e60d3d4f
commit
8dda36cf02
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user