Code

remote-curl: ensure that URLs have a trailing slash
[git.git] / remote-curl.c
index 136100695994049f2e9d6357cb25dd5a9d73ae28..1fe59d6db0e85ab938959f08d3bca4a83f748ab5 100644 (file)
@@ -9,7 +9,7 @@
 #include "sideband.h"
 
 static struct remote *remote;
-static const char *url;
+static const char *url; /* always ends with a trailing slash */
 static struct walker *walker;
 
 struct options {
@@ -102,13 +102,13 @@ static struct discovery* discover_refs(const char *service)
        struct strbuf buffer = STRBUF_INIT;
        struct discovery *last = last_discovery;
        char *refs_url;
-       int http_ret, is_http = 0;
+       int http_ret, is_http = 0, proto_git_candidate = 1;
 
        if (last && !strcmp(service, last->service))
                return last;
        free_discovery(last);
 
-       strbuf_addf(&buffer, "%s/info/refs", url);
+       strbuf_addf(&buffer, "%sinfo/refs", url);
        if (!prefixcmp(url, "http://") || !prefixcmp(url, "https://")) {
                is_http = 1;
                if (!strchr(url, '?'))
@@ -121,6 +121,19 @@ static struct discovery* discover_refs(const char *service)
 
        init_walker();
        http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
+
+       /* try again with "plain" url (no ? or & appended) */
+       if (http_ret != HTTP_OK) {
+               free(refs_url);
+               strbuf_reset(&buffer);
+
+               proto_git_candidate = 0;
+               strbuf_addf(&buffer, "%sinfo/refs", url);
+               refs_url = strbuf_detach(&buffer, NULL);
+
+               http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
+       }
+
        switch (http_ret) {
        case HTTP_OK:
                break;
@@ -137,7 +150,8 @@ static struct discovery* discover_refs(const char *service)
        last->buf_alloc = strbuf_detach(&buffer, &last->len);
        last->buf = last->buf_alloc;
 
-       if (is_http && 5 <= last->len && last->buf[4] == '#') {
+       if (is_http && proto_git_candidate
+               && 5 <= last->len && last->buf[4] == '#') {
                /* smart HTTP response; validate that the service
                 * pkt-line matches our request.
                 */
@@ -504,7 +518,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
        rpc->out = client.out;
        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);
 
        strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc);
@@ -791,11 +805,13 @@ int main(int argc, const char **argv)
        remote = remote_get(argv[1]);
 
        if (argc > 2) {
-               url = argv[2];
+               end_url_with_slash(&buf, argv[2]);
        } else {
-               url = remote->url[0];
+               end_url_with_slash(&buf, remote->url[0]);
        }
 
+       url = strbuf_detach(&buf, NULL);
+
        do {
                if (strbuf_getline(&buf, stdin, '\n') == EOF)
                        break;