X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FWWW.pm;h=4b7177c1b157b2e4c2b5a7f8841123f287c928a1;hb=f9fc5cf2e8cefda4a56d937ed217e47689fd7e49;hp=0f963dcbd907af3097ed5d0a8462c20acee3a0d9;hpb=70caf43a131fc5bdf7104f82f2acee9d5353d6a8;p=public-inbox.git
diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm
index 0f963dcb..4b7177c1 100644
--- a/lib/PublicInbox/WWW.pm
+++ b/lib/PublicInbox/WWW.pm
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2018 all contributors
+# Copyright (C) 2014-2019 all contributors
# License: AGPL-3.0+
#
# Main web interface for mailing list archives
@@ -28,7 +28,7 @@ use PublicInbox::UserContent;
our $INBOX_RE = qr!\A/([\w\-][\w\.\-]*)!;
our $MID_RE = qr!([^/]+)!;
our $END_RE = qr!(T/|t/|t\.mbox(?:\.gz)?|t\.atom|raw|)!;
-our $ATTACH_RE = qr!(\d[\.\d]*)-([[:alnum:]][\w\.-]+[[:alnum:]])!i;
+our $ATTACH_RE = qr!([0-9][0-9\.]*)-($PublicInbox::Hval::FN)!;
our $OID_RE = qr![a-f0-9]{7,40}!;
sub new {
@@ -59,14 +59,14 @@ sub call {
my $ctx = { env => $env, www => $self };
# we don't care about multi-value
- my %qp = map {
+ %{$ctx->{qp}} = map {
utf8::decode($_);
- my ($k, $v) = split('=', uri_unescape($_), 2);
- $v = '' unless defined $v;
- $v =~ tr/+/ /;
- ($k, $v)
+ tr/+/ /;
+ my ($k, $v) = split('=', $_, 2);
+ $v = uri_unescape($v // '');
+ # none of the keys we care about will need escaping
+ $k => $v;
} split(/[&;]+/, $env->{QUERY_STRING});
- $ctx->{qp} = \%qp;
# avoiding $env->{PATH_INFO} here since that's already decoded
my ($path_info) = ($env->{REQUEST_URI} =~ path_re($env));
@@ -74,10 +74,11 @@ sub call {
my $method = $env->{REQUEST_METHOD};
if ($method eq 'POST') {
- if ($path_info =~ m!$INBOX_RE/(?:(\d+)/)?(git-upload-pack)\z!) {
- my ($part, $path) = ($2, $3);
+ if ($path_info =~ m!$INBOX_RE/(?:(?:git/)?([0-9]+)(?:\.git)?/)?
+ (git-upload-pack)\z!x) {
+ my ($epoch, $path) = ($2, $3);
return invalid_inbox($ctx, $1) ||
- serve_git($ctx, $part, $path);
+ serve_git($ctx, $epoch, $path);
} elsif ($path_info =~ m!$INBOX_RE/!o) {
return invalid_inbox($ctx, $1) || mbox_results($ctx);
}
@@ -87,7 +88,7 @@ sub call {
}
# top-level indices and feeds
- if ($path_info eq '/') {
+ if ($path_info eq '/' || $path_info eq '/manifest.js.gz') {
www_listing($self)->call($env);
} elsif ($path_info =~ m!$INBOX_RE\z!o) {
invalid_inbox($ctx, $1) || r301($ctx, $1);
@@ -97,11 +98,11 @@ 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/(?:(\d+)/)?
+ } elsif ($path_info =~ m!$INBOX_RE/(?:(?:git/)?([0-9]+)(?:\.git)?/)?
($PublicInbox::GitHTTPBackend::ANY)\z!ox) {
- my ($part, $path) = ($2, $3);
- invalid_inbox($ctx, $1) || serve_git($ctx, $part, $path);
- } elsif ($path_info =~ m!$INBOX_RE/([\w-]+).mbox\.gz\z!o) {
+ my ($epoch, $path) = ($2, $3);
+ invalid_inbox($ctx, $1) || serve_git($ctx, $epoch, $path);
+ } elsif ($path_info =~ m!$INBOX_RE/([a-zA-Z0-9_\-]+).mbox\.gz\z!o) {
serve_mbox_range($ctx, $1, $2);
} elsif ($path_info =~ m!$INBOX_RE/$MID_RE/$END_RE\z!o) {
msg_page($ctx, $1, $2, $3);
@@ -123,11 +124,14 @@ sub call {
r301($ctx, $1, $2);
} elsif ($path_info =~ m!$INBOX_RE/_/text(?:/(.*))?\z!o) {
get_text($ctx, $1, $2);
- } elsif ($path_info =~ m!$INBOX_RE/([\w\-\.]+)\.css\z!o) {
+ } elsif ($path_info =~ m!$INBOX_RE/([a-zA-Z0-9_\-\.]+)\.css\z!o) {
get_css($ctx, $1, $2);
+ } elsif ($path_info =~ m!$INBOX_RE/manifest\.js\.gz\z!o) {
+ get_inbox_manifest($ctx, $1, $2);
} elsif ($path_info =~ m!$INBOX_RE/($OID_RE)/s/\z!o) {
get_vcs_object($ctx, $1, $2);
- } elsif ($path_info =~ m!$INBOX_RE/($OID_RE)/s/([\w\.\-]+)\z!o) {
+ } elsif ($path_info =~ m!$INBOX_RE/($OID_RE)/s/
+ ($PublicInbox::Hval::FN)\z!ox) {
get_vcs_object($ctx, $1, $2, $3);
} elsif ($path_info =~ m!$INBOX_RE/($OID_RE)/s\z!o) {
r301($ctx, $1, $2, 's/');
@@ -149,8 +153,11 @@ sub preload {
require PublicInbox::MIME;
require Digest::SHA;
require POSIX;
-
- foreach (qw(PublicInbox::Search PublicInbox::SearchView
+ eval {
+ require PublicInbox::Search;
+ PublicInbox::Search::load_xapian();
+ };
+ foreach (qw(PublicInbox::SearchView
PublicInbox::Mbox IO::Compress::Gzip
PublicInbox::NewsWWW)) {
eval "require $_;";
@@ -293,13 +300,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 = <{env};
my $ibx = $ctx->{-inbox};
- my $git = defined $part ? $ibx->git_part($part) : $ibx->git;
+ my $git = defined $epoch ? $ibx->git_epoch($epoch) : $ibx->git;
$git ? PublicInbox::GitHTTPBackend::serve($env, $git, $path) : r404();
}
@@ -485,6 +485,15 @@ sub www_listing {
}
}
+# GET $INBOX/manifest.js.gz
+sub get_inbox_manifest ($$$) {
+ my ($ctx, $inbox, $key) = @_;
+ my $r404 = invalid_inbox($ctx, $inbox);
+ return $r404 if $r404;
+ require PublicInbox::WwwListing;
+ PublicInbox::WwwListing::js($ctx->{env}, [$ctx->{-inbox}]);
+}
+
sub get_attach {
my ($ctx, $idx, $fn) = @_;
require PublicInbox::WwwAttach;
@@ -531,11 +540,15 @@ sub stylesheets_prepare ($$) {
$inline_ok = 0;
} else {
my $fn = $_;
+ my ($key) = (m!([^/]+?)(?:\.css)?\z!i);
+ if ($key !~ /\A[a-zA-Z0-9_\-\.]+\z/) {
+ warn "ignoring $fn, non-ASCII word character\n";
+ next;
+ }
open(my $fh, '<', $fn) or do {
warn "failed to open $fn: $!\n";
next;
};
- my ($key) = (m!([^/]+?)(?:\.css)?\z!i);
my $ctime = 0;
my $local = do { local $/; <$fh> };
if ($local =~ /\S/) {