[PATCH] http-backend: respect GIT_NAMESPACE with dumb clients

2013-03-27 Thread John Koleszar
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 
---
 http-backend.c  |  8 +---
 t/lib-httpd/apache.conf |  5 +
 t/t5561-http-backend.sh |  4 
 t/t556x_common  | 16 
 4 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/http-backend.c b/http-backend.c
index f50e77f..b9896b0 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -361,17 +361,19 @@ static void run_service(const char **argv)
 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,7 +404,7 @@ 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);
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 938b4cf..ad85537 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -61,6 +61,11 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_COMMITTER_NAME "Custom User"
SetEnv GIT_COMMITTER_EMAIL cus...@example.com
 
+
+   SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+   SetEnv GIT_HTTP_EXPORT_ALL
+   SetEnv GIT_NAMESPACE ns
+
 ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
 ScriptAlias /broken_smart/ broken-smart-http.sh/
 
diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh
index b5d7fbc..5a19d61 100755
--- a/t/t5561-http-backend.sh
+++ b/t/t5561-http-backend.sh
@@ -134,6 +134,10 @@ POST /smart/repo.git/git-receive-pack HTTP/1.1 200 -
 ###
 GET  /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 403 -
 POST /smart/repo.git/git-receive-pack HTTP/1.1 403 -
+
+###  namespace test
+###
+GET  /smart_namespace/repo.git/info/refs HTTP/1.1 200
 EOF
 test_expect_success 'server request log matches test results' '
sed -e "
diff --git a/t/t556x_common b/t/t556x_common
index 82926cf..cb9eb9d 100755
--- a/t/t556x_common
+++ b/t/t556x_common
@@ -120,3 +120,19 @@ test_expect_success 'http.receivepack false' '
GET info/refs?service=git-receive-pack "403 Forbidden" &&
POST git-receive-pack  "403 Forbidden"
 '
+test_expect_success 'backend respects namespaces' '
+   log_div "namespace test"
+   config http.uploadpack true &&
+   config http.getanyfile true &&
+
+   GIT_NAMESPACE=ns && export GIT_NAMESPACE &&
+   git push public master:master &&
+   (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+   git for-each-ref | grep /$GIT_NAMESPACE/ >/dev/null
+   ) &&
+
+   git ls-remote public >exp &&  
+   curl "$HTTPD_URL/smart_namespace/repo.git/info/refs" >act &&
+   test_cmp exp act &&
+   (grep /ns/ exp && false || true)
+'
-- 
1.8.1.3

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] http-backend: respect GIT_NAMESPACE with dumb clients

