Skip to content

Commit 6130f86

Browse files
jkoleszargitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 19534ee commit 6130f86

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

http-backend.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,17 +361,19 @@ static void run_service(const char **argv)
361361
static int show_text_ref(const char *name, const unsigned char *sha1,
362362
int flag, void *cb_data)
363363
{
364+
const char *name_nons = strip_namespace(name);
364365
struct strbuf *buf = cb_data;
365366
struct object *o = parse_object(sha1);
366367
if (!o)
367368
return 0;
368369

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);
370371
if (o->type == OBJ_TAG) {
371372
o = deref_tag(o, name, 0);
372373
if (!o)
373374
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);
375377
}
376378
return 0;
377379
}
@@ -402,12 +404,40 @@ static void get_info_refs(char *arg)
402404

403405
} else {
404406
select_getanyfile();
405-
for_each_ref(show_text_ref, &buf);
407+
for_each_namespaced_ref(show_text_ref, &buf);
406408
send_strbuf("text/plain", &buf);
407409
}
408410
strbuf_release(&buf);
409411
}
410412

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+
411441
static void get_info_packs(char *arg)
412442
{
413443
size_t objdirlen = strlen(get_object_directory());
@@ -520,7 +550,7 @@ static struct service_cmd {
520550
const char *pattern;
521551
void (*imp)(char *);
522552
} services[] = {
523-
{"GET", "/HEAD$", get_text_file},
553+
{"GET", "/HEAD$", get_head},
524554
{"GET", "/info/refs$", get_info_refs},
525555
{"GET", "/objects/info/alternates$", get_text_file},
526556
{"GET", "/objects/info/http-alternates$", get_text_file},

t/lib-httpd/apache.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ Alias /auth/dumb/ www/auth/dumb/
6161
SetEnv GIT_COMMITTER_NAME "Custom User"
6262
SetEnv GIT_COMMITTER_EMAIL [email protected]
6363
</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>
6469
ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
6570
ScriptAlias /broken_smart/ broken-smart-http.sh/
6671
<Directory ${GIT_EXEC_PATH}>

t/t5551-http-fetch.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,30 @@ test_expect_success 'invalid Content-Type rejected' '
162162
grep "not valid:" actual
163163
'
164164

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+
165189
test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE
166190

167191
test_expect_success EXPENSIVE 'create 50,000 tags in the repo' '

0 commit comments

Comments
 (0)