Enable info/refs gzip decompression in HTTP client

Some HTTP servers try to use gzip compression on the /info/refs request to save transfer bandwidth. Repositories with many tags may find the /info/refs request can be gzipped to be 50% of the original size due to the few but often repeated bytes used (hex SHA-1 and commonly digits in tag names). For most HTTP requests enable "Accept-Encoding: gzip" ensuring the /info/refs payload can use this encoding format. Only request gzip encoding from servers. Although deflate is supported by libcurl, most servers have standardized on gzip encoding for compression as that is what most browsers support. Asking for deflate increases request sizes by a few bytes, but is unlikely to ever be used by a server. Disable the Accept-Encoding header on probe RPCs as response bodies are supposed to be exactly 4 bytes long, "0000". The HTTP headers requesting and indicating compression use more space than the data transferred in the body. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Shawn O. Pearce committed Sep 19, 2012 at 16:12 UTC aa90b9697f9275e4f9cb10d274495e7587f217c0
3 files changed +5 -3
http.c
+1
@@ -818,6 +818,7 @@ static int http_request(const char *url, void *result, int target, int options)
818
819 curl_easy_setopt(slot->curl, CURLOPT_URL, url);
820 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
821 + curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
822
823 if (start_active_slot(slot)) {
824 run_active_slot(slot);
remote-curl.c
+2 -2
@@ -393,7 +393,7 @@ static int probe_rpc(struct rpc_state *rpc)
393 curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
394 curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
395 curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
396 - curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
396 + curl_easy_setopt(slot->curl, CURLOPT_ENCODING, NULL);
397 curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, "0000");
398 curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, 4);
399 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
@@ -449,7 +449,7 @@ static int post_rpc(struct rpc_state *rpc)
449 curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
450 curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
451 curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
452 - curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
452 + curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
453
454 headers = curl_slist_append(headers, rpc->hdr_content_type);
455 headers = curl_slist_append(headers, rpc->hdr_accept);
t/t5551-http-fetch.sh
+2 -1
@@ -32,13 +32,14 @@ setup_askpass_helper
32 cat >exp <<EOF
33 > GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1
34 > Accept: */*
35 +> Accept-Encoding: gzip
36 > Pragma: no-cache
37 < HTTP/1.1 200 OK
38 < Pragma: no-cache
39 < Cache-Control: no-cache, max-age=0, must-revalidate
40 < Content-Type: application/x-git-upload-pack-advertisement
41 > POST /smart/repo.git/git-upload-pack HTTP/1.1
41 -> Accept-Encoding: deflate, gzip
42 +> Accept-Encoding: gzip
43 > Content-Type: application/x-git-upload-pack-request
44 > Accept: application/x-git-upload-pack-result
45 > Content-Length: xxx