2013-03-28 Thread John Koleszar
On Thu, Mar 28, 2013 at 8:52 AM, John Koleszar  wrote:
> On Thu, Mar 28, 2013 at 7:43 AM, Junio C Hamano  wrote:
>>
>> John Koleszar  writes:
>>
>> > diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh
>> > index b5d7fbc..5a19d61 100755
>> > --- a/t/t5561-http-backend.sh
>> > +++ b/t/t5561-http-backend.sh
>> > @@ -134,6 +134,10 @@ POST /smart/repo.git/git-receive-pack HTTP/1.1 200
>> > -
>> >  ###
>> >  GET  /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 403 -
>> >  POST /smart/repo.git/git-receive-pack HTTP/1.1 403 -
>> > +
>> > +###  namespace test
>> > +###
>> > +GET  /smart_namespace/repo.git/info/refs HTTP/1.1 200
>> >  EOF
>> >  test_expect_success 'server request log matches test results' '
>> >   sed -e "
>> > diff --git a/t/t556x_common b/t/t556x_common
>> > index 82926cf..cb9eb9d 100755
>> > --- a/t/t556x_common
>> > +++ b/t/t556x_common
>> > @@ -120,3 +120,19 @@ test_expect_success 'http.receivepack false' '
>> >   GET info/refs?service=git-receive-pack "403 Forbidden" &&
>> >   POST git-receive-pack  "403 Forbidden"
>> >  '
>> > +test_expect_success 'backend respects namespaces' '
>> > + log_div "namespace test"
>> > + config http.uploadpack true &&
>> > + config http.getanyfile true &&
>> > +
>> > + GIT_NAMESPACE=ns && export GIT_NAMESPACE &&
>>
>> When other people want to enhance this test suite later, their tests
>> may not want the namespace contaminated with the environment
>> variable.  You would need to enclose from here to the end inside a
>> subshell or something.
>>
>
> Ok. I'm not familiar with the test infrastructure, I had guessed that these
> were already running inside a subshell. I'll make this explicit.
>
>>
>> > + git push public master:master &&
>> > + (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
>> > + git for-each-ref | grep /$GIT_NAMESPACE/ >/dev/null
>> > + ) &&
>> > +
>> > + git ls-remote public >exp &&
>> > + curl "$HTTPD_URL/smart_namespace/repo.git/info/refs" >act &&
>>
>> Spell out "expect" and "actual".
>>
>
> The exiting tests are using exp and act for this. No objection if you want
> me to spell it out here, but having two different files for this may be
> confusing.
>
>>
>> For some unknwon reason, I am getting an HTTPD_URL at this point,
>> causing it to fail with:
>>
>> curl: (3)  malformed
>>
>
> Ah, my fault. I only ran t5561-http-backend.sh. Will fix.
>
>> > + test_cmp exp act &&
>> > + (grep /ns/ exp && false || true)
>>
>> What does that last line even mean?  Both
>>
>> false && false || true
>> true && false || true
>>
>> will yield true.  Leftover from your debugging session?
>
>
> Facepalm. The intent here is to invert the grep, to make sure that the /ns/
> does not appear in the output. No idea why I wrote it that way. Will fix.
>
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] http-backend: respect GIT_NAMESPACE with dumb clients

2013-04-03 Thread John Koleszar
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 
---

This should incorporate all of Junio's and Josh's comments. Also fixes
a bug in the first patch where the HEAD wasn't included in the list
of refs returned. PTAL.

 http-backend.c   |  9 ++---
 t/lib-httpd/apache.conf  |  5 +
 t/t5560-http-backend-noserver.sh |  7 +++
 t/t5561-http-backend.sh  | 11 +++
 t/t556x_common   | 25 +
 5 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/http-backend.c b/http-backend.c
index f50e77f..d32128f 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -361,17 +361,19 @@ static void run_service(const char **argv)
 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,7 +404,8 @@ static void get_info_refs(char *arg)
 
} else {
select_getanyfile();
-   for_each_ref(show_text_ref, &buf);
+   head_ref_namespaced(show_text_ref, &buf);
+   for_each_namespaced_ref(show_text_ref, &buf);
send_strbuf("text/plain", &buf);
}
strbuf_release(&buf);
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 938b4cf..ad85537 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -61,6 +61,11 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_COMMITTER_NAME "Custom User"
SetEnv GIT_COMMITTER_EMAIL cus...@example.com
 
+
+   SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+   SetEnv GIT_HTTP_EXPORT_ALL
+   SetEnv GIT_NAMESPACE ns
+
 ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
 ScriptAlias /broken_smart/ broken-smart-http.sh/
 
diff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh
index ef98d95..85a5625 100755
--- a/t/t5560-http-backend-noserver.sh
+++ b/t/t5560-http-backend-noserver.sh
@@ -26,6 +26,13 @@ GET() {
test_cmp exp act
 }
 
