diff options
author | Eric Wong <e@80x24.org> | 2019-06-10 02:34:48 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2019-06-10 05:05:15 +0000 |
commit | 03ddcf8dd905fc5874115ebb30e7cb6e9bd75a3e (patch) | |
tree | 8c85017e313cbbbad2ddbba036812a80a60ecf0e /lib/PublicInbox/NNTP.pm | |
parent | 180fe300da41ab0251147055bbb9ae5d9ebd2b5b (diff) | |
download | public-inbox-03ddcf8dd905fc5874115ebb30e7cb6e9bd75a3e.tar.gz |
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.
Diffstat (limited to 'lib/PublicInbox/NNTP.pm')
-rw-r--r-- | lib/PublicInbox/NNTP.pm | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index 7729399a..5e66d077 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -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); } |