diff --git a/src/http-api.js b/src/http-api.js index 761a55217b0..81eafb4f3ca 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -631,19 +631,26 @@ module.exports.MatrixHttpApi.prototype = { let timedOut = false; let req; const localTimeoutMs = opts.localTimeoutMs || this.opts.localTimeoutMs; - if (localTimeoutMs) { - timeoutId = callbacks.setTimeout(function() { - timedOut = true; - if (req && req.abort) { - req.abort(); + + const resetTimeout = () => { + if (localTimeoutMs) { + if (timeoutId) { + callbacks.clearTimeout(timeoutId); } - defer.reject(new module.exports.MatrixError({ - error: "Locally timed out waiting for a response", - errcode: "ORG.MATRIX.JSSDK_TIMEOUT", - timeout: localTimeoutMs, - })); - }, localTimeoutMs); - } + timeoutId = callbacks.setTimeout(function() { + timedOut = true; + if (req && req.abort) { + req.abort(); + } + defer.reject(new module.exports.MatrixError({ + error: "Locally timed out waiting for a response", + errcode: "ORG.MATRIX.JSSDK_TIMEOUT", + timeout: localTimeoutMs, + })); + }, localTimeoutMs); + } + }; + resetTimeout(); const reqPromise = defer.promise; @@ -679,6 +686,17 @@ module.exports.MatrixHttpApi.prototype = { handlerFn(err, response, body); }, ); + // This will only work in a browser, where opts.request is the + // `browser-request` import. Currently `request` does not support progress + // updates - see https://github.com/request/request/pull/2346. + // `browser-request` returns an XHRHttpRequest which exposes `onprogress` + if ('onprogress' in req) { + req.onprogress = (e) => { + // Prevent the timeout from rejecting the deferred promise if progress is + // seen with the request + resetTimeout(); + }; + } if (req && req.abort) { // FIXME: This is EVIL, but I can't think of a better way to expose // abort() operations on underlying HTTP requests :(