$response = new \Symfony\Component\HttpFoundation\Response;
$response->headers->set('Content-Type', 'application/mercurial-0.1');
$oldLang = getenv('LANG');
$oldLanguage = getenv('LANGUAGE');
$oldHgEnc = getenv('HGENCODING');
putenv('LANG=C');
putenv('LANGUAGE=C');
putenv('HGENCODING=UTF-8');
$options = array('--stdio');
$forcedExtensions = array('mq' => true, 'fetch' => true, 'convert' => true, 'progress' => false);
foreach ($forcedExtensions as $ext => $enabled) {
$options[] = sprintf('--config extensions.%s=%s', $ext, $enabled ? '""' : '!');
}
$command = 'hg serve ' . implode(' ', $options);
$cwd = $app['root'] . '/repos/test';
$pipes = null;
$descr = array(
libhg_Stream::STDIN => array('pipe', 'r'),
libhg_Stream::STDOUT => array('pipe', 'w'),
);
$process = proc_open($command, $descr, $pipes, $cwd);
if (!is_resource($process)) {
throw new \RuntimeException('Could not start command server.');
}
$stdin = new libhg_Stream($pipes[libhg_Stream::STDIN]);
$stdout = new libhg_Stream($pipes[libhg_Stream::STDOUT]);
putenv('LANG=' . $oldLang);
putenv('LANGUAGE=' . $oldLanguage);
putenv('HGENCODING=' . $oldHgEnc);
$hg_args = array();
for ($i = 1; ; $i++) {
$header = 'HTTP_X_HGARG_' . $i;
if (!$app['request']->server->has($header)) {
break;
}
$hg_args[] = $app['request']->server->get($header);
}
$hg_args = implode('', $hg_args);
parse_str($hg_args, $args);
$app['monolog']->info(print_r($args, true));
$commands = array(
'batch' => array('cmds', '*'),
'between' => array('pairs'),
'branchmap' => array(),
'branches' => array('nodes'),
'capabilities' => array(),
'changegroup' => array('roots'),
'changegroupsubset' => array('bases heads'),
'debugwireargs' => array('one two *'),
'getbundle' => array('*'),
'heads' => array(),
'hello' => array(),
'known' => array('nodes', '*'),
'listkeys' => array('namespace'),
'lookup' => array('key'),
'pushkey' => array('namespace', 'key', 'old', 'new'),
'stream_out' => array(''),
'unbundle' => array('heads'),
);
if (!isset($commands[$cmd])) {
$app->abort(400);
}
$out = array();
$has_star = false;
foreach ($commands[$cmd] as $arg_key) {
if ($arg_key === '*') {
$has_star = true;
break;
}
if (isset($args[$arg_key])) {
$value = $args[$arg_key];
$size = strlen($value);
$out[] = $arg_key . ' ' . $size . "\n" . $value;
unset($args[$arg_key]);
}
}
if ($has_star) {
$count = count($args);
$out[] = '* ' . $count . "\n";
foreach ($args as $key => $value) {
if (in_array($key, $commands[$cmd])) {
continue;
}
$size = strlen($value);
$out[] = $key . ' ' . $size . "\n" . $value;
}
}
$out = implode('', $out);
if (strlen($out)) {
$out .= "\n";
}
$out = $cmd . "\n" . $out;
$app['monolog']->info($out);
$stdin->write($out);
if ($cmd === 'getbundle') {
$pipe = $pipes[libhg_Stream::STDOUT];
$response->setContent("\x78\x9C" . gzdeflate(stream_get_contents($pipe)));
} else {
$length = (int)fgets($pipes[libhg_Stream::STDOUT]);
if ($length != 0) {
$response->setContent(fread($pipes[libhg_Stream::STDOUT], $length));
}
}
$stdin->close();
$stdout->close();
proc_close($process);
return $response;