forked from yuki-kimoto/gitprep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
archive.html.ep
81 lines (73 loc) · 1.6 KB
/
archive.html.ep
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<%
# API
my $api = $self->gitprep_api;
# Parameter
my $user = param('user');
my $project = param('project');
my $rev = param('rev');
my $archive_type = stash('archive_type');
my $content_type;
my $format;
my $ext;
if ($archive_type eq 'tar') {
$format = 'tar';
$ext = 'tar.gz';
$content_type = 'application/x-tar';
}
elsif ($archive_type eq 'zip') {
$format = 'zip';
$ext = 'zip';
$content_type = 'application/zip';
}
# Git
my $git = app->git;
# Object type
my $type = $git->object_type($user, $project, "$rev^{}");
if (!$type || $type eq 'blob') {
$self->render_not_found;
return;
}
my $name = "$project-$rev";
my $file = "$name.$ext";
my $quote = sub {
return join(' ',
map { my $a = $_; $a =~ s/(['!])/'\\$1'/g; "'$a'" } @_
);
};
my $cmd = $quote->(
$git->cmd(
$user,
$project,
'archive',
"--format=$format",
"--prefix=$name/",
$rev
)
);
if ($archive_type eq 'tar') {
$cmd .= ' | ' . $quote->('gzip', '-n');
}
$file =~ s/(["\\])/\\$1/g;
my $success = open my $fh, '-|', $cmd;
unless ($success) {
$self->render_exeption;
return;
}
# Write chunk
$self->res->headers->content_type($content_type);
$self->res->headers->content_disposition(qq/attachment; filename="$file"/);
my $cb;
$cb = sub {
my $c = shift;
my $size = 500 * 1024;
my $length = sysread($fh, my $buffer, $size);
unless ($length) {
close $fh;
undef $cb;
$c->finish;
return;
}
$c->write_chunk($buffer, $cb);
};
$self->$cb;
%>