Author: radu
Date: Wed Apr 30 23:15:32 2008
New Revision: 878
Modified:
trunk/lib/Danga/Client.pm
trunk/lib/Qpsmtpd/PollServer.pm
Log:
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.
Modified: trunk/lib/Danga/Client.pm
==============================================================================
--- trunk/lib/Danga/Client.pm (original)
+++ trunk/lib/Danga/Client.pm Wed Apr 30 23:15:32 2008
@@ -54,6 +54,26 @@
$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 @@
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 @@
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) {
Modified: trunk/lib/Qpsmtpd/PollServer.pm
==============================================================================
--- trunk/lib/Qpsmtpd/PollServer.pm (original)
+++ trunk/lib/Qpsmtpd/PollServer.pm Wed Apr 30 23:15:32 2008
@@ -16,7 +16,6 @@
start_time
cmd_timeout
conn
- prev_crlf
_auth
_auth_mechanism
_auth_state
@@ -209,7 +208,6 @@
$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 @@
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;