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.
Files changed (3) hide show
  1. package/README.md +3 -3
  2. package/index.js +18 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # reachable-url
2
2
 
3
- ![Last version](https://img.shields.io/github/tag/Kikobeats/reachable-url.svg?style=flat-square)
4
- [![Coverage Status](https://img.shields.io/coveralls/Kikobeats/reachable-url.svg?style=flat-square)](https://coveralls.io/github/Kikobeats/reachable-url)
5
- [![NPM Status](https://img.shields.io/npm/dm/reachable-url.svg?style=flat-square)](https://www.npmjs.org/package/reachable-url)
3
+ [![Last version](https://img.shields.io/github/v/tag/Kikobeats/reachable-url?style=flat-square)](https://github.com/Kikobeats/reachable-url/releases)
4
+ [![Coverage Status](https://img.shields.io/coverallsCoverage/github/Kikobeats/reachable-url?style=flat-square)](https://coveralls.io/github/Kikobeats/reachable-url)
5
+ [![NPM Status](https://img.shields.io/npm/dm/reachable-url?style=flat-square)](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`, a retry needs a retryable error, and `maxBody: Infinity`
70
- // asked for the entity, so all three keep the body.
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) && !willRetry(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 cancelDownload = (req, res) => {
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.4",
5
+ "version": "2.1.6",
6
6
  "main": "index.js",
7
7
  "author": {
8
8
  "email": "josefrancisco.verdu@gmail.com",