diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php --- a/src/applications/diffusion/controller/DiffusionServeController.php +++ b/src/applications/diffusion/controller/DiffusionServeController.php @@ -886,10 +886,29 @@ } $args_raw[] = $_SERVER[$header]; } - $args_raw = implode('', $args_raw); - return id(new PhutilQueryStringParser()) - ->parseQueryString($args_raw); + if ($args_raw) { + $args_raw = implode('', $args_raw); + return id(new PhutilQueryStringParser()) + ->parseQueryString($args_raw); + } + + // Sometimes arguments come in via the query string. Note that this will + // not handle multi-value entries e.g. "a[]=1,a[]=2" however it's unclear + // whether or how the mercurial protocol should handle this. + $query = idx($_SERVER, 'QUERY_STRING', ''); + $query_pairs = id(new PhutilQueryStringParser()) + ->parseQueryString($query); + foreach ($query_pairs as $key => $value) { + // Filter out private/internal keys as well as the command itself. + if (strncmp($key, '__', 2) && $key != 'cmd') { + $args_raw[$key] = $value; + } + } + + // TODO: Arguments can also come in via request body for POST requests. The + // body would be all arguments, url-encoded. + return $args_raw; } private function formatMercurialArguments($command, array $arguments) {