Enable info/refs gzip decompression in HTTP client
authorShawn O. Pearce <spearce@spearce.org>
Wed, 19 Sep 2012 23:12:02 +0000 (16:12 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 20 Sep 2012 17:26:50 +0000 (10:26 -0700)
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>
http.c
remote-curl.c
t/t5551-http-fetch.sh

diff --git a/http.c b/http.c
index 9bac1d89fdb639f6991bfe9f683ccf7bd5ada4cb..345c171c5fd572e65e34ea421a334141a5438979 100644 (file)
--- a/http.c
+++ b/http.c
@@ -818,6 +818,7 @@ static int http_request(const char *url, void *result, int target, int options)
 
        curl_easy_setopt(slot->curl, CURLOPT_URL, url);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
 
        if (start_active_slot(slot)) {
                run_active_slot(slot);
index 3ec474fc631eb3b433b3cadbd74aed4b83cba724..4a0927e5cf45b056242fdffd4782475ca9c273d1 100644 (file)
@@ -393,7 +393,7 @@ static int probe_rpc(struct rpc_state *rpc)
        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
        curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
        curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
-       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, NULL);
        curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, "0000");
        curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, 4);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
@@ -449,7 +449,7 @@ static int post_rpc(struct rpc_state *rpc)
        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
        curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
        curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
-       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
 
        headers = curl_slist_append(headers, rpc->hdr_content_type);
        headers = curl_slist_append(headers, rpc->hdr_accept);
index 2db5c3564181818efdf885188d7cc597024c6f12..380c17541efd39946fe14c924b84bc212c435f17 100755 (executable)
@@ -32,13 +32,14 @@ setup_askpass_helper
 cat >exp <<EOF
 > GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1
 > Accept: */*
+> Accept-Encoding: gzip
 > Pragma: no-cache
 < HTTP/1.1 200 OK
 < Pragma: no-cache
 < Cache-Control: no-cache, max-age=0, must-revalidate
 < Content-Type: application/x-git-upload-pack-advertisement
 > POST /smart/repo.git/git-upload-pack HTTP/1.1
-> Accept-Encoding: deflate, gzip
+> Accept-Encoding: gzip
 > Content-Type: application/x-git-upload-pack-request
 > Accept: application/x-git-upload-pack-result
 > Content-Length: xxx