user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
From: "Eric Wong (Contractor, The Linux Foundation)" <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 2/4] nntp: set Xref across multiple inboxes
Date: Fri,  6 Apr 2018 21:44:37 +0000	[thread overview]
Message-ID: <20180406214439.29591-3-e@80x24.org> (raw)
In-Reply-To: <20180406214439.29591-1-e@80x24.org>

Noted by Jonathan Corbet in https://lwn.net/Articles/748184/
---
 lib/PublicInbox/NNTP.pm | 43 ++++++++++++++++++++++++++++---------------
 t/nntp.t                |  6 ++++--
 2 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index e517935..fa890cb 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -407,12 +407,30 @@ sub header_append ($$$) {
 	$hdr->header_set($k, @v, $v);
 }
 
-sub set_nntp_headers {
-	my ($hdr, $ng, $n, $mid) = @_;
+sub xref ($$$$) {
+	my ($self, $ng, $n, $mid) = @_;
+	my $ret = "$ng->{domain} $ng->{newsgroup}:$n";
+
+	# num_for is pretty cheap and sometimes we'll lookup the existence
+	# of an article without getting even the OVER info.  In other words,
+	# I'm not sure if its worth optimizing by scanning To:/Cc: and
+	# PublicInbox::ExtMsg on the PSGI end is just as expensive
+	foreach my $other (@{$self->{nntpd}->{grouplist}}) {
+		next if $ng eq $other;
+		my $num = eval { $other->mm->num_for($mid) } or next;
+		$ret .= " $other->{newsgroup}:$num";
+	}
+	$ret;
+}
+
+sub set_nntp_headers ($$$$$) {
+	my ($self, $hdr, $ng, $n, $mid) = @_;
 
 	# clobber some
-	$hdr->header_set('Newsgroups', $ng->{newsgroup});
-	$hdr->header_set('Xref', xref($ng, $n));
+	my $xref = xref($self, $ng, $n, $mid);
+	$hdr->header_set('Xref', $xref);
+	$xref =~ s/:\d+//g;
+	$hdr->header_set('Newsgroups', (split(/ /, $xref, 2))[1]);
 	header_append($hdr, 'List-Post', "<mailto:$ng->{-primary_address}>");
 	if (my $url = $ng->base_url) {
 		$mid = mid_escape($mid);
@@ -461,7 +479,7 @@ found:
 	my $msg = $ng->msg_by_smsg($smsg) or return $err;
 	my $s = Email::Simple->new($msg);
 	if ($set_headers) {
-		set_nntp_headers($s->header_obj, $ng, $n, $mid);
+		set_nntp_headers($self, $s->header_obj, $ng, $n, $mid);
 
 		# must be last
 		$s->body_set('') if ($set_headers == 2);
@@ -635,11 +653,6 @@ sub hdr_message_id ($$$) { # optimize XHDR Message-ID [range] for slrnpull.
 	}
 }
 
-sub xref ($$) {
-	my ($ng, $n) = @_;
-	"$ng->{domain} $ng->{newsgroup}:$n"
-}
-
 sub mid_lookup ($$) {
 	my ($self, $mid) = @_;
 	my $self_ng = $self->{ng};
@@ -659,9 +672,11 @@ sub hdr_xref ($$$) { # optimize XHDR Xref [range] for rtin
 	my ($self, $xhdr, $range) = @_;
 
 	if (defined $range && $range =~ /\A<(.+)>\z/) { # Message-ID
-		my ($ng, $n) = mid_lookup($self, $1);
+		my $mid = $1;
+		my ($ng, $n) = mid_lookup($self, $mid);
 		return r430 unless $n;
-		hdr_mid_response($self, $xhdr, $ng, $n, $range, xref($ng, $n));
+		hdr_mid_response($self, $xhdr, $ng, $n, $range,
+				xref($self, $ng, $n, $mid));
 	} else { # numeric range
 		$range = $self->{article} unless defined $range;
 		my $r = get_range($self, $range);
@@ -674,10 +689,8 @@ sub hdr_xref ($$$) { # optimize XHDR Xref [range] for rtin
 			my $r = $mm->msg_range(\$beg, $end);
 			@$r or return;
 			more($self, join("\r\n", map {
-				# TODO: use $_->[1] (mid) to fill
-				# Xref: from other inboxes
 				my $num = $_->[0];
-				"$num ".xref($ng, $num);
+				"$num ".xref($self, $ng, $num, $_->[1]);
 			} @$r));
 			1;
 		});
diff --git a/t/nntp.t b/t/nntp.t
index 03c7f08..57fef48 100644
--- a/t/nntp.t
+++ b/t/nntp.t
@@ -109,7 +109,9 @@ use_ok 'PublicInbox::Inbox';
 	is($ng->base_url, $u, 'URL expanded');
 	my $mid = 'a@b';
 	my $mime = Email::MIME->new("Message-ID: <$mid>\r\n\r\n");
-	PublicInbox::NNTP::set_nntp_headers($mime->header_obj, $ng, 1, $mid);
+	my $hdr = $mime->header_obj;
+	my $mock_self = { nntpd => { grouplist => [] } };
+	PublicInbox::NNTP::set_nntp_headers($mock_self, $hdr, $ng, 1, $mid);
 	is_deeply([ $mime->header('Message-ID') ], [ "<$mid>" ],
 		'Message-ID unchanged');
 	is_deeply([ $mime->header('Archived-At') ], [ "<${u}a\@b/>" ],
@@ -124,7 +126,7 @@ use_ok 'PublicInbox::Inbox';
 		'Xref: set');
 
 	$ng->{-base_url} = 'http://mirror.example.com/m/';
-	PublicInbox::NNTP::set_nntp_headers($mime->header_obj, $ng, 2, $mid);
+	PublicInbox::NNTP::set_nntp_headers($mock_self, $hdr, $ng, 2, $mid);
 	is_deeply([ $mime->header('Message-ID') ], [ "<$mid>" ],
 		'Message-ID unchanged');
 	is_deeply([ $mime->header('Archived-At') ],
-- 
EW


  parent reply	other threads:[~2018-04-06 21:44 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-06 21:44 [PATCH 0/4] a few more odds and ends for v2 Eric Wong (Contractor, The Linux Foundation)
2018-04-06 21:44 ` [PATCH 1/4] altid: fix miscopied field name Eric Wong (Contractor, The Linux Foundation)
2018-04-06 21:44 ` Eric Wong (Contractor, The Linux Foundation) [this message]
2018-04-06 21:44 ` [PATCH 3/4] www: favor reading more from SQLite, and less from Xapian Eric Wong (Contractor, The Linux Foundation)
2018-04-06 21:44 ` [PATCH 4/4] ensure Xapian and SQLite are still optional for v1 tests Eric Wong (Contractor, The Linux Foundation)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180406214439.29591-3-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).