+GET_BODY() {
+   REQUEST_METHOD="GET" && export REQUEST_METHOD &&
+   run_backend "/repo.git/$1" &&
+   sane_unset REQUEST_METHOD &&
+   tr '\015' Q expected &&  
+   grep /$NS/ expected >/dev/null &&
+   GET_BODY "info/refs" >actual &&
+   test_cmp expected actual &&
+   GET_BODY "info/refs?service=git-upload-pack" | grep /$NS/ >/dev/null &&
+
+   SMART=smart_namespace &&
+   GIT_NAMESPACE=$NS && export GIT_NAMESPACE &&
+   git ls-remote public >expected &&  
+   ! grep /$NS/ expected>/dev/null &&
+   GET_BODY "info/refs" >actual &&
+   test_cmp expected actual &&
+   ! (GET_BODY "info/refs?service=git-upload-pack" | grep /$NS/ >/dev/null)
+)'
-- 
1.8.1.3

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] http-backend: respect GIT_NAMESPACE with dumb clients

2013-04-04 Thread John Koleszar
On Wed, Apr 3, 2013 at 11:05 AM, Junio C Hamano  wrote:
> Jeff King  writes:
>
>> On Wed, Apr 03, 2013 at 12:10:38PM -0400, Jeff King wrote:
>>
>>> Hmm. This is testing just the ref advertisement. It would be nice to see
>>> a complete transaction tested with namespaces turned on. Something like
>>> this (squashed into your patch) seems to work for me:
>>
>> Actually, I guess the point of your patch was to fix the
>> dumb-via-http-backend transport. So this would be more complete:
>
> Yeah, sounds sensible to me.
>

Agreed, this is much more thorough. Thanks!

I'll fold this in with Junio's comments and have another patch ready in a bit.

John
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] http-backend: respect GIT_NAMESPACE with dumb clients

2013-04-04 Thread John Koleszar
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 
---

Incorporate peff's suggested test, and Junio's comments. With regard to
whether it's sufficient to test for the presence of /ns/ without
testing the contents further, I think it is. The test uses ls-remote
as the gold standard, and the test verifies that what it gets back from
the http-backend matches what ls-remote sees on the local filesystem
without the http-backend, so I think we're covered under whatever tests
exist for ls-remote and upload-pack, in addition to the new tests peff
suggested. If you want more though, let me know.
 
http-backend.c   |  9 ++---
 t/lib-httpd/apache.conf  |  5 +
 t/t5551-http-fetch.sh| 22 ++
 t/t5560-http-backend-noserver.sh |  7 +++
 t/t5561-http-backend.sh  | 11 +++
 t/t556x_common   | 28 
 6 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/http-backend.c b/http-backend.c
index f50e77f..d32128f 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -361,17 +361,19 @@ static void run_service(const char **argv)
 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,7 +404,8 @@ static void get_info_refs(char *arg)
 
} else {
select_getanyfile();
-   for_each_ref(show_text_ref, &buf);
+   head_ref_namespaced(show_text_ref, &buf);
+   for_each_namespaced_ref(show_text_ref, &buf);
send_strbuf("text/plain", &buf);
}
strbuf_release(&buf);
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 938b4cf..ad85537 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -61,6 +61,11 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_COMMITTER_NAME "Custom User"
SetEnv GIT_COMMITTER_EMAIL cus...@example.com
 
+
+   SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+   SetEnv GIT_HTTP_EXPORT_ALL
+   SetEnv GIT_NAMESPACE ns
+
 ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
 ScriptAlias /broken_smart/ broken-smart-http.sh/
 
diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh
index 47eb769..b5032bd 100755
--- a/t/t5551-http-fetch.sh
+++ b/t/t5551-http-fetch.sh
@@ -162,6 +162,28 @@ test_expect_success 'invalid Content-Type rejected' '
grep "not valid:" actual
 '
 
+test_expect_success 'create namespaced refs' '
+   test_commit namespaced &&
+   git push public HEAD:refs/namespaces/ns/refs/heads/master
+'
+
+test_expect_success 'smart clone respects namespace' '
+   git clone --bare "$HTTPD_URL/smart_namespace/repo.git" ns-smart.git &&
+   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 --bare \
+   "$HTTPD_URL/smart_namespace/repo.git" ns-dumb.git &&
+   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' '
diff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh
index ef98d95..85a5625 100755
--- a/t/t5560-http-backend-noserver.sh
+++ b/t/t5560-http-backend-noserver.sh
@@ -26,6 +26,13 @@ GET() {
test_cmp exp act
 }
 
