<% use IPC::Open3 (); use Symbol (); use IO::Select (); my $api = gitprep_api; my $service = param('service'); my $user = param('user'); my $project = param('project'); my $git = $api->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 = $ENV{GITPREP_SMART_HTTP_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; %>