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;
         

Reply via email to