summaryrefslogtreecommitdiff
path: root/http.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-10-12 22:29:40 +0000
committerJonathan Nieder <jrnieder@gmail.com>2013-10-14 07:03:59 -0700
commita15d069a19867b9c508ccfca5702f36448e829e8 (patch)
treea2a85f65e195cbcc499edeb6b3e6bf55d2d1ce3a /http.c
parente47a8583a20256851e7fc882233e3bd5bf33dc6e (diff)
downloadgit-a15d069a19867b9c508ccfca5702f36448e829e8.tar.gz
http: enable keepalive on TCP sockets
This is a follow up to commit e47a8583 (enable SO_KEEPALIVE for connected TCP sockets, 2011-12-06). Sockets may never receive notification of some link errors, causing "git fetch" or similar processes to hang forever. Enabling keepalive messages allows hung processes to error out after a few minutes/hours depending on the keepalive settings of the system. I noticed this problem with some non-interactive cronjobs getting hung when talking to HTTP servers. Signed-off-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Diffstat (limited to 'http.c')
-rw-r--r--http.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/http.c b/http.c
index b2ae8de16d..a2c1819e22 100644
--- a/http.c
+++ b/http.c
@@ -233,6 +233,24 @@ static int has_cert_password(void)
return 0;
}
+/* curl 7.25.0 has CURLOPT_TCP_KEEPALIVE, too, but we support older curl */
+static int sockopt_callback(void *client, curl_socket_t fd, curlsocktype type)
+{
+ int ka = 1;
+ int rc;
+ socklen_t len = (socklen_t)sizeof(ka);
+
+ if (type != CURLSOCKTYPE_IPCXN)
+ return 0;
+
+ rc = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&ka, len);
+ if (rc < 0)
+ warning("unable to set SO_KEEPALIVE on socket %s",
+ strerror(errno));
+
+ return 0; /* CURL_SOCKOPT_OK only exists since curl 7.21.5 */
+}
+
static CURL *get_curl_handle(void)
{
CURL *result = curl_easy_init();
@@ -298,6 +316,10 @@ static CURL *get_curl_handle(void)
if (curl_http_proxy)
curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
+#if LIBCURL_VERSION_NUM >= 0x071000
+ curl_easy_setopt(result, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
+#endif
+
return result;
}