+GET_BODY() {
+   REQUEST_METHOD="GET" && export REQUEST_METHOD &&
+   run_backend "/repo.git/$1" &&
+   sane_unset REQUEST_METHOD &&

Re: [PATCH] http-backend: respect GIT_NAMESPACE with dumb clients

2013-04-04 Thread John Koleszar
On Thu, Apr 4, 2013 at 10:25 AM, Junio C Hamano  wrote:
> John Koleszar  writes:
>
>> @@ -402,7 +404,8 @@ static void get_info_refs(char *arg)
>>
>>   } else {
>>   select_getanyfile();
>> - for_each_ref(show_text_ref, &buf);
>> + head_ref_namespaced(show_text_ref, &buf);
>> + for_each_namespaced_ref(show_text_ref, &buf);
>>   send_strbuf("text/plain", &buf);
>>   }
>
> Whether we are namespaced or not, we used to do for_each_ref() here,
> not advertising the HEAD (outside refs/ hierarchy), but we now do,
> and as the first element in the output.
>
> Am I reading the patch correctly?
>
> Is that an unrelated but useful bugfix even for people who do not
> use server namespaces?
>

Actually, I think this line may be buggy. Hold off submitting if you
haven't already.

Including the HEAD ref in the advertisement from /info/refs ends up
duplicating it, since the dumb client unconditionally fetches the file
/HEAD to use as the that ref. I think the right thing to do is
generate the correct /HEAD using head_ref_namespaced(), rather than
returning the bare file $GIT_DIR/HEAD, but I'm not 100% sure how HEAD
and namespaces interact, since I haven't been able to produce a repo
with a different HEAD in a namespace. Can you verify this approach?

$ GIT_SMART_HTTP=0 ./git ls-remote http://localhost:8080/  | grep HEAD
bd9cd9a1859aa464b3092f2023b3a4040166572d HEAD
bd9cd9a1859aa464b3092f2023b3a4040166572d HEAD

Generates these requests (ignore the errors):
2013/04/04 18:18:49 /info/refs
2013/04/04 18:18:49 http: invalid Content-Length of "3285\r\n" sent
2013/04/04 18:18:49 /HEAD
2013/04/04 18:18:49 http: invalid Content-Length of "41\r\n" sent

I didn't catch this before, since the smart protocol includes HEAD in
its response, and I was trying to make the two match.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] http-backend: respect GIT_NAMESPACE with dumb clients

2013-04-05 Thread John Koleszar
On Thu, Apr 4, 2013 at 10:43 PM, Jeff King  wrote:
>
> On Thu, Apr 04, 2013 at 10:34:49PM -0700, Junio C Hamano wrote:
>
> > > +static void get_head(char *arg)
> > > +{
> > > +   struct strbuf buf = STRBUF_INIT;
> > > +   head_ref_namespaced(show_text_ref, &buf);
> > > +   send_strbuf("text/plain", &buf);
> > > +   strbuf_release(&buf);
> > > +}
> >
> > You identified the right place to patch, but I think we need a bit
> > more than this.
> >
> > The show_text_ref() function gives "SHA-1  refname". It is
> > likely that the dumb client will ignore the trailing part of that
> > output, but let's avoid a hack that we would not want see other
> > implementations imitate.
>
> Oh, right. I was thinking too much about normal clients which see HEAD
> in the ref advertisement; of course the dumb client is expecting to see
> the actual HEAD file.
>
> > One advantage dumb clients has over smart ones is that they can read
> > HEAD that is a textual symref from a dumb server and learn which
> > branch is the default one (remote.c::guess_remote_head()) without
> > guessing.  I think this function should:
> >
> >  - Turn "HEAD" into a namespaced equivalent;
> >
> >  - Run resolve_ref() on the result of the above;
> >
> >  - Is it a symbolic ref?
> >
> >. If it is, then format "ref: \n" into a strbuf and send
> >  it (make sure  is without the namespace prefix);
> >
> >. Otherwise, HEAD is detached. Prepare "%s\n" % sha1_to_hex(sha1),
> >  and send it.
>
> Yes, that sounds right; it is basically just reconstructing a HEAD
> file. What do the HEADs inside namespaces look like? Do they refer to
> full global refs, or do they refer to refs within the namespace?
>
> If the latter, we could just send the HEAD file directly. But I suspect
> it is the former, so that they can function when non-namespaced commands
> are used.
>

