From: Junio C Hamano Date: Thu, 18 Apr 2013 18:49:21 +0000 (-0700) Subject: Merge branch 'jk/http-dumb-namespaces' X-Git-Tag: v1.8.3-rc0~54 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/77354d8cdc6e0bf407de23d762760cccee5d757c?ds=inline;hp=-c 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 --- 77354d8cdc6e0bf407de23d762760cccee5d757c diff --combined http-backend.c index 8144f3ad5e,0c69ddd9b6..6b85ffac27 --- a/http-backend.c +++ b/http-backend.c @@@ -70,7 -70,7 +70,7 @@@ static void format_write(int fd, const if (n >= sizeof(buffer)) die("protocol error: impossibly long line"); - safe_write(fd, buffer, n); + write_or_die(fd, buffer, n); } static void http_status(unsigned code, const char *msg) @@@ -111,7 -111,7 +111,7 @@@ static void hdr_cache_forever(void static void end_headers(void) { - safe_write(1, "\r\n", 2); + write_or_die(1, "\r\n", 2); } __attribute__((format (printf, 1, 2))) @@@ -157,7 -157,7 +157,7 @@@ static void send_strbuf(const char *typ hdr_int(content_length, buf->len); hdr_str(content_type, type); end_headers(); - safe_write(1, buf->buf, buf->len); + write_or_die(1, buf->buf, buf->len); } static void send_local_file(const char *the_type, const char *name) @@@ -185,7 -185,7 +185,7 @@@ die_errno("Cannot read '%s'", p); if (!n) break; - safe_write(1, buf, n); + write_or_die(1, buf, n); } close(fd); free(buf); @@@ -361,17 -361,19 +361,19 @@@ static void run_service(const char **ar static int show_text_ref(const char *name, const unsigned char *sha1, int flag, void *cb_data) { + const char *name_nons = strip_namespace(name); struct strbuf *buf = cb_data; struct object *o = parse_object(sha1); if (!o) 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) { o = deref_tag(o, name, 0); if (!o) 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; } @@@ -402,12 -404,40 +404,40 @@@ static void get_info_refs(char *arg } else { select_getanyfile(); - for_each_ref(show_text_ref, &buf); + for_each_namespaced_ref(show_text_ref, &buf); send_strbuf("text/plain", &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) { size_t objdirlen = strlen(get_object_directory()); @@@ -520,7 -550,7 +550,7 @@@ static struct service_cmd const char *pattern; void (*imp)(char *); } services[] = { - {"GET", "/HEAD$", get_text_file}, + {"GET", "/HEAD$", get_head}, {"GET", "/info/refs$", get_info_refs}, {"GET", "/objects/info/alternates$", get_text_file}, {"GET", "/objects/info/http-alternates$", get_text_file}, diff --combined t/t5551-http-fetch.sh index f0f313fb7c,b31019fab7..b23efbbfd9 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch.sh @@@ -13,7 -13,6 +13,7 @@@ LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5551' start_httpd test_expect_success 'setup repository' ' + git config push.default matching && echo content >file && git add file && git commit -m one @@@ -163,6 -162,30 +163,30 @@@ test_expect_success 'invalid Content-Ty 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_expect_success EXPENSIVE 'create 50,000 tags in the repo' '