Skip to content

Commit 77354d8

Browse files
committed
Merge branch 'jk/http-dumb-namespaces'
Allow smart-capable HTTP servers to be restricted via the GIT_NAMESPACE mechanism when talking with commit-walker clients (they already do so when talking with smart HTTP clients). * jk/http-dumb-namespaces: http-backend: respect GIT_NAMESPACE with dumb clients
2 parents 1931f6d + 6130f86 commit 77354d8

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
@@ -163,6 +163,30 @@ test_expect_success 'invalid Content-Type rejected' '
163163
grep "not valid:" actual
164164
'
165165

166+
test_expect_success 'create namespaced refs' '
167+
test_commit namespaced &&
168+
git push public HEAD:refs/namespaces/ns/refs/heads/master &&
169+
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
170+
symbolic-ref refs/namespaces/ns/HEAD refs/namespaces/ns/refs/heads/master
171+
'
172+
173+
test_expect_success 'smart clone respects namespace' '
174+
git clone "$HTTPD_URL/smart_namespace/repo.git" ns-smart &&
175+
echo namespaced >expect &&
176+
git --git-dir=ns-smart/.git log -1 --format=%s >actual &&
177+
test_cmp expect actual
178+
'
179+
180+
test_expect_success 'dumb clone via http-backend respects namespace' '
181+
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
182+
config http.getanyfile true &&
183+
GIT_SMART_HTTP=0 git clone \
184+
"$HTTPD_URL/smart_namespace/repo.git" ns-dumb &&
185+
echo namespaced >expect &&
186+
git --git-dir=ns-dumb/.git log -1 --format=%s >actual &&
187+
test_cmp expect actual
188+
'
189+
166190
test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE
167191

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

0 commit comments

Comments
 (0)