timeout on body and clear timeout internally
This commit is contained in:
parent
803ed8a502
commit
e09dfae0a5
1
index.js
1
index.js
|
@ -159,6 +159,7 @@ function Fetch(url, opts) {
|
|||
, status: res.statusCode
|
||||
, headers: headers
|
||||
, size: options.size
|
||||
, timeout: options.timeout
|
||||
});
|
||||
|
||||
resolve(output);
|
||||
|
|
|
@ -27,6 +27,7 @@ function Response(body, opts) {
|
|||
this.bodyUsed = false;
|
||||
this.size = opts.size;
|
||||
this.ok = this.status >= 200 && this.status < 300;
|
||||
this.timeout = opts.timeout;
|
||||
|
||||
}
|
||||
|
||||
|
@ -73,6 +74,16 @@ Response.prototype._decode = function() {
|
|||
this._raw = [];
|
||||
|
||||
return new Response.Promise(function(resolve, reject) {
|
||||
var resTimeout;
|
||||
|
||||
// allow timeout on slow response body
|
||||
if (self.timeout) {
|
||||
resTimeout = setTimeout(function() {
|
||||
self._abort = true;
|
||||
reject(new Error('response timeout at ' + self.url + ' over limit: ' + self.timeout));
|
||||
}, self.timeout);
|
||||
}
|
||||
|
||||
self.body.on('data', function(chunk) {
|
||||
if (self._abort || chunk === null) {
|
||||
return;
|
||||
|
@ -93,6 +104,7 @@ Response.prototype._decode = function() {
|
|||
return;
|
||||
}
|
||||
|
||||
clearTimeout(resTimeout);
|
||||
resolve(self._convert());
|
||||
});
|
||||
});
|
||||
|
|
|
@ -87,6 +87,15 @@ TestServer.prototype.router = function(req, res) {
|
|||
}, 1000);
|
||||
}
|
||||
|
||||
if (p === '/slow') {
|
||||
res.statusCode = 200;
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.write('test');
|
||||
setTimeout(function() {
|
||||
res.end('test');
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
if (p === '/cookie') {
|
||||
res.statusCode = 200;
|
||||
res.setHeader('Set-Cookie', ['a=1', 'b=1']);
|
||||
|
|
45
test/test.js
45
test/test.js
|
@ -316,6 +316,7 @@ describe('node-fetch', function() {
|
|||
});
|
||||
|
||||
it('should allow custom timeout', function() {
|
||||
this.timeout(500);
|
||||
url = base + '/timeout';
|
||||
opts = {
|
||||
timeout: 100
|
||||
|
@ -323,6 +324,42 @@ describe('node-fetch', function() {
|
|||
return expect(fetch(url, opts)).to.eventually.be.rejectedWith(Error);
|
||||
});
|
||||
|
||||
it('should allow custom timeout on response body', function() {
|
||||
this.timeout(500);
|
||||
url = base + '/slow';
|
||||
opts = {
|
||||
timeout: 100
|
||||
};
|
||||
return fetch(url, opts).then(function(res) {
|
||||
expect(res.ok).to.be.true;
|
||||
return expect(res.text()).to.eventually.be.rejectedWith(Error);
|
||||
});
|
||||
});
|
||||
|
||||
it('should clear internal timeout on fetch response', function (done) {
|
||||
this.timeout(1000);
|
||||
spawn('node', ['-e', 'require("./")("' + base + '/hello", { timeout: 5000 })'])
|
||||
.on('exit', function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should clear internal timeout on fetch redirect', function (done) {
|
||||
this.timeout(1000);
|
||||
spawn('node', ['-e', 'require("./")("' + base + '/redirect/301", { timeout: 5000 })'])
|
||||
.on('exit', function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should clear internal timeout on fetch error', function (done) {
|
||||
this.timeout(1000);
|
||||
spawn('node', ['-e', 'require("./")("' + base + '/error/reset", { timeout: 5000 })'])
|
||||
.on('exit', function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow POST request', function() {
|
||||
url = base + '/inspect';
|
||||
opts = {
|
||||
|
@ -583,12 +620,4 @@ describe('node-fetch', function() {
|
|||
expect(res.ok).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove timeout on response', function (done) {
|
||||
this.timeout(1e3);
|
||||
spawn('node', ['-e', 'require("./")("' + base + '/hello", {timeout: 1e4})'])
|
||||
.on('exit', function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue