Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/controller/DiffusionServeController.php
Show First 20 Lines • Show All 323 Lines • ▼ Show 20 Lines | private function serveGitRequest( | ||||
$input = PhabricatorStartup::getRawInput(); | $input = PhabricatorStartup::getRawInput(); | ||||
list($err, $stdout, $stderr) = id(new ExecFuture('%s', $bin)) | list($err, $stdout, $stderr) = id(new ExecFuture('%s', $bin)) | ||||
->setEnv($env, true) | ->setEnv($env, true) | ||||
->write($input) | ->write($input) | ||||
->resolve(); | ->resolve(); | ||||
if ($err) { | if ($err) { | ||||
if ($this->isValidGitShallowCloneResponse($stdout, $stderr)) { | |||||
// Ignore the error if the response passes this special check for | |||||
// validity. | |||||
$err = 0; | |||||
} | |||||
} | |||||
if ($err) { | |||||
return new PhabricatorVCSResponse( | return new PhabricatorVCSResponse( | ||||
500, | 500, | ||||
pht('Error %d: %s', $err, $stderr)); | pht('Error %d: %s', $err, $stderr)); | ||||
} | } | ||||
return id(new DiffusionGitResponse())->setGitData($stdout); | return id(new DiffusionGitResponse())->setGitData($stdout); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | if ($has_star) { | ||||
$size = strlen($value); | $size = strlen($value); | ||||
$out[] = "{$key} {$size}\n{$value}"; | $out[] = "{$key} {$size}\n{$value}"; | ||||
} | } | ||||
} | } | ||||
return implode('', $out); | return implode('', $out); | ||||
} | } | ||||
private function isValidGitShallowCloneResponse($stdout, $stderr) { | |||||
// If you execute `git clone --depth N ...`, git sends a request which | |||||
// `git-http-backend` responds to by emitting valid output and then exiting | |||||
// with a failure code and an error message. If we ignore this error, | |||||
// everything works. | |||||
// This is a pretty funky fix: it would be nice to more precisely detect | |||||
// that a request is a `--depth N` clone request, but we don't have any code | |||||
// to decode protocol frames yet. Instead, look for reasonable evidence | |||||
// in the error and output that we're looking at a `--depth` clone. | |||||
// For evidence this isn't completely crazy, see: | |||||
// https://github.com/schacon/grack/pull/7 | |||||
$stdout_regexp = '(^Content-Type: application/x-git-upload-pack-result)m'; | |||||
$stderr_regexp = '(The remote end hung up unexpectedly)'; | |||||
$has_pack = preg_match($stdout_regexp, $stdout); | |||||
$is_hangup = preg_match($stderr_regexp, $stderr); | |||||
return $has_pack && $is_hangup; | |||||
} | |||||
} | } | ||||