diff options
Diffstat (limited to 'remote-curl.c')
| -rw-r--r-- | remote-curl.c | 78 | 
1 files changed, 60 insertions, 18 deletions
| diff --git a/remote-curl.c b/remote-curl.c index a331bae6c8..b76bfcb3d3 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -10,7 +10,6 @@  static struct remote *remote;  static const char *url; -static struct walker *walker;  struct options {  	int verbosity; @@ -22,12 +21,6 @@ struct options {  };  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")) { @@ -102,7 +95,7 @@ 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; @@ -119,8 +112,20 @@ static struct discovery* discover_refs(const char *service)  	}  	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; @@ -137,7 +142,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.  		 */ @@ -170,13 +176,13 @@ static struct discovery* discover_refs(const char *service)  	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;  } @@ -188,6 +194,7 @@ static struct ref *parse_git_refs(struct discovery *heads)  	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"); @@ -235,9 +242,8 @@ static struct ref *parse_info_refs(struct discovery *heads)  		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; @@ -290,6 +296,7 @@ struct rpc_state {  	int out;  	struct strbuf result;  	unsigned gzip_request : 1; +	unsigned initial_buffer : 1;  };  static size_t rpc_out(void *ptr, size_t eltsize, @@ -300,6 +307,7 @@ static size_t rpc_out(void *ptr, size_t eltsize,  	size_t avail = rpc->len - rpc->pos;  	if (!avail) { +		rpc->initial_buffer = 0;  		avail = packet_read_line(rpc->out, rpc->buf, rpc->alloc);  		if (!avail)  			return 0; @@ -314,6 +322,29 @@ static size_t rpc_out(void *ptr, size_t eltsize,  	return avail;  } +#ifndef NO_CURL_IOCTL +static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp) +{ +	struct rpc_state *rpc = clientp; + +	switch (cmd) { +	case CURLIOCMD_NOP: +		return CURLIOE_OK; + +	case CURLIOCMD_RESTARTREAD: +		if (rpc->initial_buffer) { +			rpc->pos = 0; +			return CURLIOE_OK; +		} +		fprintf(stderr, "Unable to rewind rpc post data - try increasing http.postBuffer\n"); +		return CURLIOE_FAILRESTART; + +	default: +		return CURLIOE_UNKNOWNCMD; +	} +} +#endif +  static size_t rpc_in(const void *ptr, size_t eltsize,  		size_t nmemb, void *buffer_)  { @@ -370,8 +401,13 @@ static int post_rpc(struct rpc_state *rpc)  		 */  		headers = curl_slist_append(headers, "Expect: 100-continue");  		headers = curl_slist_append(headers, "Transfer-Encoding: chunked"); +		rpc->initial_buffer = 1;  		curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);  		curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc); +#ifndef NO_CURL_IOCTL +		curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl); +		curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc); +#endif  		if (options.verbosity > 1) {  			fprintf(stderr, "POST %s (chunked)\n", rpc->service_name);  			fflush(stderr); @@ -457,7 +493,6 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)  	struct child_process client;  	int err = 0; -	init_walker();  	memset(&client, 0, sizeof(client));  	client.in = -1;  	client.out = -1; @@ -480,7 +515,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)  	strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc);  	rpc->hdr_content_type = strbuf_detach(&buf, NULL); -	strbuf_addf(&buf, "Accept: application/x-%s-response", svc); +	strbuf_addf(&buf, "Accept: application/x-%s-result", svc);  	rpc->hdr_accept = strbuf_detach(&buf, NULL);  	while (!err) { @@ -509,6 +544,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)  static int fetch_dumb(int nr_heads, struct ref **to_fetch)  { +	struct walker *walker;  	char **targets = xmalloc(nr_heads * sizeof(char*));  	int ret, i; @@ -517,13 +553,14 @@ static int fetch_dumb(int nr_heads, struct ref **to_fetch)  	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]); @@ -766,6 +803,8 @@ int main(int argc, const char **argv)  		url = remote->url[0];  	} +	http_init(remote); +  	do {  		if (strbuf_getline(&buf, stdin, '\n') == EOF)  			break; @@ -811,5 +850,8 @@ int main(int argc, const char **argv)  		}  		strbuf_reset(&buf);  	} while (1); + +	http_cleanup(); +  	return 0;  } | 
