Skip to content

Commit 19113a2

Browse files
bmwillgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0c2f0d2 commit 19113a2

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ static inline enum object_type object_type(unsigned int mode)
452452
* ignored.
453453
*/
454454
#define GIT_PROTOCOL_ENVIRONMENT "GIT_PROTOCOL"
455+
/* HTTP header used to handshake the wire protocol */
456+
#define GIT_PROTOCOL_HEADER "Git-Protocol"
455457

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

http.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "gettext.h"
1313
#include "transport.h"
1414
#include "packfile.h"
15+
#include "protocol.h"
1516

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

901+
static void protocol_http_header(void)
902+
{
903+
if (get_protocol_version_config() > 0) {
904+
struct strbuf protocol_header = STRBUF_INIT;
905+
906+
strbuf_addf(&protocol_header, GIT_PROTOCOL_HEADER ": version=%d",
907+
get_protocol_version_config());
908+
909+
910+
extra_http_headers = curl_slist_append(extra_http_headers,
911+
protocol_header.buf);
912+
strbuf_release(&protocol_header);
913+
}
914+
}
915+
900916
void http_init(struct remote *remote, const char *url, int proactive_auth)
901917
{
902918
char *low_speed_limit;
@@ -927,6 +943,8 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
927943
if (remote)
928944
var_override(&http_proxy_authmethod, remote->http_proxy_authmethod);
929945

946+
protocol_http_header();
947+
930948
pragma_header = curl_slist_append(http_copy_default_headers(),
931949
"Pragma: no-cache");
932950
no_pragma_header = curl_slist_append(http_copy_default_headers(),

t/lib-httpd/apache.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ LockFile accept.lock
6767
<IfModule !mod_unixd.c>
6868
LoadModule unixd_module modules/mod_unixd.so
6969
</IfModule>
70+
<IfModule !mod_setenvif.c>
71+
LoadModule setenvif_module modules/mod_setenvif.so
72+
</IfModule>
7073
</IfVersion>
7174

7275
PassEnv GIT_VALGRIND
@@ -76,6 +79,10 @@ PassEnv ASAN_OPTIONS
7679
PassEnv GIT_TRACE
7780
PassEnv GIT_CONFIG_NOSYSTEM
7881

82+
<IfVersion >= 2.4>
83+
SetEnvIf Git-Protocol ".*" GIT_PROTOCOL=$0
84+
</IfVersion>
85+
7986
Alias /dumb/ www/
8087
Alias /auth/dumb/ www/auth/dumb/
8188

t/t5700-protocol-v1.sh

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,73 @@ test_expect_success 'push with ssh:// using protocol v1' '
220220
grep "push< version 1" log
221221
'
222222

223+
# Test protocol v1 with 'http://' transport
224+
#
225+
. "$TEST_DIRECTORY"/lib-httpd.sh
226+
start_httpd
227+
228+
test_expect_success 'create repo to be served by http:// transport' '
229+
git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
230+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" config http.receivepack true &&
231+
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one
232+
'
233+
234+
test_expect_success 'clone with http:// using protocol v1' '
235+
GIT_TRACE_PACKET=1 GIT_TRACE_CURL=1 git -c protocol.version=1 \
236+
clone "$HTTPD_URL/smart/http_parent" http_child 2>log &&
237+
238+
git -C http_child log -1 --format=%s >actual &&
239+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
240+
test_cmp expect actual &&
241+
242+
# Client requested to use protocol v1
243+
grep "Git-Protocol: version=1" log &&
244+
# Server responded using protocol v1
245+
grep "git< version 1" log
246+
'
247+
248+
test_expect_success 'fetch with http:// using protocol v1' '
249+
test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&
250+
251+
GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
252+
fetch 2>log &&
253+
254+
git -C http_child log -1 --format=%s origin/master >actual &&
255+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
256+
test_cmp expect actual &&
257+
258+
# Server responded using protocol v1
259+
grep "git< version 1" log
260+
'
261+
262+
test_expect_success 'pull with http:// using protocol v1' '
263+
GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
264+
pull 2>log &&
265+
266+
git -C http_child log -1 --format=%s >actual &&
267+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
268+
test_cmp expect actual &&
269+
270+
# Server responded using protocol v1
271+
grep "git< version 1" log
272+
'
273+
274+
test_expect_success 'push with http:// using protocol v1' '
275+
test_commit -C http_child three &&
276+
277+
# Push to another branch, as the target repository has the
278+
# master branch checked out and we cannot push into it.
279+
GIT_TRACE_PACKET=1 git -C http_child -c protocol.version=1 \
280+
push origin HEAD:client_branch && #2>log &&
281+
282+
git -C http_child log -1 --format=%s >actual &&
283+
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s client_branch >expect &&
284+
test_cmp expect actual &&
285+
286+
# Server responded using protocol v1
287+
grep "git< version 1" log
288+
'
289+
290+
stop_httpd
291+
223292
test_done

0 commit comments

Comments
 (0)