# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
#
# Main web interface for mailing list archives
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
#
# Main web interface for mailing list archives
# - Must not rely on static content
# - UTF-8 is only for user-content, 7-bit US-ASCII for us
package PublicInbox::WWW;
# - Must not rely on static content
# - UTF-8 is only for user-content, 7-bit US-ASCII for us
package PublicInbox::WWW;
our $MID_RE = qr!([^/]+)!;
our $END_RE = qr!(T/|t/|t\.mbox(?:\.gz)?|t\.atom|raw|)!;
our $ATTACH_RE = qr!([0-9][0-9\.]*)-($PublicInbox::Hval::FN)!;
our $MID_RE = qr!([^/]+)!;
our $END_RE = qr!(T/|t/|t\.mbox(?:\.gz)?|t\.atom|raw|)!;
our $ATTACH_RE = qr!([0-9][0-9\.]*)-($PublicInbox::Hval::FN)!;
- 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;
- my ($k, $v) = split('=', $_, 2);
- $v = uri_unescape($v // '');
+ my ($k, $v) = split(/=/, $_, 2);
} split(/[&;]+/, $env->{QUERY_STRING});
my $path_info = path_info_raw($env);
} split(/[&;]+/, $env->{QUERY_STRING});
my $path_info = path_info_raw($env);
- if ($path_info eq '/' || $path_info eq '/manifest.js.gz') {
- www_listing($self)->call($env);
+ if ($path_info eq '/') {
+ require PublicInbox::WwwListing;
+ PublicInbox::WwwListing->response($ctx);
+ } elsif ($path_info eq '/manifest.js.gz') {
+ require PublicInbox::ManifestJsGz;
+ PublicInbox::ManifestJsGz->response($ctx);
} elsif ($path_info =~ m!$INBOX_RE\z!o) {
invalid_inbox($ctx, $1) || r301($ctx, $1);
} elsif ($path_info =~ m!$INBOX_RE(?:/|/index\.html)?\z!o) {
} elsif ($path_info =~ m!$INBOX_RE\z!o) {
invalid_inbox($ctx, $1) || r301($ctx, $1);
} elsif ($path_info =~ m!$INBOX_RE(?:/|/index\.html)?\z!o) {
# convenience redirects order matters
} elsif ($path_info =~ m!$INBOX_RE/([^/]{2,})\z!o) {
r301($ctx, $1, $2);
# convenience redirects order matters
} elsif ($path_info =~ m!$INBOX_RE/([^/]{2,})\z!o) {
r301($ctx, $1, $2);
- 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');
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:
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 $s = PublicInbox::Eml->new($str);
$mid = PublicInbox::MID::mid_clean($s->header_raw('Message-ID'));
return r301($ctx, $inbox, mid_escape($mid));
my $s = PublicInbox::Eml->new($str);
$mid = PublicInbox::MID::mid_clean($s->header_raw('Message-ID'));
return r301($ctx, $inbox, mid_escape($mid));
sub get_vcs_object ($$$;$) {
my ($ctx, $inbox, $oid, $filename) = @_;
my $r404 = invalid_inbox($ctx, $inbox);
sub get_vcs_object ($$$;$) {
my ($ctx, $inbox, $oid, $filename) = @_;
my $r404 = invalid_inbox($ctx, $inbox);
require PublicInbox::ViewVCS;
PublicInbox::ViewVCS::show($ctx, $oid, $filename);
}
require PublicInbox::ViewVCS;
PublicInbox::ViewVCS::show($ctx, $oid, $filename);
}
require PublicInbox::Mbox;
PublicInbox::Mbox::thread_mbox($ctx, $over, $sfx);
}
require PublicInbox::Mbox;
PublicInbox::Mbox::thread_mbox($ctx, $over, $sfx);
}
sub r301 {
my ($ctx, $inbox, $mid_ue, $suffix) = @_;
sub r301 {
my ($ctx, $inbox, $mid_ue, $suffix) = @_;
my $git = defined $epoch ? $ibx->git_epoch($epoch) : $ibx->git;
$git ? PublicInbox::GitHTTPBackend::serve($env, $git, $path) : r404();
}
my $git = defined $epoch ? $ibx->git_epoch($epoch) : $ibx->git;
$git ? PublicInbox::GitHTTPBackend::serve($env, $git, $path) : r404();
}
# 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::ManifestJsGz;
# 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::ManifestJsGz;
# 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
# 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
- my $h = [ 'Content-Length', bytes::length($css),
- 'Content-Type', 'text/css' ];
+ my $h = [ 'Content-Length', length($css), 'Content-Type', 'text/css' ];
- 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),