diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2019-04-07 17:40:23 +0900 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2019-06-10 19:58:22 +0100 |
commit | d171fbee16d7ca7868c1d2d85f19d6dcaf31f8ee (patch) | |
tree | bbd4330d399ab79383f5f4af2cb5e00016fb8b5a | |
parent | 9af1de5bc5b57a68bd659e9f76540c3f569772e8 (diff) | |
download | libgit2-d171fbee16d7ca7868c1d2d85f19d6dcaf31f8ee.tar.gz |
http: allow server to drop a keepalive connection
When we have a keep-alive connection to the server, that server may
legally drop the connection for any reason once a successful request and
response has occurred. It's common for servers to drop the connection
after some amount of time or number of requests have occurred.
-rw-r--r-- | src/transports/http.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/transports/http.c b/src/transports/http.c index d2ae559be..f29d09b75 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -113,6 +113,7 @@ typedef struct { enum last_cb last_cb; int parse_error; int error; + unsigned request_count; unsigned parse_finished : 1, keepalive : 1, replay_count : 4; @@ -936,6 +937,10 @@ replay: if ((error = gitno_recv(&t->parse_buffer)) < 0) { goto done; + } else if (error == 0 && t->request_count > 0) { + /* Server closed a keep-alive socket; reconnect. */ + auth_replay = true; + goto done; } else if (error == 0) { git_error_set(GIT_ERROR_NET, "unexpected disconnection from server"); error = -1; @@ -985,6 +990,8 @@ replay: } } + t->request_count++; + if (auth_replay) goto replay; @@ -999,6 +1006,7 @@ replay: */ t->proxy_opts.type = GIT_PROXY_NONE; t->replay_count = 0; + t->request_count = 0; done: return error; @@ -1058,6 +1066,7 @@ static int http_connect(http_subtransport *t) t->connected = 0; t->keepalive = 0; + t->request_count = 0; if (t->proxy_opts.type == GIT_PROXY_SPECIFIED) { url = &t->proxy.url; @@ -1185,6 +1194,10 @@ replay: if ((error = gitno_recv(&t->parse_buffer)) < 0) { goto done; + } else if (error == 0 && t->request_count > 0) { + /* Server closed a keep-alive socket; reconnect. */ + auth_replay = true; + goto done; } else if (error == 0) { git_error_set(GIT_ERROR_NET, "unexpected disconnection from server"); error = -1; @@ -1235,6 +1248,8 @@ replay: } } + t->request_count++; + if (auth_replay) { s->sent_request = 0; |