X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FNNTP.pm;h=f0ee11cb0b97a7889cdee091032fccbf9c47eb84;hb=0f432191082f889c4296351e356c4abaf8cc7a28;hp=3d304c52f521ece7fb5d7c84e7e8c3bbd95960ea;hpb=b9a2b0a73585462288a0d82a2293e6ef2d601d2a;p=public-inbox.git diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index 3d304c52..f0ee11cb 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -24,12 +24,11 @@ use constant { LINE_MAX => 512, # RFC 977 section 2.3 r501 => '501 command syntax error', r502 => '502 Command unavailable', - r221 => '221 Header follows', + r221 => "221 Header follows\r\n", r224 => '224 Overview information follows (multi-line)', - r225 => '225 Headers follow (multi-line)', + r225 => "225 Headers follow (multi-line)\r\n", r430 => '430 No article with that message-id', }; -use PublicInbox::Syscall qw(EPOLLIN EPOLLONESHOT); use Errno qw(EAGAIN); my $ONE_MSGID = qr/\A$MID_EXTRACT\z/; my @OVERVIEW = qw(Subject From Date Message-ID References); @@ -47,25 +46,11 @@ HDR\r OVER\r COMPRESS DEFLATE\r -sub greet ($) { $_[0]->write($_[0]->{nntpd}->{greet}) }; - -sub new ($$$) { - my ($class, $sock, $nntpd) = @_; - my $self = bless { nntpd => $nntpd }, $class; - my $ev = EPOLLIN; - my $wbuf; - if ($sock->can('accept_SSL') && !$sock->accept_SSL) { - return CORE::close($sock) if $! != EAGAIN; - $ev = PublicInbox::TLS::epollbit() or return CORE::close($sock); - $wbuf = [ \&PublicInbox::DS::accept_tls_step, \&greet ]; - } - $self->SUPER::new($sock, $ev | EPOLLONESHOT); - if ($wbuf) { - $self->{wbuf} = $wbuf; - } else { - greet($self); - } - $self; +sub do_greet ($) { $_[0]->write($_[0]->{nntpd}->{greet}) }; + +sub new { + my ($cls, $sock, $nntpd) = @_; + (bless { nntpd => $nntpd }, $cls)->greet($sock) } sub args_ok ($$) { @@ -82,8 +67,8 @@ sub process_line ($$) { my ($self, $l) = @_; my ($req, @args) = split(/[ \t]+/, $l); return 1 unless defined($req); # skip blank line - $req = $self->can('cmd_'.lc($req)); - return res($self, '500 command not recognized') unless $req; + $req = $self->can('cmd_'.lc($req)) // + return $self->write(\"500 command not recognized\r\n"); return res($self, r501) unless args_ok($req, scalar @args); my $res = eval { $req->($self, @args) }; @@ -117,7 +102,7 @@ sub cmd_slave ($) { '202 slave status noted' } sub cmd_xgtitle ($;$) { my ($self, $wildmat) = @_; - more($self, '282 list of groups and descriptions follows'); + $self->msg_more("282 list of groups and descriptions follows\r\n"); list_newsgroups($self, $wildmat); } @@ -150,7 +135,7 @@ sub list_active_times_i { for my $ngname (@window) { my $ibx = $groups->{$ngname} or next; my $c = eval { $ibx->uidvalidity } // time; - more($self, "$ngname $c <$ibx->{-primary_address}>"); + $self->msg_more("$ngname $c <$ibx->{-primary_address}>\r\n"); } scalar(@$groupnames); # continue if there's more } @@ -169,7 +154,7 @@ sub list_newsgroups_i { my $ibx; for my $ngname (@window) { $ibx = $groups->{$ngname} and - more($self, "$ngname ".$ibx->description); + $self->msg_more("$ngname ".$ibx->description."\r\n"); } scalar(@$groupnames); # continue if there's more } @@ -191,10 +176,10 @@ sub cmd_list ($;$$) { $arg = "list_$arg"; $arg = $self->can($arg); return r501 unless $arg && args_ok($arg, scalar @args); - more($self, '215 information follows'); + $self->msg_more("215 information follows\r\n"); $arg->($self, @args); } else { - more($self, '215 list of newsgroups follows'); + $self->msg_more("215 list of newsgroups follows\r\n"); long_response($self, \&list_active_i, [ # copy array @{$self->{nntpd}->{groupnames}} ]); } @@ -212,7 +197,7 @@ sub listgroup_all_i { my ($self, $num) = @_; my $ary = $self->{ibx}->over(1)->ids_after($num); scalar(@$ary) or return; - more($self, join("\r\n", @$ary)); + $self->msg_more(join("\r\n", @$ary, '')); 1; } @@ -221,7 +206,7 @@ sub cmd_listgroup ($;$$) { if (defined $group) { my $res = cmd_group($self, $group); return $res if ($res !~ /\A211 /); - more($self, $res); + $self->msg_more($res .= "\r\n"); } $self->{ibx} or return '412 no newsgroup selected'; if (defined $range) { @@ -262,7 +247,7 @@ sub parse_time ($$;$) { sub group_line ($$) { my ($self, $ibx) = @_; my ($min, $max) = $ibx->mm(1)->minmax; - more($self, "$ibx->{newsgroup} $max $min n"); + $self->msg_more("$ibx->{newsgroup} $max $min n\r\n"); } sub newgroups_i { @@ -284,7 +269,7 @@ sub cmd_newgroups ($$$;$$) { return r501 if $@; # TODO dists - more($self, '231 list of new newsgroups follows'); + $self->msg_more("231 list of new newsgroups follows\r\n"); long_response($self, \&newgroups_i, $ts, \(my $i = 0), $self->{nntpd}->{groupnames}); } @@ -348,7 +333,7 @@ sub cmd_newnews ($$$$;$$) { my ($self, $newsgroups, $date, $time, $gmt, $dists) = @_; my $ts = eval { parse_time($date, $time, $gmt) }; return r501 if $@; - more($self, '230 list of new articles by message-id follows'); + $self->msg_more("230 list of new articles by message-id follows\r\n"); my ($keep, $skip) = split(/!/, $newsgroups, 2); ngpat2re($keep); ngpat2re($skip); @@ -403,7 +388,7 @@ sub cmd_post ($) { sub cmd_quit ($) { my ($self) = @_; - res($self, '205 closing connection - goodbye!'); + $self->write(\"205 closing connection - goodbye!\r\n"); $self->shutdn; undef; } @@ -565,15 +550,15 @@ sub blob_cb { # called by git->cat_async via ibx_async_cat my $r = "$code $smsg->{num} <$smsg->{mid}> article retrieved - "; my $eml = PublicInbox::Eml->new($bref); if ($code == 220) { - more($self, $r .= 'head and body follow'); + $self->msg_more($r .= "head and body follow\r\n"); msg_hdr_write($eml, $smsg); $self->msg_more("\r\n"); msg_body_write($self, $bref); } elsif ($code == 221) { - more($self, $r .= 'head follows'); + $self->msg_more($r .= "head follows\r\n"); msg_hdr_write($eml, $smsg); } elsif ($code == 222) { - more($self, $r .= 'body follows'); + $self->msg_more($r .= "body follows\r\n"); msg_body_write($self, $bref); } else { $self->close; @@ -609,7 +594,7 @@ sub cmd_date ($) { '111 '.strftime('%Y%m%d%H%M%S', gmtime(time)) } sub cmd_help ($) { my ($self) = @_; - more($self, '100 help text follows'); + $self->msg_more("100 help text follows\r\n"); '.' } @@ -663,7 +648,7 @@ sub long_step { $self->requeue if $new_size == 1; } else { # all done! delete $self->{long_cb}; - res($self, '.'); + $self->write(\".\r\n"); my $elapsed = now() - $t0; my $fd = fileno($self->{sock}); out($self, " deferred[$fd] done - %0.6f", $elapsed); @@ -703,7 +688,7 @@ sub hdr_message_id ($$$) { # optimize XHDR Message-ID [range] for slrnpull. $range = $self->{article} unless defined $range; my $r = get_range($self, $range); return $r unless ref $r; - more($self, $xhdr ? r221 : r225); + $self->msg_more($xhdr ? r221 : r225); long_response($self, \&hdr_msgid_range_i, @$r); } } @@ -775,7 +760,7 @@ sub hdr_xref ($$$) { # optimize XHDR Xref [range] for rtin $range = $self->{article} unless defined $range; my $r = get_range($self, $range); return $r unless ref $r; - more($self, $xhdr ? r221 : r225); + $self->msg_more($xhdr ? r221 : r225); long_response($self, \&xref_range_i, @$r); } } @@ -819,7 +804,7 @@ sub hdr_smsg ($$$$) { $range = $self->{article} unless defined $range; my $r = get_range($self, $range); return $r unless ref $r; - more($self, $xhdr ? r221 : r225); + $self->msg_more($xhdr ? r221 : r225); long_response($self, \&smsg_range_i, @$r, $field); } } @@ -837,7 +822,7 @@ sub do_hdr ($$$;$) { } elsif ($sub =~ /\A:(bytes|lines)\z/) { hdr_smsg($self, $xhdr, $1, $range); } else { - $xhdr ? (r221 . "\r\n.") : "503 HDR not permitted on $header"; + $xhdr ? (r221 . '.') : "503 HDR not permitted on $header"; } } @@ -867,23 +852,16 @@ sub hdr_mid_prefix ($$$$$) { sub hdr_mid_response ($$$$$$) { my ($self, $xhdr, $ibx, $n, $mid, $v) = @_; - my $res = ''; - if ($xhdr) { - $res .= r221 . "\r\n"; - $res .= "$mid $v\r\n"; - } else { - $res .= r225 . "\r\n"; - my $pfx = hdr_mid_prefix($self, $xhdr, $ibx, $n, $mid); - $res .= "$pfx $v\r\n"; - } - res($self, $res .= '.'); + $self->write(($xhdr ? r221.$mid : + r225.hdr_mid_prefix($self, $xhdr, $ibx, $n, $mid)) . + " $v\r\n.\r\n"); undef; } sub xrover_i { my ($self, $beg, $end) = @_; my $h = over_header_for($self->{ibx}, $$beg, 'references'); - more($self, "$$beg $h") if defined($h); + $self->msg_more("$$beg $h\r\n") if defined($h); $$beg++ < $end; } @@ -896,7 +874,7 @@ sub cmd_xrover ($;$) { $range = $self->{article} unless defined $range; my $r = get_range($self, $range); return $r unless ref $r; - more($self, '224 Overview information follows'); + $self->msg_more("224 Overview information follows\r\n"); long_response($self, \&xrover_i, @$r); } @@ -923,7 +901,8 @@ sub cmd_over ($;$) { my ($ibx, $n) = mid_lookup($self, $1); defined $n or return r430; my $smsg = $ibx->over(1)->get_art($n) or return r430; - more($self, '224 Overview information follows (multi-line)'); + $self->msg_more( + "224 Overview information follows (multi-line)\r\n"); # Only set article number column if it's the current group # (RFC 3977 8.3.2) @@ -959,7 +938,8 @@ sub cmd_xover ($;$) { my $r = get_range($self, $range); return $r unless ref $r; my ($beg, $end) = @$r; - more($self, "224 Overview information follows for $$beg to $end"); + $self->msg_more( + "224 Overview information follows for $$beg to $end\r\n"); long_response($self, \&xover_i, @$r); } @@ -972,7 +952,7 @@ sub cmd_starttls ($) { return r502 if ($sock->can('accept_SSL') || $self->compressed); my $opt = $self->{nntpd}->{accept_tls} or return '580 can not initiate TLS negotiation'; - res($self, '382 Continue with TLS negotiation'); + $self->write(\"382 Continue with TLS negotiation\r\n"); $self->{sock} = IO::Socket::SSL->start_SSL($sock, %$opt); $self->requeue if PublicInbox::DS::accept_tls_step($self); undef; @@ -988,8 +968,6 @@ sub cmd_compress ($$) { undef } -sub zflush {} # overridden by NNTPdeflate - sub cmd_xpath ($$) { my ($self, $mid) = @_; return r501 unless $mid =~ $ONE_MSGID; @@ -1021,8 +999,6 @@ sub cmd_xpath ($$) { sub res ($$) { do_write($_[0], $_[1] . "\r\n") } -sub more ($$) { $_[0]->msg_more($_[1] . "\r\n") } - sub do_write ($$) { my $self = $_[0]; my $done = $self->write(\($_[1]));