summaryrefslogtreecommitdiffstats
path: root/connect.js
diff options
context:
space:
mode:
authorJannis R <mail@jannisr.de>2021-03-03 13:54:07 +0100
committerJannis R <mail@jannisr.de>2021-03-03 13:55:18 +0100
commitec8e8c67083404440d40067e5a40351521295397 (patch)
treef7f6c603787abc61cd4f669ccb15c384fe884ce8 /connect.js
parentd7b005b9090b6d0a895906cba0cb1c8cc41805f7 (diff)
connect()/request(): add connectTimeout with 60s default
closes #7
Diffstat (limited to 'connect.js')
-rw-r--r--connect.js29
1 files changed, 29 insertions, 0 deletions
diff --git a/connect.js b/connect.js
index 1c216a5..d508d35 100644
--- a/connect.js
+++ b/connect.js
@@ -16,11 +16,13 @@ const connectToGeminiServer = (opt, cb) => {
hostname,
port,
cert, key, passphrase,
+ connectTimeout,
tlsOpt,
} = {
hostname: '127.0.0.1',
port: DEFAULT_PORT,
cert: null, key: null, passphrase: null,
+ connectTimeout: 60 * 1000, // 60s
tlsOpt: {},
...opt,
}
@@ -34,6 +36,30 @@ const connectToGeminiServer = (opt, cb) => {
...tlsOpt,
})
+ // Sets the socket to timeout after timeout milliseconds of inactivity on
+ // the socket. By default net.Socket do not have a timeout.
+ // When an idle timeout is triggered the socket will receive a 'timeout'
+ // event but the connection will not be severed. The user must manually
+ // call socket.end() or socket.destroy() to end the connection.
+ // https://nodejs.org/api/net.html#net_socket_setnodelay_nodelay
+ let timeoutTimer = null
+ const onTimeout = () => {
+ clearTimeout(timeoutTimer)
+ const err = new Error('connect timeout')
+ err.timeout = connectTimeout
+ err.code = 'ETIMEDOUT' // is it okay to mimic syscall errors?
+ err.errno = -60
+ socket.destroy(err)
+ }
+ socket.once('timeout', onTimeout)
+ if (connectTimeout !== null) {
+ // This sets the timeout for inactivity on the *socket* layer. But the
+ // TLS handshake might also stall. This is why we also set one manually.
+ // see also https://github.com/nodejs/node/issues/5757
+ socket.setTimeout(connectTimeout)
+ timeoutTimer = setTimeout(onTimeout, connectTimeout)
+ }
+
let cbCalled = false
socket.once('error', (err) => {
if (cbCalled) return;
@@ -42,6 +68,9 @@ const connectToGeminiServer = (opt, cb) => {
})
socket.once('secureConnect', () => {
if (cbCalled) return;
+ // If timeout is 0, then the existing idle timeout is disabled.
+ // https://nodejs.org/api/net.html#net_socket_setnodelay_nodelay
+ socket.setTimeout(0)
cbCalled = true
cb(null, socket)
})