<% use IPC::Open3 (); use Symbol (); use IO::Select (); my $service = param('service'); my $user = param('user'); my $project = param('project'); my $git = app->git; my $rep_info = app->rep_info($user, $project); my $rep_git_dir = $rep_info->{git_dir}; my @cmd = $git->cmd(app->rep_info($user, $project), $service, '--stateless-rpc', $rep_git_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 $s = IO::Select->new($cout, $cerr); my $buffer_size = $ENV{GITPREP_SMART_HTTP_BUFFER_SIZE}; my $error; my @ready; my $cb; $cb = sub { my $c = shift; if (@ready = $s->can_read) { my $output = ''; for my $handle (@ready) { if (sysread($handle, my $buf, $buffer_size)) { if ($handle == $cerr) { $error .= $buf; } else { $output .= $buf; } } else { $s->remove($handle); } } $c->write_chunk($output, $cb); } else { $c->finish; waitpid($pid, 0); $c->app->log->error($c->url_for . ": $error") if defined $error; undef $cb; return; } }; $self->$cb; %>