about summary refs log tree commit homepage
path: root/lib/PublicInbox/Cgit.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-04-05 20:04:26 +0000
committerEric Wong <e@80x24.org>2019-04-15 06:20:35 +0000
commit19151f1b6a04532a1bc3f86fa945a10be6849b8d (patch)
tree3ef59c69c008a831653de93baed87fe426b4a897 /lib/PublicInbox/Cgit.pm
parent8efc7b62fc3e3bd94d0196fc1942ca9572a481cc (diff)
downloadpublic-inbox-19151f1b6a04532a1bc3f86fa945a10be6849b8d.tar.gz
We can reduce the configuration needed to run cgit by reusing
the static file handling logic of the dumb git HTTP protocol.

I hate logos and icons, so don't expect public-inbox.org or
80x24.org to ever have those to waste users' bandwidth with :P
But I expect other users to find this useful.
Diffstat (limited to 'lib/PublicInbox/Cgit.pm')
-rw-r--r--lib/PublicInbox/Cgit.pm41
1 files changed, 38 insertions, 3 deletions
diff --git a/lib/PublicInbox/Cgit.pm b/lib/PublicInbox/Cgit.pm
index 9ba9e14d..8922ec56 100644
--- a/lib/PublicInbox/Cgit.pm
+++ b/lib/PublicInbox/Cgit.pm
@@ -13,17 +13,45 @@ use PublicInbox::GitHTTPBackend;
 *input_prepare = *PublicInbox::GitHTTPBackend::input_prepare;
 *parse_cgi_headers = *PublicInbox::GitHTTPBackend::parse_cgi_headers;
 *serve = *PublicInbox::GitHTTPBackend::serve;
+*static_result = *PublicInbox::GitHTTPBackend::static_result;
 use warnings;
 use PublicInbox::Qspawn;
+use Plack::MIME;
+
+sub locate_cgit ($) {
+        my ($pi_config) = @_;
+        my $cgit_bin = $pi_config->{'publicinbox.cgitbin'};
+        my $cgit_data = $pi_config->{'publicinbox.cgitdata'};
+
+        # /var/www/htdocs/cgit is the default install path from cgit.git
+        # /usr/{lib,share}/cgit is where Debian puts cgit
+        # TODO: check other distros for common paths
+        unless (defined $cgit_bin) {
+                foreach (qw(/var/www/htdocs/cgit /usr/lib/cgit)) {
+                        my $x = "$_/cgit.cgi";
+                        next unless -x $x;
+                        $cgit_bin = $x;
+                        last;
+                }
+        }
+        unless (defined $cgit_data) {
+                foreach my $d (qw(/var/www/htdocs/cgit /usr/share/cgit)) {
+                        my $f = "$d/cgit.css";
+                        next unless -f $f;
+                        $cgit_data = $d;
+                        last;
+                }
+        }
+        ($cgit_bin, $cgit_data);
+}
 
 sub new {
         my ($class, $pi_config) = @_;
-        my $cgit_bin = $pi_config->{'publicinbox.cgitbin'} ||
-                # Debian default location:
-                '/usr/lib/cgit/cgit.cgi';
+        my ($cgit_bin, $cgit_data) = locate_cgit($pi_config);
 
         my $self = bless {
                 cmd => [ $cgit_bin ],
+                cgit_data => $cgit_data,
                 pi_config => $pi_config,
         }, $class;
 
@@ -39,6 +67,9 @@ sub new {
         while (my ($nick, $repo) = each %$code_repos) {
                 $self->{"\0$nick"} = $repo;
         }
+        my $cgit_static = $pi_config->{-cgit_static};
+        my $static = join('|', map { quotemeta $_ } keys %$cgit_static);
+        $self->{static} = qr/\A($static)\z/;
         $self;
 }
 
@@ -66,6 +97,10 @@ sub call {
                 if (my $git = $self->{"\0$nick"}) {
                         return serve($env, $git, $path);
                 }
+        } elsif ($path_info =~ m!$self->{static}!) {
+                my $f = $1;
+                my $type = Plack::MIME->mime_type($f);
+                return static_result($env, [], "$self->{cgit_data}$f", $type);
         }
 
         my $cgi_env = { PATH_INFO => $path_info };