1 contributor
<%
use IO::Uncompress::Gunzip ();
use IPC::Open3 ();
use Symbol ();
use IO::Select ();
my $sh = app->smart_http;
my $service = param('service');
my $user = param('user');
my $project = param('project');
my $git = app->git;
my $rep_dir = $git->rep($user, $project);
my @cmd = $git->cmd($user, $project, $service, '--stateless-rpc', $rep_dir);
# Command
my ($cout, $cerr) = (Symbol::gensym, Symbol::gensym);
my $pid = IPC::Open3::open3(my $cin, $cout, $cerr, @cmd);
my $pos = 0;
my $content = $self->req->content;
while (1) {
my $chunk = $content->get_body_chunk($pos);
last unless defined $chunk;
my $length = length $chunk;
last unless $length;
print $cin $chunk;
$pos += $length;
}
close $cin;
# Response
$self->res->headers->content_type("application/x-git-$service-result");
$self->render_later;
# Write
my $buf = '';
my $s = IO::Select->new($cout, $cerr);
my $buffer_size = $sh->buffer_size;
my $cb;
$cb = sub {
my $c = shift;
if (my @ready = $s->can_read) {
my $error;
my $output = '';
for my $handle (@ready) {
while (sysread($handle, $buf, $buffer_size)) {
if ($handle == $cerr) {
$error .= $buf;
}
else {
$output .= $buf;
}
}
$s->remove($handle) if eof($handle);
}
app->log->error($error) if defined $error;
$c->write_chunk($output, $cb);
}
else {
close $cout;
close $cerr;
waitpid($pid, 0);
undef $cb;
return;
}
};
$self->$cb;
%>