diff options
author | Junio C Hamano <gitster@pobox.com> | 2013-09-20 12:39:05 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-09-20 12:39:05 -0700 |
commit | 7b8315bb593c38ac957486916512e9a5df6df087 (patch) | |
tree | 626821ff6571b15d40f08fb13a6efb3c9f362c18 | |
parent | f406140baa5128bfa537c271c7292a866c08b7d4 (diff) | |
parent | 115dedd72223e101181363f4e6053b4c937fdc37 (diff) | |
download | git-7b8315bb593c38ac957486916512e9a5df6df087.tar.gz |
Merge branch 'jk/upload-pack-keepalive'
When running "fetch -q", a long silence while the sender side
computes the set of objects to send can be mistaken by proxies as
dropped connection. The server side has been taught to send a small
empty messages to keep the connection alive.
* jk/upload-pack-keepalive:
upload-pack: bump keepalive default to 5 seconds
upload-pack: send keepalive packets during pack computation
-rw-r--r-- | Documentation/config.txt | 11 | ||||
-rw-r--r-- | upload-pack.c | 25 |
2 files changed, 35 insertions, 1 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt index b320b63b91..c3f70023ec 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -2288,6 +2288,17 @@ uploadpack.allowtipsha1inwant:: of a hidden ref (by default, such a request is rejected). see also `uploadpack.hiderefs`. +uploadpack.keepalive:: + When `upload-pack` has started `pack-objects`, there may be a + quiet period while `pack-objects` prepares the pack. Normally + it would output progress information, but if `--quiet` was used + for the fetch, `pack-objects` will output nothing at all until + the pack data begins. Some clients and networks may consider + the server to be hung and give up. Setting this option instructs + `upload-pack` to send an empty keepalive packet every + `uploadpack.keepalive` seconds. Setting this option to 0 + disables keepalive packets entirely. The default is 5 seconds. + url.<base>.insteadOf:: Any URL that starts with this value will be rewritten to start, instead, with <base>. In cases where some site serves a diff --git a/upload-pack.c b/upload-pack.c index 4959dbc5fe..a6c54e06bb 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -41,6 +41,7 @@ static struct object_array have_obj; static struct object_array want_obj; static struct object_array extra_edge_obj; static unsigned int timeout; +static int keepalive = 5; /* 0 for no sideband, * otherwise maximum packet size (up to 65520 bytes). */ @@ -134,6 +135,7 @@ static void create_pack_file(void) while (1) { struct pollfd pfd[2]; int pe, pu, pollsize; + int ret; reset_timeout(); @@ -156,7 +158,8 @@ static void create_pack_file(void) if (!pollsize) break; - if (poll(pfd, pollsize, -1) < 0) { + ret = poll(pfd, pollsize, 1000 * keepalive); + if (ret < 0) { if (errno != EINTR) { error("poll failed, resuming: %s", strerror(errno)); @@ -218,6 +221,21 @@ static void create_pack_file(void) if (sz < 0) goto fail; } + + /* + * We hit the keepalive timeout without saying anything; send + * an empty message on the data sideband just to let the other + * side know we're still working on it, but don't have any data + * yet. + * + * If we don't have a sideband channel, there's no room in the + * protocol to say anything, so those clients are just out of + * luck. + */ + if (!ret && use_sideband) { + static const char buf[] = "0005\1"; + write_or_die(1, buf, 5); + } } if (finish_command(&pack_objects)) { @@ -722,6 +740,11 @@ static int upload_pack_config(const char *var, const char *value, void *unused) { if (!strcmp("uploadpack.allowtipsha1inwant", var)) allow_tip_sha1_in_want = git_config_bool(var, value); + else if (!strcmp("uploadpack.keepalive", var)) { + keepalive = git_config_int(var, value); + if (!keepalive) + keepalive = -1; + } return parse_hide_refs_config(var, value, "uploadpack"); } |