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;
|
$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 {
|
sub get_chunks {
|
||||||
my Danga::Client $self = shift;
|
my Danga::Client $self = shift;
|
||||||
my ($bytes, $callback) = @_;
|
my ($bytes, $callback) = @_;
|
||||||
@ -61,8 +81,7 @@ sub get_chunks {
|
|||||||
die "get_bytes/get_chunks currently in progress!";
|
die "get_bytes/get_chunks currently in progress!";
|
||||||
}
|
}
|
||||||
$self->{read_bytes} = $bytes;
|
$self->{read_bytes} = $bytes;
|
||||||
$callback->($self->{line}) if length($self->{line});
|
$self->process_chunk($callback) if length($self->{line});
|
||||||
$self->{line} = '';
|
|
||||||
$self->{callback} = $callback;
|
$self->{callback} = $callback;
|
||||||
$self->{get_chunks} = 1;
|
$self->{get_chunks} = 1;
|
||||||
}
|
}
|
||||||
@ -84,7 +103,8 @@ sub event_read {
|
|||||||
if ($self->{get_chunks}) {
|
if ($self->{get_chunks}) {
|
||||||
my $bref = $self->read($self->{read_bytes});
|
my $bref = $self->read($self->{read_bytes});
|
||||||
return $self->close($!) unless defined $bref;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if ($self->{read_bytes} > 0) {
|
if ($self->{read_bytes} > 0) {
|
||||||
|
@ -16,7 +16,6 @@ use fields qw(
|
|||||||
start_time
|
start_time
|
||||||
cmd_timeout
|
cmd_timeout
|
||||||
conn
|
conn
|
||||||
prev_crlf
|
|
||||||
_auth
|
_auth
|
||||||
_auth_mechanism
|
_auth_mechanism
|
||||||
_auth_state
|
_auth_state
|
||||||
@ -209,7 +208,6 @@ sub data_respond {
|
|||||||
$self->{header_lines} = '';
|
$self->{header_lines} = '';
|
||||||
$self->{data_size} = 0;
|
$self->{data_size} = 0;
|
||||||
$self->{in_header} = 1;
|
$self->{in_header} = 1;
|
||||||
$self->{prev_crlf} = 0;
|
|
||||||
$self->{max_size} = ($self->config('databytes'))[0] || 0;
|
$self->{max_size} = ($self->config('databytes'))[0] || 0;
|
||||||
|
|
||||||
$self->log(LOGDEBUG, "max_size: $self->{max_size} / size: $self->{data_size}");
|
$self->log(LOGDEBUG, "max_size: $self->{max_size} / size: $self->{data_size}");
|
||||||
@ -227,18 +225,13 @@ sub got_data {
|
|||||||
|
|
||||||
my $done = 0;
|
my $done = 0;
|
||||||
my $remainder;
|
my $remainder;
|
||||||
if ($data =~ s/\r\n\.\r\n(.*)\z/\r\n/ms
|
if ($data =~ s/^\.\r\n(.*)\z//ms) {
|
||||||
||
|
|
||||||
($self->{prev_crlf} && $data =~ s/^\.\r\n(.*)\z//ms)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
$remainder = $1;
|
$remainder = $1;
|
||||||
$done = 1;
|
$done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# add a transaction->blocked check back here when we have line by line plugin access...
|
# 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})) {
|
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/\r\n/\n/mg;
|
||||||
$data =~ s/^\.\./\./mg;
|
$data =~ s/^\.\./\./mg;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user