X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FWWW.pm;h=570e690ec8136ca7cf6c98b4ea0138da42c57032;hb=5c8909925072804901e9c3b45bbf25446d379e7b;hp=cdbcff1e1c876d176e334336ad6c315a036f5fab;hpb=d2eb1ae16e4d3aaa5bece96f17b2fa4561d5b18e;p=public-inbox.git diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm index cdbcff1e..570e690e 100644 --- a/lib/PublicInbox/WWW.pm +++ b/lib/PublicInbox/WWW.pm @@ -1,4 +1,4 @@ -# Copyright (C) 2014-2020 all contributors +# Copyright (C) 2014-2021 all contributors # License: AGPL-3.0+ # # Main web interface for mailing list archives @@ -11,10 +11,8 @@ # - Must not rely on static content # - UTF-8 is only for user-content, 7-bit US-ASCII for us package PublicInbox::WWW; -use 5.010_001; use strict; -use warnings; -use bytes (); # only for bytes::length +use v5.10.1; use PublicInbox::Config; use PublicInbox::Hval; use URI::Escape qw(uri_unescape); @@ -32,9 +30,8 @@ our $ATTACH_RE = qr!([0-9][0-9\.]*)-($PublicInbox::Hval::FN)!; our $OID_RE = qr![a-f0-9]{7,}!; sub new { - my ($class, $pi_config) = @_; - $pi_config ||= PublicInbox::Config->new; - bless { pi_config => $pi_config }, $class; + my ($class, $pi_cfg) = @_; + bless { pi_cfg => $pi_cfg // PublicInbox::Config->new }, $class; } # backwards compatibility, do not use @@ -51,10 +48,9 @@ sub call { %{$ctx->{qp}} = map { utf8::decode($_); tr/+/ /; - my ($k, $v) = split('=', $_, 2); - $v = uri_unescape($v // ''); + my ($k, $v) = split(/=/, $_, 2); # none of the keys we care about will need escaping - $k => $v; + ($k // '', uri_unescape($v // '')) } split(/[&;]+/, $env->{QUERY_STRING}); my $path_info = path_info_raw($env); @@ -135,7 +131,8 @@ sub call { # convenience redirects order matters } elsif ($path_info =~ m!$INBOX_RE/([^/]{2,})\z!o) { r301($ctx, $1, $2); - + } elsif ($path_info =~ m!\A/\+/([a-zA-Z0-9_\-\.]+)\.css\z!) { + get_css($ctx, undef, $1); # for WwwListing } else { legacy_redirects($ctx, $path_info); } @@ -169,14 +166,14 @@ sub preload { eval "require PublicInbox::$_;"; } if (ref($self)) { - my $pi_config = $self->{pi_config}; - if (defined($pi_config->{'publicinbox.cgitrc'})) { - $pi_config->limiter('-cgit'); + my $pi_cfg = $self->{pi_cfg}; + if (defined($pi_cfg->{'publicinbox.cgitrc'})) { + $pi_cfg->limiter('-cgit'); } $self->cgit; $self->stylesheets_prepare($_) for ('', '../', '../../'); $self->news_www; - $pi_config->each_inbox(\&preload_inbox); + $pi_cfg->each_inbox(\&preload_inbox); } } @@ -210,10 +207,10 @@ sub news_cgit_fallback ($) { # returns undef if valid, array ref response if invalid sub invalid_inbox ($$) { my ($ctx, $inbox) = @_; - my $ibx = $ctx->{www}->{pi_config}->lookup_name($inbox) // - $ctx->{www}->{pi_config}->lookup_ei($inbox); + my $ibx = $ctx->{www}->{pi_cfg}->lookup_name($inbox) // + $ctx->{www}->{pi_cfg}->lookup_ei($inbox); if (defined $ibx) { - $ctx->{-inbox} = $ibx; + $ctx->{ibx} = $ibx; return; } @@ -231,11 +228,11 @@ sub invalid_inbox_mid { return $ret if $ret; my $mid = $ctx->{mid} = uri_unescape($mid_ue); - my $ibx = $ctx->{-inbox}; + my $ibx = $ctx->{ibx}; if ($mid =~ m!\A([a-f0-9]{2})([a-f0-9]{38})\z!) { my ($x2, $x38) = ($1, $2); # this is horrifically wasteful for legacy URLs: - my $str = $ctx->{-inbox}->msg_by_path("$x2/$x38") or return; + my $str = $ctx->{ibx}->msg_by_path("$x2/$x38") or return; my $s = PublicInbox::Eml->new($str); $mid = PublicInbox::MID::mid_clean($s->header_raw('Message-ID')); return r301($ctx, $inbox, mid_escape($mid)); @@ -273,7 +270,7 @@ sub get_index { sub get_mid_txt { my ($ctx) = @_; require PublicInbox::Mbox; - PublicInbox::Mbox::emit_raw($ctx) || r404($ctx); + PublicInbox::Mbox::emit_raw($ctx) || r(404); } # /$INBOX/$MESSAGE_ID/ -> HTML content (short quotes) @@ -286,7 +283,7 @@ sub get_mid_html { # /$INBOX/$MESSAGE_ID/t/ sub get_thread { my ($ctx, $flat) = @_; - $ctx->{-inbox}->over or return need($ctx, 'Overview'); + $ctx->{ibx}->over or return need($ctx, 'Overview'); $ctx->{flat} = $flat; require PublicInbox::View; PublicInbox::View::thread_html($ctx); @@ -310,7 +307,7 @@ sub get_text { sub get_vcs_object ($$$;$) { my ($ctx, $inbox, $oid, $filename) = @_; my $r404 = invalid_inbox($ctx, $inbox); - return $r404 if $r404; + return $r404 if $r404 || !$ctx->{www}->{pi_cfg}->repo_objs($ctx->{ibx}); require PublicInbox::ViewVCS; PublicInbox::ViewVCS::show($ctx, $oid, $filename); } @@ -339,7 +336,7 @@ EOF # especially on older systems. Stick to zlib since that's what git uses. sub get_thread_mbox { my ($ctx, $sfx) = @_; - my $over = $ctx->{-inbox}->over or return need($ctx, 'Overview'); + my $over = $ctx->{ibx}->over or return need($ctx, 'Overview'); require PublicInbox::Mbox; PublicInbox::Mbox::thread_mbox($ctx, $over, $sfx); } @@ -348,7 +345,7 @@ sub get_thread_mbox { # /$INBOX/$MESSAGE_ID/t.atom -> thread as Atom feed sub get_thread_atom { my ($ctx) = @_; - $ctx->{-inbox}->over or return need($ctx, 'Overview'); + $ctx->{ibx}->over or return need($ctx, 'Overview'); require PublicInbox::Feed; PublicInbox::Feed::generate_thread_atom($ctx); } @@ -413,11 +410,11 @@ sub legacy_redirects { sub r301 { my ($ctx, $inbox, $mid_ue, $suffix) = @_; - my $ibx = $ctx->{-inbox}; + my $ibx = $ctx->{ibx}; unless ($ibx) { my $r404 = invalid_inbox($ctx, $inbox); return $r404 if $r404; - $ibx = $ctx->{-inbox}; + $ibx = $ctx->{ibx}; } my $url = $ibx->base_url($ctx->{env}); my $qs = $ctx->{env}->{QUERY_STRING}; @@ -454,7 +451,7 @@ sub msg_page { sub serve_git { my ($ctx, $epoch, $path) = @_; my $env = $ctx->{env}; - my $ibx = $ctx->{-inbox}; + my $ibx = $ctx->{ibx}; my $git = defined $epoch ? $ibx->git_epoch($epoch) : $ibx->git; $git ? PublicInbox::GitHTTPBackend::serve($env, $git, $path) : r404(); } @@ -462,7 +459,7 @@ sub serve_git { sub mbox_results { my ($ctx) = @_; if ($ctx->{env}->{QUERY_STRING} =~ /(?:\A|[&;])q=/) { - $ctx->{-inbox}->search or return need($ctx, 'search'); + $ctx->{ibx}->isrch or return need($ctx, 'search'); require PublicInbox::SearchView; return PublicInbox::SearchView::mbox_results($ctx); } @@ -481,18 +478,18 @@ sub news_www { my ($self) = @_; $self->{news_www} ||= do { require PublicInbox::NewsWWW; - PublicInbox::NewsWWW->new($self->{pi_config}); + PublicInbox::NewsWWW->new($self->{pi_cfg}); } } sub cgit { my ($self) = @_; $self->{cgit} ||= do { - my $pi_config = $self->{pi_config}; + my $pi_cfg = $self->{pi_cfg}; - if (defined($pi_config->{'publicinbox.cgitrc'})) { + if (defined($pi_cfg->{'publicinbox.cgitrc'})) { require PublicInbox::Cgit; - PublicInbox::Cgit->new($pi_config); + PublicInbox::Cgit->new($pi_cfg); } else { require Plack::Util; Plack::Util::inline_object(call => sub { r404() }); @@ -506,7 +503,7 @@ sub get_inbox_manifest ($$$) { my $r404 = invalid_inbox($ctx, $inbox); return $r404 if $r404; require PublicInbox::ManifestJsGz; - PublicInbox::ManifestJsGz->response($ctx); + PublicInbox::ManifestJsGz::per_inbox($ctx); } sub get_attach { @@ -538,7 +535,7 @@ sub stylesheets_prepare ($$) { } || sub { $_[0] }; my $css_map = {}; - my $stylesheets = $self->{pi_config}->{css} || []; + my $stylesheets = $self->{pi_cfg}->{css} || []; my $links = []; my $inline_ok = 1; @@ -629,24 +626,25 @@ sub style { }; } -# /$INBOX/$KEY.css endpoint +# /$INBOX/$KEY.css and /+/$KEY.css endpoints # CSS is configured globally for all inboxes, but we access them on # a per-inbox basis. This allows administrators to setup per-inbox # static routes to intercept the request before it hits PSGI +# inbox == undef => top-level WwwListing sub get_css ($$$) { my ($ctx, $inbox, $key) = @_; - my $r404 = invalid_inbox($ctx, $inbox); + my $r404 = defined($inbox) ? invalid_inbox($ctx, $inbox) : undef; return $r404 if $r404; my $self = $ctx->{www}; - my $css_map = $self->{-css_map} || stylesheets_prepare($self, ''); + my $css_map = $self->{-css_map} || + stylesheets_prepare($self, defined($inbox) ? '' : '+/'); my $css = $css_map->{$key}; - if (!defined($css) && $key eq 'userContent') { + if (!defined($css) && defined($inbox) && $key eq 'userContent') { my $env = $ctx->{env}; - $css = PublicInbox::UserContent::sample($ctx->{-inbox}, $env); + $css = PublicInbox::UserContent::sample($ctx->{ibx}, $env); } defined $css or return r404(); - my $h = [ 'Content-Length', bytes::length($css), - 'Content-Type', 'text/css' ]; + my $h = [ 'Content-Length', length($css), 'Content-Type', 'text/css' ]; PublicInbox::GitHTTPBackend::cache_one_year($h); [ 200, $h, [ $css ] ]; } @@ -654,8 +652,9 @@ sub get_css ($$$) { sub get_description { my ($ctx, $inbox) = @_; invalid_inbox($ctx, $inbox) || do { - my $d = $ctx->{-inbox}->description . "\n"; - [ 200, [ 'Content-Length', bytes::length($d), + my $d = $ctx->{ibx}->description . "\n"; + utf8::encode($d); + [ 200, [ 'Content-Length', length($d), 'Content-Type', 'text/plain' ], [ $d ] ]; }; }