Here's a quick cut at this. Seems to work ok in local testing, I
haven't updated the test suite yet. If the namespaced HEAD is a
symbolic ref, its target must have the namespace prefix applied, or
the resolved ref will be from outside the namespace (eg
refs/heads/master vs refs/namespace/ns/refs/heads/master). This seems
to be handled at write time, not sure if we need to do more
verification here or not.

diff --git a/http-backend.c b/http-backend.c
index d32128f..da4482c 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -404,13 +404,40 @@ static void get_info_refs(char *arg)

} else {
select_getanyfile();
-   head_ref_namespaced(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());
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] http-backend: respect GIT_NAMESPACE with dumb clients

2013-04-09 Thread John Koleszar
On Mon, Apr 8, 2013 at 2:45 PM, Jeff King  wrote:
> On Mon, Apr 08, 2013 at 11:25:39PM +0200, Thomas Rast wrote:
>
>> At the risk of repeating something that's been said already -- I only
>> skimmed the thread -- this test breaks in today's pu on my machine.  I
>> get:
>> [...]
>> --- expect2013-04-08 21:24:36.571874540 +
>> +++ actual2013-04-08 21:24:36.579874619 +
>> @@ -1,3 +1,2 @@
>> -453190505bf07f7513bed9839da875eb3610f807 HEAD
>>  453190505bf07f7513bed9839da875eb3610f807 refs/heads/master
>>  453190505bf07f7513bed9839da875eb3610f807 
>> refs/namespaces/ns/refs/heads/master
>> not ok 14 - backend respects namespaces
>
> I think what is in pu is not yet reflecting the latest discussion. HEAD
> should not be included in the simulated info/refs, but should be
> generated, respecting namespaces, whenever a client retrieves the HEAD
> file directly.
>
> It looks like the thread was left here;
>
>   http://article.gmane.org/gmane.comp.version-control.git/220237
>
> and we are just waiting for John's re-roll.
>

I should be able to get this done either later today or later this
week. Life/$DAYJOB has been taking up the time slot I was spending on
this the past few days.

John
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4] http-backend: respect GIT_NAMESPACE with dumb clients

2013-04-09 Thread John Koleszar
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 
---
Updates to generate HEAD. Drops my original tests, since they were under the
flawed assumption that both the dumb and smart protocols produced the same
ref advertisement at /info/refs.

 http-backend.c  |   38 ++
 t/lib-httpd/apache.conf |5 +
 t/t5551-http-fetch.sh   |   24 
 3 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/http-backend.c b/http-backend.c
index f50e77f..4f35a31 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -361,17 +361,19 @@ static void run_service(const char **argv)
 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 @@ 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 @@ 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 --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 938b4cf..ad85537 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -61,6 +61,11 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_COMMITTER_NAME "Custom User"
SetEnv GIT_COMMITTER_EMAIL cus...@example.com
 
+
+   SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+   SetEnv GIT_HTTP_EXPORT_ALL
+   SetEnv GIT_NAMESPACE ns
+
 ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
 ScriptAlias /broken_smart/ broken-smart-http.sh/
 
diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh
index 47eb769..b31019f 100755
--- a/t/t5551-http-fetch.sh
+++ b/t/t5551-http-fetch.sh
@@ -162,6 +162,30 @@ test_expect_success 'invalid Content-Type rejected' '
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-