]> Sergey Matveev's repositories - public-inbox.git/commitdiff
nntp: use sysread to append to existing buffer
authorEric Wong <e@80x24.org>
Mon, 10 Jun 2019 02:34:48 +0000 (02:34 +0000)
committerEric Wong <e@80x24.org>
Mon, 10 Jun 2019 05:05:15 +0000 (05:05 +0000)
We already do this in PublicInbox::HTTP, as it's superior to
DS::read in this regard.  Initially (when I started writing
NNTP.pm, I wanted to use Danga::Socket's read buffering and
push_back_read (removed in DS) but quickly figured out it wasn't
useful at all for dealing with trickling clients.

lib/PublicInbox/NNTP.pm

index 7729399accdd91ff68163cac6a5c89db82cb6434..5e66d077cafee16179490ddf442d0335895e8ab0 100644 (file)
@@ -954,13 +954,20 @@ sub event_write {
 sub event_read {
        my ($self) = @_;
        use constant LINE_MAX => 512; # RFC 977 section 2.3
-
-       if (index($self->{rbuf}, "\n") < 0) {
-               my $buf = $self->read(LINE_MAX) or return $self->close;
-               $self->{rbuf} .= $$buf;
+       my $rbuf = \($self->{rbuf});
+       my $r;
+
+       if (index($$rbuf, "\n") < 0) {
+               my $off = length($$rbuf);
+               $r = sysread($self->{sock}, $$rbuf, LINE_MAX, $off);
+               unless (defined $r) {
+                       return if $!{EAGAIN};
+                       return $self->close;
+               }
+               return $self->close if $r == 0;
        }
-       my $r = 1;
-       while ($r > 0 && $self->{rbuf} =~ s/\A[ \t\r\n]*([^\r\n]*)\r?\n//) {
+       $r = 1;
+       while ($r > 0 && $$rbuf =~ s/\A[ \t\r\n]*([^\r\n]*)\r?\n//) {
                my $line = $1;
                return $self->close if $line =~ /[[:cntrl:]]/s;
                my $t0 = now();
@@ -972,7 +979,7 @@ sub event_read {
        }
 
        return $self->close if $r < 0;
-       my $len = length($self->{rbuf});
+       my $len = length($$rbuf);
        return $self->close if ($len >= LINE_MAX);
        update_idle_time($self);
 }