Re: [PATCH] handle http urls with query string ("?foo") correctly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Thu, 5 Jun 2008, David ʽBombeʼ Roden wrote:

> 
> ---
> handle http urls with query string ("?foo") correctly
> git breaks when a repository is cloned from an http url that contains a
> query string. This patch fixes this behaviour be inserting the name of
> the requested object (like "/info/refs") before the query string.

Usually, this comes before the "---", and your comments/answers after it.  
And the first line would be the subject:

-- snip --
Handle http urls with query string ("?foo") correctly

Git breaks when a repository is cloned from an http url that contains a
query string. This patch fixes this behaviour be inserting the name of
the requested object (like "/info/refs") before the query string.
-- snap --

And of course, you usually sign off your patches.

> diff --git a/http-walker.c b/http-walker.c
> index 99f397e..b14497a 100644
> --- a/http-walker.c
> +++ b/http-walker.c
> @@ -100,7 +100,6 @@ static void start_object_request(struct walker *walker,
>  	char *hex = sha1_to_hex(obj_req->sha1);
>  	char prevfile[PATH_MAX];
>  	char *url;
> -	char *posn;
>  	int prevlocal;
>  	unsigned char prev_buf[PREV_BUF_SIZE];
>  	ssize_t prev_read = 0;
> @@ -109,6 +108,7 @@ static void start_object_request(struct walker *walker,
>  	struct curl_slist *range_header = NULL;
>  	struct active_request_slot *slot;
>  	struct walker_data *data = walker->data;
> +	struct strbuf suffix_buffer = STRBUF_INIT;
>  
>  	snprintf(prevfile, sizeof(prevfile), "%s.prev", obj_req->filename);
>  	unlink(prevfile);
> @@ -146,16 +146,10 @@ static void start_object_request(struct walker *walker,
>  
>  	SHA1_Init(&obj_req->c);
>  
> -	url = xmalloc(strlen(obj_req->repo->base) + 51);
> +	strbuf_addstr(&suffix_buffer, "/objects/");
> +	strbuf_addf(&suffix_buffer, "%c%c/%s", hex[0], hex[1], hex + 2);

How about

	strbuf_addf(&suffix_buffer, "/objects/%c%c/%s",
		hex[0], hex[1], hex + 2);

?

> +	url = transform_url(obj_req->repo->base, strbuf_detach(&suffix_buffer, NULL));

And this line wrapped, like so?

	url = transform_url(obj_req->repo->base,
		strbuf_detach(&suffix_buffer, NULL));

Oh, but maybe it makes more sense to let transform_url() work on the 
strbuf itself?

> @@ -608,8 +603,7 @@ static void fetch_alternates(struct walker *walker, const char *base)
>  	if (walker->get_verbosely)
>  		fprintf(stderr, "Getting alternates list for %s\n", base);
>  
> -	url = xmalloc(strlen(base) + 31);
> -	sprintf(url, "%s/objects/info/http-alternates", base);
> +	url = transform_url(base, "/objects/info/http-alternates");
>  
>  	/* Use a callback to process the result, since another request
>  	   may fail and need to have alternates loaded before continuing */
> @@ -655,8 +649,7 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)
>  	if (walker->get_verbosely)
>  		fprintf(stderr, "Getting pack list for %s\n", repo->base);
>  
> -	url = xmalloc(strlen(repo->base) + 21);
> -	sprintf(url, "%s/objects/info/packs", repo->base);
> +	url = transform_url(repo->base, "/objects/info/packs");
>  
>  	slot = get_active_slot();
>  	slot->results = &results;

Of course, these two would have to initialise their strbuf, then.

> diff --git a/http.c b/http.c
> index 2a21ccb..a60f9ea 100644
> --- a/http.c
> +++ b/http.c
> @@ -590,15 +590,17 @@ static char *quote_ref_url(const char *base, const char *ref)
>  	qref = xmalloc(len);
>  	memcpy(qref, base, baselen);
>  	dp = qref + baselen;
> -	*(dp++) = '/';
> -	for (cp = ref; (ch = *cp) != 0; cp++) {
> -		if (needs_quote(ch)) {
> -			*dp++ = '%';
> -			*dp++ = hex((ch >> 4) & 0xF);
> -			*dp++ = hex(ch & 0xF);
> +	if (*ref) {
> +		*(dp++) = '/';
> +		for (cp = ref; (ch = *cp) != 0; cp++) {
> +			if (needs_quote(ch)) {
> +				*dp++ = '%';
> +				*dp++ = hex((ch >> 4) & 0xF);
> +				*dp++ = hex(ch & 0xF);
> +			}
> +			else
> +				*dp++ = ch;
>  		}
> -		else
> -			*dp++ = ch;
>  	}
>  	*dp = 0;
>  

Is this correct?  Either it should work the old way, or you will run into 
problems when ref is not empty...

> @@ -611,9 +613,12 @@ int http_fetch_ref(const char *base, struct ref *ref)
>  	struct strbuf buffer = STRBUF_INIT;
>  	struct active_request_slot *slot;
>  	struct slot_results results;
> +	struct strbuf suffix_buffer = STRBUF_INIT;
>  	int ret;
>  
> -	url = quote_ref_url(base, ref->name);
> +	strbuf_addf(&suffix_buffer, "/%s", ref->name);
> +	url = transform_url(base, strbuf_detach(&suffix_buffer, NULL));
> +	url = quote_ref_url(url, "");

... and indeed, it seems that by now, you would not want to add the ref in 
quote_ref_url() anymore... which you do not, since you pass "" as ref 
(and this is the only caller of quote_ref_url).

> @@ -643,3 +648,22 @@ int http_fetch_ref(const char *base, struct ref *ref)
>  	free(url);
>  	return ret;
>  }
> +
> +char *transform_url(const char *url, const char *suffix)
> +{
> +	struct strbuf new_url = STRBUF_INIT;
> +	char *question_mark;
> +	ptrdiff_t offset;
> +
> +	if ((question_mark = strchr(url, '?'))) {

Junio usually prefers assignments outside of the if() statement.

> +		offset = (ptrdiff_t) question_mark - (ptrdiff_t) url;
> +		strbuf_add(&new_url, url, offset);
> +		strbuf_addstr(&new_url, suffix);
> +		strbuf_addstr(&new_url, url + offset);
> +	} else {
> +		strbuf_addstr(&new_url, url);
> +		strbuf_addstr(&new_url, suffix);
> +	}
> +	return strbuf_detach(&new_url, NULL);
> +}
> +

There is an extra empty line at the end.

But another thing is more pressing: obviously, there were reasons to quote 
the ref names with this funny URL encoding (%45%75%6E%6E%79), and you 
effectively undid that change.

> diff --git a/transport.c b/transport.c
> index 3ff8519..b1966d8 100644
> --- a/transport.c
> +++ b/transport.c
> @@ -1,3 +1,4 @@
> +#include <stddef.h>

Why?

Ciao,
Dscho

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux