@web-std/fetch
Advanced tools
+37
-26
@@ -1240,3 +1240,3 @@ 'use strict'; | ||
| /** | ||
| * @param {string|Request input Url or Request instance | ||
| * @param {string|Request} input Url or Request instance | ||
| * @param {RequestInit} init Custom options | ||
@@ -1360,5 +1360,5 @@ */ | ||
| * Convert a Request to Node.js http request options. | ||
| * The options object to be passed to http.request | ||
| * | ||
| * @param Request A Request instance | ||
| * @return Object The options object to be passed to http.request | ||
| * @param {Request} request - A Request instance | ||
| */ | ||
@@ -1483,3 +1483,5 @@ const getNodeRequestOptions = request => { | ||
| const {signal} = request; | ||
| /** @type {Response|null} */ | ||
| let response = null; | ||
| /** @type {import('http').IncomingMessage|null} */ | ||
| let response_ = null; | ||
@@ -1531,20 +1533,24 @@ | ||
| fixResponseChunkedTransferBadEnding(request_, err => { | ||
| response_.emit('error', err); | ||
| if (signal && signal.aborted) { | ||
| return | ||
| } | ||
| response_?.emit("error", err); | ||
| }); | ||
| /* c8 ignore next 18 */ | ||
| if (process.version < 'v14') { | ||
| if (parseInt(process.version.substring(1)) < 14) { | ||
| // Before Node.js 14, pipeline() does not fully support async iterators and does not always | ||
| // properly handle when the socket close/end events are out of order. | ||
| request_.on('socket', s => { | ||
| let endedWithEventsCount; | ||
| s.prependListener('end', () => { | ||
| endedWithEventsCount = s._eventsCount; | ||
| }); | ||
| s.prependListener('close', hadError => { | ||
| // if a data listener is still present we didn't end cleanly | ||
| const hasDataListener = s.listenerCount('data') > 0; | ||
| // if end happened before close but the socket didn't emit an error, do it now | ||
| if (response && endedWithEventsCount < s._eventsCount && !hadError) { | ||
| const err = new Error('Premature close'); | ||
| err.code = 'ERR_STREAM_PREMATURE_CLOSE'; | ||
| response_.emit('error', err); | ||
| if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { | ||
| const err = Object.assign(new Error('Premature close'), { | ||
| code: 'ERR_STREAM_PREMATURE_CLOSE' | ||
| }); | ||
| response_?.emit('error', err); | ||
| } | ||
@@ -1561,3 +1567,3 @@ }); | ||
| // HTTP fetch step 5 | ||
| if (isRedirect(response_.statusCode)) { | ||
| if (isRedirect(Number(response_.statusCode))) { | ||
| // HTTP fetch step 5.2 | ||
@@ -1597,2 +1603,3 @@ const location = headers.get('Location'); | ||
| // Create a new Request object. | ||
| /** @type {RequestInit} */ | ||
| const requestOptions = { | ||
@@ -1630,3 +1637,3 @@ headers: new Headers(request.headers), | ||
| // HTTP-redirect fetch step 15 | ||
| resolve(fetch(new Request(locationURL, requestOptions))); | ||
| fetch(new Request(locationURL.href, requestOptions)).then(resolve, reject); | ||
| finalize(); | ||
@@ -1736,4 +1743,9 @@ return; | ||
| /** | ||
| * | ||
| * @param {import('http').ClientRequest} request | ||
| * @param {(error:Error) => void} errorCallback | ||
| */ | ||
| function fixResponseChunkedTransferBadEnding(request, errorCallback) { | ||
| const LAST_CHUNK = Buffer.from('0\r\n'); | ||
| /** @type {import('net').Socket} */ | ||
| let socket; | ||
@@ -1746,14 +1758,13 @@ | ||
| request.on('response', response => { | ||
| const {headers} = response; | ||
| if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { | ||
| let properLastChunkReceived = false; | ||
| socket.on('data', buf => { | ||
| properLastChunkReceived = Buffer.compare(buf.slice(-3), LAST_CHUNK) === 0; | ||
| }); | ||
| socket.prependListener('close', () => { | ||
| if (!properLastChunkReceived) { | ||
| const err = new Error('Premature close'); | ||
| err.code = 'ERR_STREAM_PREMATURE_CLOSE'; | ||
| socket.prependListener('close', hadError => { | ||
| // if a data listener is still present we didn't end cleanly | ||
| const hasDataListener = socket.listenerCount('data') > 0; | ||
| if (hasDataListener && !hadError) { | ||
| const err = Object.assign(new Error('Premature close'), { | ||
| code: 'ERR_STREAM_PREMATURE_CLOSE' | ||
| }); | ||
| errorCallback(err); | ||
@@ -1760,0 +1771,0 @@ } |
+1
-1
| { | ||
| "name": "@web-std/fetch", | ||
| "version": "2.0.2", | ||
| "version": "2.0.3", | ||
| "description": "Web compatible Fetch API implementation for node.js", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.cjs", |
+34
-23
@@ -58,3 +58,5 @@ /** | ||
| const {signal} = request; | ||
| /** @type {Response|null} */ | ||
| let response = null; | ||
| /** @type {import('http').IncomingMessage|null} */ | ||
| let response_ = null; | ||
@@ -106,20 +108,24 @@ | ||
| fixResponseChunkedTransferBadEnding(request_, err => { | ||
| response_.emit('error', err); | ||
| if (signal && signal.aborted) { | ||
| return | ||
| } | ||
| response_?.emit("error", err); | ||
| }); | ||
| /* c8 ignore next 18 */ | ||
| if (process.version < 'v14') { | ||
| if (parseInt(process.version.substring(1)) < 14) { | ||
| // Before Node.js 14, pipeline() does not fully support async iterators and does not always | ||
| // properly handle when the socket close/end events are out of order. | ||
| request_.on('socket', s => { | ||
| let endedWithEventsCount; | ||
| s.prependListener('end', () => { | ||
| endedWithEventsCount = s._eventsCount; | ||
| }); | ||
| s.prependListener('close', hadError => { | ||
| // if a data listener is still present we didn't end cleanly | ||
| const hasDataListener = s.listenerCount('data') > 0 | ||
| // if end happened before close but the socket didn't emit an error, do it now | ||
| if (response && endedWithEventsCount < s._eventsCount && !hadError) { | ||
| const err = new Error('Premature close'); | ||
| err.code = 'ERR_STREAM_PREMATURE_CLOSE'; | ||
| response_.emit('error', err); | ||
| if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { | ||
| const err = Object.assign(new Error('Premature close'), { | ||
| code: 'ERR_STREAM_PREMATURE_CLOSE' | ||
| }); | ||
| response_?.emit('error', err); | ||
| } | ||
@@ -136,3 +142,3 @@ }); | ||
| // HTTP fetch step 5 | ||
| if (isRedirect(response_.statusCode)) { | ||
| if (isRedirect(Number(response_.statusCode))) { | ||
| // HTTP fetch step 5.2 | ||
@@ -172,2 +178,3 @@ const location = headers.get('Location'); | ||
| // Create a new Request object. | ||
| /** @type {RequestInit} */ | ||
| const requestOptions = { | ||
@@ -205,3 +212,3 @@ headers: new Headers(request.headers), | ||
| // HTTP-redirect fetch step 15 | ||
| resolve(fetch(new Request(locationURL, requestOptions))); | ||
| fetch(new Request(locationURL.href, requestOptions)).then(resolve, reject); | ||
| finalize(); | ||
@@ -311,4 +318,9 @@ return; | ||
| /** | ||
| * | ||
| * @param {import('http').ClientRequest} request | ||
| * @param {(error:Error) => void} errorCallback | ||
| */ | ||
| function fixResponseChunkedTransferBadEnding(request, errorCallback) { | ||
| const LAST_CHUNK = Buffer.from('0\r\n'); | ||
| /** @type {import('net').Socket} */ | ||
| let socket; | ||
@@ -321,14 +333,13 @@ | ||
| request.on('response', response => { | ||
| const {headers} = response; | ||
| if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { | ||
| let properLastChunkReceived = false; | ||
| socket.on('data', buf => { | ||
| properLastChunkReceived = Buffer.compare(buf.slice(-3), LAST_CHUNK) === 0; | ||
| }); | ||
| socket.prependListener('close', () => { | ||
| if (!properLastChunkReceived) { | ||
| const err = new Error('Premature close'); | ||
| err.code = 'ERR_STREAM_PREMATURE_CLOSE'; | ||
| socket.prependListener('close', hadError => { | ||
| // if a data listener is still present we didn't end cleanly | ||
| const hasDataListener = socket.listenerCount('data') > 0; | ||
| if (hasDataListener && !hadError) { | ||
| const err = Object.assign(new Error('Premature close'), { | ||
| code: 'ERR_STREAM_PREMATURE_CLOSE' | ||
| }) | ||
| errorCallback(err); | ||
@@ -335,0 +346,0 @@ } |
+3
-3
@@ -36,3 +36,3 @@ | ||
| /** | ||
| * @param {string|Request input Url or Request instance | ||
| * @param {string|Request} input Url or Request instance | ||
| * @param {RequestInit} init Custom options | ||
@@ -156,5 +156,5 @@ */ | ||
| * Convert a Request to Node.js http request options. | ||
| * The options object to be passed to http.request | ||
| * | ||
| * @param Request A Request instance | ||
| * @return Object The options object to be passed to http.request | ||
| * @param {Request} request - A Request instance | ||
| */ | ||
@@ -161,0 +161,0 @@ export const getNodeRequestOptions = request => { |
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
196864
0.56%3299
0.55%19
-5%