about summary refs log tree commit homepage
path: root/lib/PublicInbox/RepobrowseGitPatch.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-01-12 21:32:33 +0000
committerEric Wong <e@80x24.org>2016-04-05 18:58:27 +0000
commit1e7a2bbd2c7b0c1d5f989c0e225d22276055eff1 (patch)
tree38673ce828a8e35b2776415c9ff633b8b7964f1e /lib/PublicInbox/RepobrowseGitPatch.pm
parent6cc4db944fa85f97734ed93763dd745e8938b8e6 (diff)
downloadpublic-inbox-1e7a2bbd2c7b0c1d5f989c0e225d22276055eff1.tar.gz
We mainly call it "repobrowse" (all lowercase), so do not imply
it is two separate words by capitalizing "Browse".
Diffstat (limited to 'lib/PublicInbox/RepobrowseGitPatch.pm')
-rw-r--r--lib/PublicInbox/RepobrowseGitPatch.pm47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/PublicInbox/RepobrowseGitPatch.pm b/lib/PublicInbox/RepobrowseGitPatch.pm
new file mode 100644
index 00000000..7f03864e
--- /dev/null
+++ b/lib/PublicInbox/RepobrowseGitPatch.pm
@@ -0,0 +1,47 @@
+# Copyright (C) 2015 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# shows the /patch/ endpoint for git repositories
+# usage: /repo.git/patch?id=COMMIT_ID
+package PublicInbox::RepobrowseGitPatch;
+use strict;
+use warnings;
+use base qw(PublicInbox::RepobrowseBase);
+
+# try to be educational and show the command-line used in the signature
+my @CMD = qw(format-patch -M --stdout);
+my $sig = '--signature=git '.join(' ', @CMD);
+
+sub call_git_patch {
+        my ($self, $req) = @_;
+        my $git = $req->{repo_info}->{git};
+        my $q = PublicInbox::RepobrowseQuery->new($req->{cgi});
+        my $id = $q->{id};
+        $id =~ /\A[\w-]+([~\^][~\^\d])*\z/ or $id = 'HEAD';
+
+        # limit scope, don't take extra args to avoid wasting server
+        # resources buffering:
+        my $range = "$id~1..$id^0";
+        my @cmd = (@CMD, $sig." $range", $range, '--');
+        if (defined(my $expath = $req->{expath})) {
+                push @cmd, $expath;
+        }
+        my $fp = $git->popen(@cmd);
+        my ($buf, $n);
+
+        $n = read($fp, $buf, 8192);
+        return unless (defined $n && $n > 0);
+        sub {
+                my ($res) = @_; # Plack callback
+                my $fh = $res->([200, ['Content-Type' => 'text/plain']]);
+                $fh->write($buf);
+                while (1) {
+                        $n = read($fp, $buf, 8192);
+                        last unless (defined $n && $n > 0);
+                        $fh->write($buf);
+                }
+                $fh->close;
+        }
+}
+
+1;