Skip to content

Commit 0b6e758

Browse files
committedMay 29, 2023
Updates for Mercurial's HTTP protocol
Summary: While testing https://secure.phabricator.com/D21864 I ran into some issues getting mercurial HTTP access working. Using wireshark I confirmed that my local mercurial 6.4 was not including command arguments as HTTP headers but in the querystring. I didn't dig too deep into understanding when/why this started happening. The protocol documents this in [[ https://repo.mercurial-scm.org/hg/file/tip/mercurial/helptext/internals/wireprotocol.txt | wireprotocol.txt ]]. >Command arguments can be sent multiple ways. The simplest is part of the URL query string using ``x-www-form-urlencoded`` encoding (see Python's ``urllib.urlencode()``. However, many servers impose length limitations on the URL. So this mechanism is typically only used if the server doesn't support other mechanisms. Based on that either the mercurial on the server is really old (it's 6.1.1 tho) or maybe some other parsing/info passing in Phab's handling of the wire protocol is causing the client to downgrade the wire protocol support. Test Plan: Host mercurial repo using HTTP, test push/pull. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin, epriestley Differential Revision: https://secure.phabricator.com/D21867
1 parent ec9ebe5 commit 0b6e758

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed
 

‎src/applications/diffusion/controller/DiffusionServeController.php

+22-3
Original file line numberDiff line numberDiff line change
@@ -886,10 +886,29 @@ private function getMercurialArguments() {
886886
}
887887
$args_raw[] = $_SERVER[$header];
888888
}
889-
$args_raw = implode('', $args_raw);
890889

891-
return id(new PhutilQueryStringParser())
892-
->parseQueryString($args_raw);
890+
if ($args_raw) {
891+
$args_raw = implode('', $args_raw);
892+
return id(new PhutilQueryStringParser())
893+
->parseQueryString($args_raw);
894+
}
895+
896+
// Sometimes arguments come in via the query string. Note that this will
897+
// not handle multi-value entries e.g. "a[]=1,a[]=2" however it's unclear
898+
// whether or how the mercurial protocol should handle this.
899+
$query = idx($_SERVER, 'QUERY_STRING', '');
900+
$query_pairs = id(new PhutilQueryStringParser())
901+
->parseQueryString($query);
902+
foreach ($query_pairs as $key => $value) {
903+
// Filter out private/internal keys as well as the command itself.
904+
if (strncmp($key, '__', 2) && $key != 'cmd') {
905+
$args_raw[$key] = $value;
906+
}
907+
}
908+
909+
// TODO: Arguments can also come in via request body for POST requests. The
910+
// body would be all arguments, url-encoded.
911+
return $args_raw;
893912
}
894913

895914
private function formatMercurialArguments($command, array $arguments) {

0 commit comments

Comments
 (0)
Failed to load comments.