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
|
, status: res.statusCode
|
||||||
, headers: headers
|
, headers: headers
|
||||||
, size: options.size
|
, size: options.size
|
||||||
|
, timeout: options.timeout
|
||||||
});
|
});
|
||||||
|
|
||||||
resolve(output);
|
resolve(output);
|
||||||
|
|
|
@ -27,6 +27,7 @@ function Response(body, opts) {
|
||||||
this.bodyUsed = false;
|
this.bodyUsed = false;
|
||||||
this.size = opts.size;
|
this.size = opts.size;
|
||||||
this.ok = this.status >= 200 && this.status < 300;
|
this.ok = this.status >= 200 && this.status < 300;
|
||||||
|
this.timeout = opts.timeout;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +74,16 @@ Response.prototype._decode = function() {
|
||||||
this._raw = [];
|
this._raw = [];
|
||||||
|
|
||||||
return new Response.Promise(function(resolve, reject) {
|
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) {
|
self.body.on('data', function(chunk) {
|
||||||
if (self._abort || chunk === null) {
|
if (self._abort || chunk === null) {
|
||||||
return;
|
return;
|
||||||
|
@ -93,6 +104,7 @@ Response.prototype._decode = function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearTimeout(resTimeout);
|
||||||
resolve(self._convert());
|
resolve(self._convert());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -87,6 +87,15 @@ TestServer.prototype.router = function(req, res) {
|
||||||
}, 1000);
|
}, 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') {
|
if (p === '/cookie') {
|
||||||
res.statusCode = 200;
|
res.statusCode = 200;
|
||||||
res.setHeader('Set-Cookie', ['a=1', 'b=1']);
|
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() {
|
it('should allow custom timeout', function() {
|
||||||
|
this.timeout(500);
|
||||||
url = base + '/timeout';
|
url = base + '/timeout';
|
||||||
opts = {
|
opts = {
|
||||||
timeout: 100
|
timeout: 100
|
||||||
|
@ -323,6 +324,42 @@ describe('node-fetch', function() {
|
||||||
return expect(fetch(url, opts)).to.eventually.be.rejectedWith(Error);
|
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() {
|
it('should allow POST request', function() {
|
||||||
url = base + '/inspect';
|
url = base + '/inspect';
|
||||||
opts = {
|
opts = {
|
||||||
|
@ -583,12 +620,4 @@ describe('node-fetch', function() {
|
||||||
expect(res.ok).to.be.true;
|
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