static struct remote *remote;
static const char *url;
-static struct walker *walker;
struct options {
int verbosity;
};
static struct options options;
-static void init_walker(void)
-{
- if (!walker)
- walker = get_http_walker(url, remote);
-}
-
static int set_option(const char *name, const char *value)
{
if (!strcmp(name, "verbosity")) {
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;
}
refs_url = strbuf_detach(&buffer, NULL);
- 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, "%s/info/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;
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.
*/
return last;
}
-static int write_discovery(int fd, void *data)
+static int write_discovery(int in, int out, void *data)
{
struct discovery *heads = data;
int err = 0;
- if (write_in_full(fd, heads->buf, heads->len) != heads->len)
+ if (write_in_full(out, heads->buf, heads->len) != heads->len)
err = 1;
- close(fd);
+ close(out);
return err;
}
memset(&async, 0, sizeof(async));
async.proc = write_discovery;
async.data = heads;
+ async.out = -1;
if (start_async(&async))
die("cannot start thread to parse advertised refs");
i++;
}
- init_walker();
ref = alloc_ref("HEAD");
- if (!walker->fetch_ref(walker, ref) &&
+ if (!http_fetch_ref(url, ref) &&
!resolve_remote_symref(ref, refs)) {
ref->next = refs;
refs = ref;
struct child_process client;
int err = 0;
- init_walker();
memset(&client, 0, sizeof(client));
client.in = -1;
client.out = -1;
static int fetch_dumb(int nr_heads, struct ref **to_fetch)
{
+ struct walker *walker;
char **targets = xmalloc(nr_heads * sizeof(char*));
int ret, i;
for (i = 0; i < nr_heads; i++)
targets[i] = xstrdup(sha1_to_hex(to_fetch[i]->old_sha1));
- init_walker();
+ walker = get_http_walker(url);
walker->get_all = 1;
walker->get_tree = 1;
walker->get_history = 1;
walker->get_verbosely = options.verbosity >= 3;
walker->get_recover = 0;
ret = walker_fetch(walker, nr_heads, targets, NULL, NULL);
+ walker_free(walker);
for (i = 0; i < nr_heads; i++)
free(targets[i]);
url = remote->url[0];
}
+ http_init(remote);
+
do {
if (strbuf_getline(&buf, stdin, '\n') == EOF)
break;
}
strbuf_reset(&buf);
} while (1);
+
+ http_cleanup();
+
return 0;
}