diff options
author | Edward Thomson <ethomson@vercel.com> | 2023-03-21 09:34:09 +0000 |
---|---|---|
committer | Edward Thomson <ethomson@vercel.com> | 2023-03-21 09:36:37 +0000 |
commit | 4fe577247ab3dd5b9e74ffaaddf24027824b6a9d (patch) | |
tree | 917bea00bb89f37abe87b7ef4b351352b0705880 /src/libgit2/streams/stransport.c | |
parent | da0454e1440d72609df85fb77a7b3866d668e082 (diff) | |
download | libgit2-ethomson/nonblocking.tar.gz |
streams: sockets are non-blocking and can timeoutethomson/nonblocking
Make socket I/O non-blocking and add optional timeouts.
Users may now set `GIT_OPT_SET_SERVER_CONNECT_TIMEOUT` to set a shorter
connection timeout. (The connect timeout cannot be longer than the
operating system default.) Users may also now configure the socket read
and write timeouts with `GIT_OPT_SET_SERVER_TIMEOUT`.
By default, connects still timeout based on the operating system
defaults (typically 75 seconds) and socket read and writes block.
Add a test against our custom testing git server that ensures that we
can timeout reads against a slow server.
Diffstat (limited to 'src/libgit2/streams/stransport.c')
-rw-r--r-- | src/libgit2/streams/stransport.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/libgit2/streams/stransport.c b/src/libgit2/streams/stransport.c index 74ee0d1ee..d956df84d 100644 --- a/src/libgit2/streams/stransport.c +++ b/src/libgit2/streams/stransport.c @@ -161,7 +161,9 @@ static OSStatus write_cb(SSLConnectionRef conn, const void *data, size_t *len) if (ret < 0) { st->error = ret; - return -36; /* ioErr */ + return (ret == GIT_TIMEOUT) ? + errSSLNetworkTimeout : + -36 /* ioErr */; } return noErr; @@ -176,8 +178,12 @@ static ssize_t stransport_write(git_stream *stream, const char *data, size_t len GIT_UNUSED(flags); data_len = min(len, SSIZE_MAX); - if ((ret = SSLWrite(st->ctx, data, data_len, &processed)) != noErr) + if ((ret = SSLWrite(st->ctx, data, data_len, &processed)) != noErr) { + if (st->error == GIT_TIMEOUT) + return GIT_TIMEOUT; + return stransport_error(ret); + } GIT_ASSERT(processed < SSIZE_MAX); return (ssize_t)processed; @@ -207,7 +213,9 @@ static OSStatus read_cb(SSLConnectionRef conn, void *data, size_t *len) if (ret < 0) { st->error = ret; - error = -36; /* ioErr */ + error = (ret == GIT_TIMEOUT) ? + errSSLNetworkTimeout : + -36 /* ioErr */; break; } else if (ret == 0) { error = errSSLClosedGraceful; @@ -228,6 +236,9 @@ static ssize_t stransport_read(git_stream *stream, void *data, size_t len) OSStatus ret; if ((ret = SSLRead(st->ctx, data, len, &processed)) != noErr) { + if (st->error == GIT_TIMEOUT) + return GIT_TIMEOUT; + return stransport_error(ret); } |