Make sure to finalize the request properly (#432)

Unfortunately, I could not write a test case that allows testing the bug
in #428. Credits to Roman Zaharenkov <ZaharenkovRoman@gmail.com> for
discovering this long-standing bug and proposing a first version of the
fix.

Co-authored-by: Roman Zaharenkov <ZaharenkovRoman@gmail.com>
Fixes: #428
This commit is contained in:
Timothy Gu 2018-03-24 20:48:33 -07:00
parent d522036bee
commit aed2e69a39
No known key found for this signature in database
GPG Key ID: 7FE6B095B582B0D4
1 changed files with 13 additions and 3 deletions

View File

@ -47,18 +47,23 @@ export default function fetch(url, opts) {
const req = send(options);
let reqTimeout;
function finalize() {
req.abort();
clearTimeout(reqTimeout);
}
if (request.timeout) {
req.once('socket', socket => {
reqTimeout = setTimeout(() => {
req.abort();
reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
finalize();
}, request.timeout);
});
}
req.on('error', err => {
clearTimeout(reqTimeout);
reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
finalize();
});
req.on('response', res => {
@ -78,6 +83,7 @@ export default function fetch(url, opts) {
switch (request.redirect) {
case 'error':
reject(new FetchError(`redirect mode is set to error: ${request.url}`, 'no-redirect'));
finalize();
return;
case 'manual':
// node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.
@ -94,6 +100,7 @@ export default function fetch(url, opts) {
// HTTP-redirect fetch step 5
if (request.counter >= request.follow) {
reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
finalize();
return;
}
@ -111,7 +118,9 @@ export default function fetch(url, opts) {
// HTTP-redirect fetch step 9
if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'))
reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
finalize();
return;
}
// HTTP-redirect fetch step 11
@ -123,6 +132,7 @@ export default function fetch(url, opts) {
// HTTP-redirect fetch step 15
resolve(fetch(new Request(locationURL, requestOpts)));
finalize();
return;
}
}