http-backend: respect GIT_NAMESPACE with dumb clients
Filter the list of refs returned via the dumb HTTP protocol according to the active namespace, consistent with other clients of the upload-pack service. Signed-off-by: John Koleszar <jkoleszar@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									19534ee8a7
								
							
						
					
					
						commit
						6130f86dea
					
				|  | @ -361,17 +361,19 @@ static void run_service(const char **argv) | ||||||
| static int show_text_ref(const char *name, const unsigned char *sha1, | static int show_text_ref(const char *name, const unsigned char *sha1, | ||||||
| 	int flag, void *cb_data) | 	int flag, void *cb_data) | ||||||
| { | { | ||||||
|  | 	const char *name_nons = strip_namespace(name); | ||||||
| 	struct strbuf *buf = cb_data; | 	struct strbuf *buf = cb_data; | ||||||
| 	struct object *o = parse_object(sha1); | 	struct object *o = parse_object(sha1); | ||||||
| 	if (!o) | 	if (!o) | ||||||
| 		return 0; | 		return 0; | ||||||
|  |  | ||||||
| 	strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name); | 	strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name_nons); | ||||||
| 	if (o->type == OBJ_TAG) { | 	if (o->type == OBJ_TAG) { | ||||||
| 		o = deref_tag(o, name, 0); | 		o = deref_tag(o, name, 0); | ||||||
| 		if (!o) | 		if (!o) | ||||||
| 			return 0; | 			return 0; | ||||||
| 		strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1), name); | 		strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1), | ||||||
|  | 			    name_nons); | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -402,12 +404,40 @@ static void get_info_refs(char *arg) | ||||||
|  |  | ||||||
| 	} else { | 	} else { | ||||||
| 		select_getanyfile(); | 		select_getanyfile(); | ||||||
| 		for_each_ref(show_text_ref, &buf); | 		for_each_namespaced_ref(show_text_ref, &buf); | ||||||
| 		send_strbuf("text/plain", &buf); | 		send_strbuf("text/plain", &buf); | ||||||
| 	} | 	} | ||||||
| 	strbuf_release(&buf); | 	strbuf_release(&buf); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int show_head_ref(const char *name, const unsigned char *sha1, | ||||||
|  | 	int flag, void *cb_data) | ||||||
|  | { | ||||||
|  | 	struct strbuf *buf = cb_data; | ||||||
|  |  | ||||||
|  | 	if (flag & REF_ISSYMREF) { | ||||||
|  | 		unsigned char sha1[20]; | ||||||
|  | 		const char *target = resolve_ref_unsafe(name, sha1, 1, NULL); | ||||||
|  | 		const char *target_nons = strip_namespace(target); | ||||||
|  |  | ||||||
|  | 		strbuf_addf(buf, "ref: %s\n", target_nons); | ||||||
|  | 	} else { | ||||||
|  | 		strbuf_addf(buf, "%s\n", sha1_to_hex(sha1)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void get_head(char *arg) | ||||||
|  | { | ||||||
|  | 	struct strbuf buf = STRBUF_INIT; | ||||||
|  |  | ||||||
|  | 	select_getanyfile(); | ||||||
|  | 	head_ref_namespaced(show_head_ref, &buf); | ||||||
|  | 	send_strbuf("text/plain", &buf); | ||||||
|  | 	strbuf_release(&buf); | ||||||
|  | } | ||||||
|  |  | ||||||
| static void get_info_packs(char *arg) | static void get_info_packs(char *arg) | ||||||
| { | { | ||||||
| 	size_t objdirlen = strlen(get_object_directory()); | 	size_t objdirlen = strlen(get_object_directory()); | ||||||
|  | @ -520,7 +550,7 @@ static struct service_cmd { | ||||||
| 	const char *pattern; | 	const char *pattern; | ||||||
| 	void (*imp)(char *); | 	void (*imp)(char *); | ||||||
| } services[] = { | } services[] = { | ||||||
| 	{"GET", "/HEAD$", get_text_file}, | 	{"GET", "/HEAD$", get_head}, | ||||||
| 	{"GET", "/info/refs$", get_info_refs}, | 	{"GET", "/info/refs$", get_info_refs}, | ||||||
| 	{"GET", "/objects/info/alternates$", get_text_file}, | 	{"GET", "/objects/info/alternates$", get_text_file}, | ||||||
| 	{"GET", "/objects/info/http-alternates$", get_text_file}, | 	{"GET", "/objects/info/http-alternates$", get_text_file}, | ||||||
|  |  | ||||||
|  | @ -61,6 +61,11 @@ Alias /auth/dumb/ www/auth/dumb/ | ||||||
| 	SetEnv GIT_COMMITTER_NAME "Custom User" | 	SetEnv GIT_COMMITTER_NAME "Custom User" | ||||||
| 	SetEnv GIT_COMMITTER_EMAIL custom@example.com | 	SetEnv GIT_COMMITTER_EMAIL custom@example.com | ||||||
| </LocationMatch> | </LocationMatch> | ||||||
|  | <LocationMatch /smart_namespace/> | ||||||
|  | 	SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} | ||||||
|  | 	SetEnv GIT_HTTP_EXPORT_ALL | ||||||
|  | 	SetEnv GIT_NAMESPACE ns | ||||||
|  | </LocationMatch> | ||||||
| ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1 | ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1 | ||||||
| ScriptAlias /broken_smart/ broken-smart-http.sh/ | ScriptAlias /broken_smart/ broken-smart-http.sh/ | ||||||
| <Directory ${GIT_EXEC_PATH}> | <Directory ${GIT_EXEC_PATH}> | ||||||
|  |  | ||||||
|  | @ -162,6 +162,30 @@ test_expect_success 'invalid Content-Type rejected' ' | ||||||
| 	grep "not valid:" actual | 	grep "not valid:" actual | ||||||
| ' | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'create namespaced refs' ' | ||||||
|  | 	test_commit namespaced && | ||||||
|  | 	git push public HEAD:refs/namespaces/ns/refs/heads/master && | ||||||
|  | 	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \ | ||||||
|  | 		symbolic-ref refs/namespaces/ns/HEAD refs/namespaces/ns/refs/heads/master | ||||||
|  | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'smart clone respects namespace' ' | ||||||
|  | 	git clone "$HTTPD_URL/smart_namespace/repo.git" ns-smart && | ||||||
|  | 	echo namespaced >expect && | ||||||
|  | 	git --git-dir=ns-smart/.git log -1 --format=%s >actual && | ||||||
|  | 	test_cmp expect actual | ||||||
|  | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'dumb clone via http-backend respects namespace' ' | ||||||
|  | 	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \ | ||||||
|  | 		config http.getanyfile true && | ||||||
|  | 	GIT_SMART_HTTP=0 git clone \ | ||||||
|  | 		"$HTTPD_URL/smart_namespace/repo.git" ns-dumb && | ||||||
|  | 	echo namespaced >expect && | ||||||
|  | 	git --git-dir=ns-dumb/.git log -1 --format=%s >actual && | ||||||
|  | 	test_cmp expect actual | ||||||
|  | ' | ||||||
|  |  | ||||||
| test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE | test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE | ||||||
|  |  | ||||||
| test_expect_success EXPENSIVE 'create 50,000 tags in the repo' ' | test_expect_success EXPENSIVE 'create 50,000 tags in the repo' ' | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 John Koleszar
						John Koleszar