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>

John Koleszar committed Apr 9, 2013 at 17:55 UTC 6130f86deabe15c78d966b3588f47dbd653ec4fa
3 files changed +63 -4
http-backend.c
+34 -4
@@ -361,17 +361,19 @@ static void run_service(const char **argv)
361 static int show_text_ref(const char *name, const unsigned char *sha1,
362 int flag, void *cb_data)
363 {
364 + const char *name_nons = strip_namespace(name);
365 struct strbuf *buf = cb_data;
366 struct object *o = parse_object(sha1);
367 if (!o)
368 return 0;
369
369 - strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name);
370 + strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name_nons);
371 if (o->type == OBJ_TAG) {
372 o = deref_tag(o, name, 0);
373 if (!o)
374 return 0;
374 - strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1), name);
375 + strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1),
376 + name_nons);
377 }
378 return 0;
379 }
@@ -402,12 +404,40 @@ static void get_info_refs(char *arg)
404
405 } else {
406 select_getanyfile();
405 - for_each_ref(show_text_ref, &buf);
407 + for_each_namespaced_ref(show_text_ref, &buf);
408 send_strbuf("text/plain", &buf);
409 }
410 strbuf_release(&buf);
411 }
412
413 +static int show_head_ref(const char *name, const unsigned char *sha1,
414 + int flag, void *cb_data)
415 +{
416 + struct strbuf *buf = cb_data;
417 +
418 + if (flag & REF_ISSYMREF) {
419 + unsigned char sha1[20];
420 + const char *target = resolve_ref_unsafe(name, sha1, 1, NULL);
421 + const char *target_nons = strip_namespace(target);
422 +
423 + strbuf_addf(buf, "ref: %s\n", target_nons);
424 + } else {
425 + strbuf_addf(buf, "%s\n", sha1_to_hex(sha1));
426 + }
427 +
428 + return 0;
429 +}
430 +
431 +static void get_head(char *arg)
432 +{
433 + struct strbuf buf = STRBUF_INIT;
434 +
435 + select_getanyfile();
436 + head_ref_namespaced(show_head_ref, &buf);
437 + send_strbuf("text/plain", &buf);
438 + strbuf_release(&buf);
439 +}
440 +
441 static void get_info_packs(char *arg)
442 {
443 size_t objdirlen = strlen(get_object_directory());
@@ -520,7 +550,7 @@ static struct service_cmd {
550 const char *pattern;
551 void (*imp)(char *);
552 } services[] = {
523 - {"GET", "/HEAD$", get_text_file},
553 + {"GET", "/HEAD$", get_head},
554 {"GET", "/info/refs$", get_info_refs},
555 {"GET", "/objects/info/alternates$", get_text_file},
556 {"GET", "/objects/info/http-alternates$", get_text_file},
t/lib-httpd/apache.conf
+5
@@ -61,6 +61,11 @@ Alias /auth/dumb/ www/auth/dumb/
61 SetEnv GIT_COMMITTER_NAME "Custom User"
62 SetEnv GIT_COMMITTER_EMAIL custom@example.com
63 </LocationMatch>
64 +<LocationMatch /smart_namespace/>
65 + SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
66 + SetEnv GIT_HTTP_EXPORT_ALL
67 + SetEnv GIT_NAMESPACE ns
68 +</LocationMatch>
69 ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
70 ScriptAlias /broken_smart/ broken-smart-http.sh/
71 <Directory ${GIT_EXEC_PATH}>
t/t5551-http-fetch.sh
+24
@@ -162,6 +162,30 @@ test_expect_success 'invalid Content-Type rejected' '
162 grep "not valid:" actual
163 '
164
165 +test_expect_success 'create namespaced refs' '
166 + test_commit namespaced &&
167 + git push public HEAD:refs/namespaces/ns/refs/heads/master &&
168 + git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
169 + symbolic-ref refs/namespaces/ns/HEAD refs/namespaces/ns/refs/heads/master
170 +'
171 +
172 +test_expect_success 'smart clone respects namespace' '
173 + git clone "$HTTPD_URL/smart_namespace/repo.git" ns-smart &&
174 + echo namespaced >expect &&
175 + git --git-dir=ns-smart/.git log -1 --format=%s >actual &&
176 + test_cmp expect actual
177 +'
178 +
179 +test_expect_success 'dumb clone via http-backend respects namespace' '
180 + git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
181 + config http.getanyfile true &&
182 + GIT_SMART_HTTP=0 git clone \
183 + "$HTTPD_URL/smart_namespace/repo.git" ns-dumb &&
184 + echo namespaced >expect &&
185 + git --git-dir=ns-dumb/.git log -1 --format=%s >actual &&
186 + test_cmp expect actual
187 +'
188 +
189 test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE
190
191 test_expect_success EXPENSIVE 'create 50,000 tags in the repo' '