remote-curl: ensure that URLs have a trailing slash

Previously, we blindly assumed that URLs passed to the remote-curl
helper did not end with a trailing slash.

Use the convenience function end_url_with_slash() from http.[ch] to
ensure that URLs have a trailing slash on invocation of the remote-curl
helper, and use the URL as one with a trailing slash throughout.

It is possible for users to pass a URL with a trailing slash to
remote-curl, by, say, setting it in remote.<name>.url in their git
config. The resulting requests have an empty path component (//) and may
break implementations of the http git protocol.

Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Tay Ray Chuan 2010-04-08 10:15:18 +08:00 коммит произвёл Junio C Hamano
Родитель eb9d47cf9b
Коммит d8fab07208
2 изменённых файлов: 9 добавлений и 7 удалений

Просмотреть файл

@ -9,7 +9,7 @@
#include "sideband.h" #include "sideband.h"
static struct remote *remote; static struct remote *remote;
static const char *url; static const char *url; /* always ends with a trailing slash */
static struct walker *walker; static struct walker *walker;
struct options { struct options {
@ -108,7 +108,7 @@ static struct discovery* discover_refs(const char *service)
return last; return last;
free_discovery(last); free_discovery(last);
strbuf_addf(&buffer, "%s/info/refs", url); strbuf_addf(&buffer, "%sinfo/refs", url);
if (!prefixcmp(url, "http://") || !prefixcmp(url, "https://")) { if (!prefixcmp(url, "http://") || !prefixcmp(url, "https://")) {
is_http = 1; is_http = 1;
if (!strchr(url, '?')) if (!strchr(url, '?'))
@ -128,7 +128,7 @@ static struct discovery* discover_refs(const char *service)
strbuf_reset(&buffer); strbuf_reset(&buffer);
proto_git_candidate = 0; proto_git_candidate = 0;
strbuf_addf(&buffer, "%s/info/refs", url); strbuf_addf(&buffer, "%sinfo/refs", url);
refs_url = strbuf_detach(&buffer, NULL); refs_url = strbuf_detach(&buffer, NULL);
http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
@ -518,7 +518,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
rpc->out = client.out; rpc->out = client.out;
strbuf_init(&rpc->result, 0); strbuf_init(&rpc->result, 0);
strbuf_addf(&buf, "%s/%s", url, svc); strbuf_addf(&buf, "%s%s", url, svc);
rpc->service_url = strbuf_detach(&buf, NULL); rpc->service_url = strbuf_detach(&buf, NULL);
strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc); strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc);
@ -805,11 +805,13 @@ int main(int argc, const char **argv)
remote = remote_get(argv[1]); remote = remote_get(argv[1]);
if (argc > 2) { if (argc > 2) {
url = argv[2]; end_url_with_slash(&buf, argv[2]);
} else { } else {
url = remote->url[0]; end_url_with_slash(&buf, remote->url[0]);
} }
url = strbuf_detach(&buf, NULL);
do { do {
if (strbuf_getline(&buf, stdin, '\n') == EOF) if (strbuf_getline(&buf, stdin, '\n') == EOF)
break; break;

Просмотреть файл

@ -38,7 +38,7 @@ cat >exp <<EOF
GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200 GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200 POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200
EOF EOF
test_expect_failure 'no empty path components' ' test_expect_success 'no empty path components' '
# In the URL, add a trailing slash, and see if git appends yet another # In the URL, add a trailing slash, and see if git appends yet another
# slash. # slash.
cd "$ROOT_PATH" && cd "$ROOT_PATH" &&