X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FWWW.pm;h=2434f2f581b2b0fbd1d48d1a08881bf0a1c1187b;hb=31ec75b69e02df6330bc16dd2bd48d354726f4c1;hp=9021cb528e5f8da398e28d79c6ee7bbae787566b;hpb=c477bdd8a80eecc319b680764edfb24bd12cb7b2;p=public-inbox.git diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm index 9021cb52..2434f2f5 100644 --- a/lib/PublicInbox/WWW.pm +++ b/lib/PublicInbox/WWW.pm @@ -1,4 +1,4 @@ -# Copyright (C) 2014-2018 all contributors +# Copyright (C) 2014-2020 all contributors # License: AGPL-3.0+ # # Main web interface for mailing list archives @@ -15,14 +15,13 @@ use 5.010_001; use strict; use warnings; use bytes (); # only for bytes::length -use Plack::Util; use PublicInbox::Config; use PublicInbox::Hval; use URI::Escape qw(uri_unescape); use PublicInbox::MID qw(mid_escape); -require PublicInbox::Git; use PublicInbox::GitHTTPBackend; use PublicInbox::UserContent; +use PublicInbox::WwwStatic qw(r path_info_raw); # TODO: consider a routing tree now that we have more endpoints: our $INBOX_RE = qr!\A/([\w\-][\w\.\-]*)!; @@ -43,17 +42,6 @@ sub run { PublicInbox::WWW->new->call($req->env); } -my %path_re_cache; - -sub path_re ($) { - my $sn = $_[0]->{SCRIPT_NAME}; - $path_re_cache{$sn} ||= do { - $sn = '/'.$sn unless index($sn, '/') == 0; - $sn =~ s!/\z!!; - qr!\A(?:https?://[^/]+)?\Q$sn\E(/[^\?\#]+)!; - }; -} - sub call { my ($self, $env) = @_; my $ctx = { env => $env, www => $self }; @@ -68,9 +56,7 @@ sub call { $k => $v; } split(/[&;]+/, $env->{QUERY_STRING}); - # avoiding $env->{PATH_INFO} here since that's already decoded - my ($path_info) = ($env->{REQUEST_URI} =~ path_re($env)); - $path_info //= $env->{PATH_INFO}; + my $path_info = path_info_raw($env); my $method = $env->{REQUEST_METHOD}; if ($method eq 'POST') { @@ -83,8 +69,8 @@ sub call { return invalid_inbox($ctx, $1) || mbox_results($ctx); } } - elsif ($method !~ /\AGET|HEAD\z/) { - return r(405, 'Method Not Allowed'); + elsif ($method !~ /\A(?:GET|HEAD)\z/) { + return r(405); } # top-level indices and feeds @@ -98,6 +84,8 @@ sub call { invalid_inbox($ctx, $1) || get_atom($ctx); } elsif ($path_info =~ m!$INBOX_RE/new\.html\z!o) { invalid_inbox($ctx, $1) || get_new($ctx); + } elsif ($path_info =~ m!$INBOX_RE/description\z!o) { + get_description($ctx, $1); } elsif ($path_info =~ m!$INBOX_RE/(?:(?:git/)?([0-9]+)(?:\.git)?/)? ($PublicInbox::GitHTTPBackend::ANY)\z!ox) { my ($epoch, $path) = ($2, $3); @@ -144,31 +132,47 @@ sub call { } } -# for CoW-friendliness, MOOOOO! +# for CoW-friendliness, MOOOOO! Even for single-process setups, +# we want to get all immortal allocations done early to avoid heap +# fragmentation since common allocators favor a large contiguous heap. sub preload { my ($self) = @_; + require PublicInbox::ExtMsg; require PublicInbox::Feed; require PublicInbox::View; require PublicInbox::SearchThread; require PublicInbox::MIME; - require Digest::SHA; - require POSIX; + require PublicInbox::Mbox; + require PublicInbox::ViewVCS; + require PublicInbox::WwwText; + require PublicInbox::WwwAttach; eval { require PublicInbox::Search; PublicInbox::Search::load_xapian(); }; - foreach (qw(PublicInbox::SearchView - PublicInbox::Mbox IO::Compress::Gzip - PublicInbox::NewsWWW)) { + foreach (qw(PublicInbox::SearchView PublicInbox::MboxGz)) { eval "require $_;"; } if (ref($self)) { + my $pi_config = $self->{pi_config}; + if (defined($pi_config->{'publicinbox.cgitrc'})) { + $pi_config->limiter('-cgit'); + } $self->cgit; $self->stylesheets_prepare($_) for ('', '../', '../../'); $self->www_listing; + $self->news_www; + $pi_config->each_inbox(\&preload_inbox); } } +sub preload_inbox { + my $ibx = shift; + $ibx->cloneurl; + $ibx->description; + $ibx->base_url; +} + # private functions below sub r404 { @@ -177,12 +181,9 @@ sub r404 { require PublicInbox::ExtMsg; return PublicInbox::ExtMsg::ext_msg($ctx); } - r(404, 'Not Found'); + r(404); } -# simple response for errors -sub r { [ $_[0], ['Content-Type' => 'text/plain'], [ join(' ', @_, "\n") ] ] } - sub news_cgit_fallback ($) { my ($ctx) = @_; my $www = $ctx->{www}; @@ -300,13 +301,6 @@ sub get_vcs_object ($$$;$) { PublicInbox::ViewVCS::show($ctx, $oid, $filename); } -sub ctx_get { - my ($ctx, $key) = @_; - my $val = $ctx->{$key}; - (defined $val && $val ne '') or die "BUG: bad ctx, $key unusable"; - $val; -} - sub need { my ($ctx, $extra) = @_; my $msg = <new($pi_config); } else { + require Plack::Util; Plack::Util::inline_object(call => sub { r404() }); } } @@ -643,4 +638,13 @@ sub get_css ($$$) { [ 200, $h, [ $css ] ]; } +sub get_description { + my ($ctx, $inbox) = @_; + invalid_inbox($ctx, $inbox) || do { + my $d = $ctx->{-inbox}->description . "\n"; + [ 200, [ 'Content-Length', bytes::length($d), + 'Content-Type', 'text/plain' ], [ $d ] ]; + }; +} + 1;