# - 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);
%{$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);
# 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);
}
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)
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);
}
};
}
-# /$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->{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 ] ];
}
my ($ctx, $inbox) = @_;
invalid_inbox($ctx, $inbox) || do {
my $d = $ctx->{ibx}->description . "\n";
- [ 200, [ 'Content-Length', bytes::length($d),
+ utf8::encode($d);
+ [ 200, [ 'Content-Length', length($d),
'Content-Type', 'text/plain' ], [ $d ] ];
};
}