Browse Source

http: tell server that the client understands v1

Tell a server that protocol v1 can be used by sending the http header
'Git-Protocol' with 'version=1' indicating this.

Also teach the apache http server to pass through the 'Git-Protocol'
header as an environment variable 'GIT_PROTOCOL'.

Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Brandon Williams 7 years ago committed by Junio C Hamano
parent
commit
19113a26b6
  1. 2
      cache.h
  2. 18
      http.c
  3. 7
      t/lib-httpd/apache.conf
  4. 69
      t/t5700-protocol-v1.sh

2
cache.h

@ -452,6 +452,8 @@ static inline enum object_type object_type(unsigned int mode)
* ignored. * ignored.
*/ */
#define GIT_PROTOCOL_ENVIRONMENT "GIT_PROTOCOL" #define GIT_PROTOCOL_ENVIRONMENT "GIT_PROTOCOL"
/* HTTP header used to handshake the wire protocol */
#define GIT_PROTOCOL_HEADER "Git-Protocol"


/* /*
* This environment variable is expected to contain a boolean indicating * This environment variable is expected to contain a boolean indicating

18
http.c

@ -12,6 +12,7 @@
#include "gettext.h" #include "gettext.h"
#include "transport.h" #include "transport.h"
#include "packfile.h" #include "packfile.h"
#include "protocol.h"


static struct trace_key trace_curl = TRACE_KEY_INIT(CURL); static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
#if LIBCURL_VERSION_NUM >= 0x070a08 #if LIBCURL_VERSION_NUM >= 0x070a08
@ -897,6 +898,21 @@ static void set_from_env(const char **var, const char *envname)
*var = val; *var = val;
} }


static void protocol_http_header(void)
{
if (get_protocol_version_config() > 0) {
struct strbuf protocol_header = STRBUF_INIT;

strbuf_addf(&protocol_header, GIT_PROTOCOL_HEADER ": version=%d",
get_protocol_version_config());


extra_http_headers = curl_slist_append(extra_http_headers,
protocol_header.buf);
strbuf_release(&protocol_header);
}
}

void http_init(struct remote *remote, const char *url, int proactive_auth) void http_init(struct remote *remote, const char *url, int proactive_auth)
{ {
char *low_speed_limit; char *low_speed_limit;
@ -927,6 +943,8 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
if (remote) if (remote)
var_override(&http_proxy_authmethod, remote->http_proxy_authmethod); var_override(&http_proxy_authmethod, remote->http_proxy_authmethod);


protocol_http_header();

pragma_header = curl_slist_append(http_copy_default_headers(), pragma_header = curl_slist_append(http_copy_default_headers(),
"Pragma: no-cache"); "Pragma: no-cache");
no_pragma_header = curl_slist_append(http_copy_default_headers(), no_pragma_header = curl_slist_append(http_copy_default_headers(),

7
t/lib-httpd/apache.conf

@ -67,6 +67,9 @@ LockFile accept.lock
<IfModule !mod_unixd.c> <IfModule !mod_unixd.c>
LoadModule unixd_module modules/mod_unixd.so LoadModule unixd_module modules/mod_unixd.so
</IfModule> </IfModule>
<IfModule !mod_setenvif.c>
LoadModule setenvif_module modules/mod_setenvif.so
</IfModule>
</IfVersion> </IfVersion>


PassEnv GIT_VALGRIND PassEnv GIT_VALGRIND
@ -76,6 +79,10 @@ PassEnv ASAN_OPTIONS
PassEnv GIT_TRACE PassEnv GIT_TRACE
PassEnv GIT_CONFIG_NOSYSTEM PassEnv GIT_CONFIG_NOSYSTEM


<IfVersion >= 2.4>
SetEnvIf Git-Protocol ".*" GIT_PROTOCOL=$0
</IfVersion>

Alias /dumb/ www/ Alias /dumb/ www/
Alias /auth/dumb/ www/auth/dumb/ Alias /auth/dumb/ www/auth/dumb/



69
t/t5700-protocol-v1.sh

@ -220,4 +220,73 @@ test_expect_success 'push with ssh:// using protocol v1' '
grep "push< version 1" log grep "push< version 1" log
' '


# Test protocol v1 with 'http://' transport
#
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd

test_expect_success 'create repo to be served by http:// transport' '
git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" config http.receivepack true &&
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one
'

test_expect_success 'clone with http:// using protocol v1' '
GIT_TRACE_PACKET=1 GIT_TRACE_CURL=1 git -c protocol.version=1 \
clone "$HTTPD_URL/smart/http_parent" http_child 2>log &&

git -C http_child log -1 --format=%s >actual &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
test_cmp expect actual &&

# Client requested to use protocol v1
grep "Git-Protocol: version=1" log &&
# Server responded using protocol v1
grep "git< version 1" log
'

test_expect_success 'fetch with http:// using protocol v1' '
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&

GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
fetch 2>log &&

git -C http_child log -1 --format=%s origin/master >actual &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
test_cmp expect actual &&

# Server responded using protocol v1
grep "git< version 1" log
'

test_expect_success 'pull with http:// using protocol v1' '
GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
pull 2>log &&

git -C http_child log -1 --format=%s >actual &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
test_cmp expect actual &&

# Server responded using protocol v1
grep "git< version 1" log
'

test_expect_success 'push with http:// using protocol v1' '
test_commit -C http_child three &&

# Push to another branch, as the target repository has the
# master branch checked out and we cannot push into it.
GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
push origin HEAD:client_branch && #2>log &&

git -C http_child log -1 --format=%s >actual &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s client_branch >expect &&
test_cmp expect actual &&

# Server responded using protocol v1
grep "git< version 1" log
'

stop_httpd

test_done test_done

Loading…
Cancel
Save