diff --git a/lib/client.js b/lib/client.js index 90af2656d..e1a752f6a 100644 --- a/lib/client.js +++ b/lib/client.js @@ -676,6 +676,17 @@ Request.prototype.end = function(fn){ return this._end(); }; +Request.prototype._setUploadTimeout = function () { + const self = this; + + // upload timeout it's wokrs only if deadline timeout is off + if (this._uploadTimeout && !this._uploadTimeoutTimer) { + this._uploadTimeoutTimer = setTimeout(() => { + self._timeoutError('Upload timeout of ', self._uploadTimeout, 'ETIMEDOUT'); + }, this._uploadTimeout); + } +}; + Request.prototype._end = function() { if (this._aborted) return this.callback(Error("The request has been aborted even before .end() was called")); @@ -709,9 +720,15 @@ Request.prototype._end = function() { // progress const handleProgress = (direction, e) => { + if (e.total > 0) { e.percent = e.loaded / e.total * 100; + + if(e.percent === 100) { + clearTimeout(self._uploadTimeoutTimer); + } } + e.direction = direction; self.emit('progress', e); }; @@ -728,6 +745,10 @@ Request.prototype._end = function() { } } + if(xhr.upload){ + this._setUploadTimeout(); + } + // initiate request try { if (this.username && this.password) { diff --git a/lib/request-base.js b/lib/request-base.js index bc4f4a7c0..2b2b722ee 100644 --- a/lib/request-base.js +++ b/lib/request-base.js @@ -46,8 +46,10 @@ function mixin(obj) { RequestBase.prototype.clearTimeout = function _clearTimeout(){ clearTimeout(this._timer); clearTimeout(this._responseTimeoutTimer); + clearTimeout(this._uploadTimeoutTimer); delete this._timer; delete this._responseTimeoutTimer; + delete this._uploadTimeoutTimer; return this; }; @@ -107,6 +109,7 @@ RequestBase.prototype.serialize = function serialize(fn){ * * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time. * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections. + * - upload is the time since last bit of data was sent or received. This timeout works only if deadline timeout is off * * Value of 0 or false means no timeout. * @@ -119,6 +122,7 @@ RequestBase.prototype.timeout = function timeout(options){ if (!options || 'object' !== typeof options) { this._timeout = options; this._responseTimeout = 0; + this._uploadTimeout = 0; return this; } @@ -130,6 +134,9 @@ RequestBase.prototype.timeout = function timeout(options){ case 'response': this._responseTimeout = options.response; break; + case 'upload': + this._uploadTimeout = options.upload; + break; default: console.warn("Unknown timeout option", option); } @@ -692,4 +699,5 @@ RequestBase.prototype._setTimeouts = function() { self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT'); }, this._responseTimeout); } + };