1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-25 05:23:13 +03:00

Use XHR onprogress to debounce http._request timeout (#392)

Instead of just using a timeout to reject ongoing requests, reset the timeout when progress is observed (at least when requests are done from browsers).

This is to fix https://github.com/vector-im/riot-web/issues/2737
This commit is contained in:
Luke Barnard
2017-03-16 09:50:24 +00:00
committed by Richard van der Hoff
parent 8b4b0e0d39
commit 2f5da3851b

View File

@@ -631,19 +631,26 @@ module.exports.MatrixHttpApi.prototype = {
let timedOut = false; let timedOut = false;
let req; let req;
const localTimeoutMs = opts.localTimeoutMs || this.opts.localTimeoutMs; const localTimeoutMs = opts.localTimeoutMs || this.opts.localTimeoutMs;
if (localTimeoutMs) {
timeoutId = callbacks.setTimeout(function() { const resetTimeout = () => {
timedOut = true; if (localTimeoutMs) {
if (req && req.abort) { if (timeoutId) {
req.abort(); callbacks.clearTimeout(timeoutId);
} }
defer.reject(new module.exports.MatrixError({ timeoutId = callbacks.setTimeout(function() {
error: "Locally timed out waiting for a response", timedOut = true;
errcode: "ORG.MATRIX.JSSDK_TIMEOUT", if (req && req.abort) {
timeout: localTimeoutMs, req.abort();
})); }
}, localTimeoutMs); 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; const reqPromise = defer.promise;
@@ -679,6 +686,17 @@ module.exports.MatrixHttpApi.prototype = {
handlerFn(err, response, body); 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) { if (req && req.abort) {
// FIXME: This is EVIL, but I can't think of a better way to expose // FIXME: This is EVIL, but I can't think of a better way to expose
// abort() operations on underlying HTTP requests :( // abort() operations on underlying HTTP requests :(