X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FWwwStream.pm;h=77b6f9c29e4ec675120cd2b47f5c6f003abb8e2f;hb=ab9c03ff4aa369b397dc1a8c8936153c8565fd05;hp=c960edc52fdc545503e9d73ec8444f04c812e62e;hpb=5b96edcb1e0d825244d5a12470e0f32526262611;p=public-inbox.git diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm index c960edc5..77b6f9c2 100644 --- a/lib/PublicInbox/WwwStream.pm +++ b/lib/PublicInbox/WwwStream.pm @@ -1,4 +1,4 @@ -# Copyright (C) 2016-2021 all contributors +# Copyright (C) all contributors # License: AGPL-3.0+ # # HTML body stream for which yields getline+close methods for @@ -27,12 +27,15 @@ sub init { my ($ctx, $cb) = @_; $ctx->{cb} = $cb; $ctx->{base_url} = base_url($ctx); + $ctx->{-res_hdr} = [ 'Content-Type' => 'text/html; charset=UTF-8' ]; + $ctx->{gz} = PublicInbox::GzipFilter::gz_or_noop($ctx->{-res_hdr}, + $ctx->{env}); bless $ctx, __PACKAGE__; } sub async_eml { # for async_blob_cb my ($ctx, $eml) = @_; - $ctx->{http_out}->write($ctx->translate($ctx->{cb}->($ctx, $eml))); + $ctx->write($ctx->{cb}->($ctx, $eml)); } sub html_top ($) { @@ -49,6 +52,8 @@ sub html_top ($) { # we had some kind of query, link to /$INBOX/?t=YYYYMMDDhhmmss } elsif ($ctx->{qp}->{t}) { $top = qq($top); + } elsif (length($upfx)) { + $top = qq($top); } my $code = $ibx->{coderepo} ? qq( / code) : ''; # id=mirror must exist for legacy bookmarks @@ -84,17 +89,17 @@ sub coderepos ($) { my $cr = $ctx->{ibx}->{coderepo} // return (); my $cfg = $ctx->{www}->{pi_cfg}; my $upfx = ($ctx->{-upfx} // ''). '../'; - my @ret; + my $pfx = $ctx->{base_url} //= $ctx->base_url; + my $up = $upfx =~ tr!/!/!; + $pfx =~ s!/[^/]+\z!/! for (1..$up); + my @ret = ('' . + 'Code repositories for project(s) associated with this '. + $ctx->{ibx}->thing_type . "\n"); for my $cr_name (@$cr) { - $ret[0] //= <code repositories for project(s) associated with this inbox: -EOF my $urls = $cfg->get_all("coderepo.$cr_name.cgiturl"); if ($urls) { for (@$urls) { - # relative or absolute URL?, prefix relative - # "foo.git" with appropriate number of "../" - my $u = m!\A(?:[a-z\+]+:)?//! ? $_ : $upfx.$_; + my $u = m!\A(?:[a-z\+]+:)?//! ? $_ : $pfx.$_; $u = ascii_html(prurl($ctx->{env}, $u)); $ret[0] .= qq(\n\t$u); } @@ -107,10 +112,42 @@ EOF sub _html_end { my ($ctx) = @_; - my @cr = coderepos($ctx); - scalar(@cr) ? - '
'.join("\n\n", @cr).'
' : - ''; + my $upfx = $ctx->{-upfx} || ''; + my $m = "${upfx}_/text/mirror/"; + my $x; + if ($ctx->{ibx}->can('cloneurl')) { + $x = <mirroring instructions +for how to clone and mirror all data and code used for this inbox +EOF + my $has_nntp = @{$ctx->{ibx}->nntp_url($ctx)}; + my $has_imap = @{$ctx->{ibx}->imap_url($ctx)}; + if ($has_nntp || $has_imap) { + substr($x, -1, 1) = ";\n"; # s/\n/;\n + if ($has_nntp && $has_imap) { + $x .= <mirroring instructions on how to clone and mirror +all data and code used by this external index. +EOF + } + chomp $x; + '
'.join("\n\n", coderepos($ctx), $x).'
' } # callback for HTTP.pm (and any other PSGI servers) @@ -130,18 +167,26 @@ sub getline { $ctx->zflush(_html_end($ctx)); } -sub html_oneshot ($$;$) { - my ($ctx, $code, $sref) = @_; +sub html_done ($;@) { + my $ctx = $_[0]; + my $bdy = $ctx->zflush(@_[1..$#_], _html_end($ctx)); + my $res_hdr = delete $ctx->{-res_hdr}; + push @$res_hdr, 'Content-Length', length($bdy); + [ 200, $res_hdr, [ $bdy ] ] +} + +sub html_oneshot ($$;@) { + my ($ctx, $code) = @_[0, 1]; my $res_hdr = [ 'Content-Type' => 'text/html; charset=UTF-8', 'Content-Length' => undef ]; bless $ctx, __PACKAGE__; $ctx->{gz} = PublicInbox::GzipFilter::gz_or_noop($res_hdr, $ctx->{env}); - $ctx->{base_url} //= do { - $ctx->zmore(html_top($ctx)); - base_url($ctx); + my @top; + $ctx->{base_url} // do { + @top = html_top($ctx); + $ctx->{base_url} = base_url($ctx); }; - $ctx->zmore($$sref) if $sref; - my $bdy = $ctx->zflush(_html_end($ctx)); + my $bdy = $ctx->zflush(@top, @_[2..$#_], _html_end($ctx)); $res_hdr->[3] = length($bdy); [ $code, $res_hdr, [ $bdy ] ] } @@ -153,8 +198,7 @@ sub async_next ($) { if (my $smsg = $ctx->{smsg} = $ctx->{cb}->($ctx)) { $ctx->smsg_blob($smsg); } else { - $ctx->{http_out}->write( - $ctx->translate(_html_end($ctx))); + $ctx->write(_html_end($ctx)); $ctx->close; # GzipFilter->close } }; @@ -162,10 +206,18 @@ sub async_next ($) { } sub aresponse { - my ($ctx, $code, $cb) = @_; - my $res_hdr = [ 'Content-Type' => 'text/html; charset=UTF-8' ]; + my ($ctx, $cb) = @_; init($ctx, $cb); - $ctx->psgi_response($code, $res_hdr); + $ctx->psgi_response(200, delete $ctx->{-res_hdr}); +} + +sub html_init { + my ($ctx) = @_; + $ctx->{base_url} = base_url($ctx); + my $h = $ctx->{-res_hdr} = ['Content-Type', 'text/html; charset=UTF-8']; + $ctx->{gz} = PublicInbox::GzipFilter::gz_or_noop($h, $ctx->{env}); + bless $ctx, __PACKAGE__; + print { $ctx->zfh } html_top($ctx); } 1;