reachable-url 2.1.4 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/index.js +18 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# reachable-url
|
|
2
2
|
|
|
3
|
-
](https://github.com/Kikobeats/reachable-url/releases)
|
|
4
|
+
[](https://coveralls.io/github/Kikobeats/reachable-url)
|
|
5
|
+
[](https://www.npmjs.com/package/reachable-url)
|
|
6
6
|
|
|
7
7
|
> Given an URL, it resolves as fast as possible, performing a GET without downloading the body.
|
|
8
8
|
|
package/index.js
CHANGED
|
@@ -66,22 +66,35 @@ const willRetry = res => {
|
|
|
66
66
|
|
|
67
67
|
// `responseType: 'buffer'` would read the whole entity a server sent despite
|
|
68
68
|
// `Range`; the status and headers already answer reachability. A cache entry is
|
|
69
|
-
// written on `end`,
|
|
70
|
-
//
|
|
69
|
+
// written on `end`, and `maxBody: Infinity` asked for the entity, so both keep
|
|
70
|
+
// the body. A retryable status still has to become a retryable error: canceling
|
|
71
|
+
// the promise would skip the retry, so the unread body is destroyed instead
|
|
72
|
+
// and got sees ECONNRESET.
|
|
71
73
|
const shouldAbortDownload = (res, maxBody) =>
|
|
72
|
-
maxBody !== Infinity && !res.request.options.cache && !honoredRange(res)
|
|
74
|
+
maxBody !== Infinity && !res.request.options.cache && !honoredRange(res)
|
|
73
75
|
|
|
74
76
|
// Asking for a range while wanting more of the body than it holds is
|
|
75
77
|
// contradictory: a server honoring it would answer with that one byte.
|
|
76
78
|
const withoutRange = opts => ({ ...opts, headers: { ...opts.headers, Range: undefined } })
|
|
77
79
|
|
|
78
|
-
const
|
|
80
|
+
const stampTotal = res => {
|
|
79
81
|
// `phases.total` is filled on `end`, which a cancelled request never emits,
|
|
80
82
|
// and the timer does not record the cancel either.
|
|
81
83
|
res.timings.phases.total = Date.now() - res.timings.start
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const cancelDownload = (req, res) => {
|
|
87
|
+
stampTotal(res)
|
|
82
88
|
req.cancel()
|
|
83
89
|
}
|
|
84
90
|
|
|
91
|
+
// Destroying the IncomingMessage (not the promise) lets got treat the attempt
|
|
92
|
+
// as ECONNRESET and retry. `req.cancel()` would reject with CancelError.
|
|
93
|
+
const abortBodyForRetry = res => {
|
|
94
|
+
stampTotal(res)
|
|
95
|
+
res.destroy()
|
|
96
|
+
}
|
|
97
|
+
|
|
85
98
|
const keepFirstBytes = (req, res, maxBody) => {
|
|
86
99
|
const chunks = []
|
|
87
100
|
let read = 0
|
|
@@ -116,6 +129,7 @@ const reachableUrl = async (url, { maxBody = 0, ...opts } = {}) => {
|
|
|
116
129
|
req.on('response', res => {
|
|
117
130
|
response = res
|
|
118
131
|
if (!shouldAbortDownload(res, maxBody)) return
|
|
132
|
+
if (willRetry(res)) return abortBodyForRetry(res)
|
|
119
133
|
if (maxBody === 0) return cancelDownload(req, res)
|
|
120
134
|
keepFirstBytes(req, res, maxBody)
|
|
121
135
|
})
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "reachable-url",
|
|
3
3
|
"description": "Resolve a URL as fast as possible and report whether the destination is reachable over HTTP.",
|
|
4
4
|
"homepage": "https://github.com/Kikobeats/reachable-url",
|
|
5
|
-
"version": "2.1.
|
|
5
|
+
"version": "2.1.6",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"author": {
|
|
8
8
|
"email": "josefrancisco.verdu@gmail.com",
|