]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/WWW.pm
treewide: replace {-inbox} with {ibx} for consistency
[public-inbox.git] / lib / PublicInbox / WWW.pm
index 56d2c42a41cd8eafd37444e68495644f28a80388..6bae2190ac5f3f4d0e040fb787cc951e2402c87d 100644 (file)
@@ -22,13 +22,14 @@ use PublicInbox::MID qw(mid_escape);
 use PublicInbox::GitHTTPBackend;
 use PublicInbox::UserContent;
 use PublicInbox::WwwStatic qw(r path_info_raw);
+use PublicInbox::Eml;
 
 # TODO: consider a routing tree now that we have more endpoints:
 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!([0-9][0-9\.]*)-($PublicInbox::Hval::FN)!;
-our $OID_RE = qr![a-f0-9]{7,40}!;
+our $OID_RE = qr![a-f0-9]{7,}!;
 
 sub new {
        my ($class, $pi_config) = @_;
@@ -76,8 +77,12 @@ sub call {
        }
 
        # top-level indices and feeds
-       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) {
@@ -125,6 +130,8 @@ sub call {
                get_vcs_object($ctx, $1, $2, $3);
        } elsif ($path_info =~ m!$INBOX_RE/($OID_RE)/s\z!o) {
                r301($ctx, $1, $2, 's/');
+       } elsif ($path_info =~ m!$INBOX_RE/(\w+)\.sql\.gz\z!o) {
+               get_altid_dump($ctx, $1, $2);
        # convenience redirects order matters
        } elsif ($path_info =~ m!$INBOX_RE/([^/]{2,})\z!o) {
                r301($ctx, $1, $2);
@@ -139,11 +146,17 @@ sub call {
 # fragmentation since common allocators favor a large contiguous heap.
 sub preload {
        my ($self) = @_;
+
+       # populate caches used by Encode internally, since emails
+       # may show up with any encoding.
+       require Encode;
+       Encode::find_encoding($_) for Encode->encodings(':all');
+
        require PublicInbox::ExtMsg;
        require PublicInbox::Feed;
        require PublicInbox::View;
        require PublicInbox::SearchThread;
-       require PublicInbox::MIME;
+       require PublicInbox::Eml;
        require PublicInbox::Mbox;
        require PublicInbox::ViewVCS;
        require PublicInbox::WwwText;
@@ -162,7 +175,6 @@ sub preload {
                }
                $self->cgit;
                $self->stylesheets_prepare($_) for ('', '../', '../../');
-               $self->www_listing;
                $self->news_www;
                $pi_config->each_inbox(\&preload_inbox);
        }
@@ -198,9 +210,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);
+       my $ibx = $ctx->{www}->{pi_config}->lookup_name($inbox) //
+                       $ctx->{www}->{pi_config}->lookup_ei($inbox);
        if (defined $ibx) {
-               $ctx->{-inbox} = $ibx;
+               $ctx->{ibx} = $ibx;
                return;
        }
 
@@ -218,14 +231,13 @@ 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;
-               require Email::Simple;
-               my $s = Email::Simple->new($str);
-               $mid = PublicInbox::MID::mid_clean($s->header('Message-ID'));
+               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));
        }
        undef;
@@ -274,7 +286,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);
@@ -293,9 +305,8 @@ sub get_text {
 }
 
 # show git objects (blobs and commits)
-# /$INBOX/_/$OBJECT_ID/show
-# /$INBOX/_/${OBJECT_ID}_${FILENAME}
-# KEY may contain slashes
+# /$INBOX/$GIT_OBJECT_ID/s/
+# /$INBOX/$GIT_OBJECT_ID/s/$FILENAME
 sub get_vcs_object ($$$;$) {
        my ($ctx, $inbox, $oid, $filename) = @_;
        my $r404 = invalid_inbox($ctx, $inbox);
@@ -314,12 +325,11 @@ sub get_altid_dump {
 
 sub need {
        my ($ctx, $extra) = @_;
-       my $msg = <<EOF;
-<html><head><title>$extra not available for this
-public-inbox</title><body><pre>$extra is not available for this public-inbox
-<a href="../">Return to index</a></pre></body></html>
+       require PublicInbox::WwwStream;
+       PublicInbox::WwwStream::html_oneshot($ctx, 501, \<<EOF);
+<pre>$extra is not available for this public-inbox
+<a\nhref="../">Return to index</a></pre>
 EOF
-       [ 501, [ 'Content-Type' => 'text/html; charset=UTF-8' ], [ $msg ] ];
 }
 
 # /$INBOX/$MESSAGE_ID/t.mbox           -> thread as mbox
@@ -329,7 +339,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);
 }
@@ -338,7 +348,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);
 }
@@ -403,11 +413,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};
@@ -444,7 +454,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();
 }
@@ -452,7 +462,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);
        }
@@ -490,21 +500,13 @@ sub cgit {
        }
 }
 
-sub www_listing {
-       my ($self) = @_;
-       $self->{www_listing} ||= do {
-               require PublicInbox::WwwListing;
-               PublicInbox::WwwListing->new($self);
-       }
-}
-
 # 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}]);
+       require PublicInbox::ManifestJsGz;
+       PublicInbox::ManifestJsGz->response($ctx);
 }
 
 sub get_attach {
@@ -640,7 +642,7 @@ sub get_css ($$$) {
        my $css = $css_map->{$key};
        if (!defined($css) && $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),
@@ -652,7 +654,7 @@ sub get_css ($$$) {
 sub get_description {
        my ($ctx, $inbox) = @_;
        invalid_inbox($ctx, $inbox) || do {
-               my $d = $ctx->{-inbox}->description . "\n";
+               my $d = $ctx->{ibx}->description . "\n";
                [ 200, [ 'Content-Length', bytes::length($d),
                        'Content-Type', 'text/plain' ], [ $d ] ];
        };