rekwest 8.0.0 → 8.1.0
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 +264 -260
- package/dist/ackn.cjs +9 -0
- package/dist/config.cjs +1 -0
- package/dist/cookies.cjs +1 -1
- package/dist/transfer.cjs +1 -5
- package/package.json +81 -76
- package/src/ackn.js +46 -33
- package/src/config.js +91 -90
- package/src/constants.js +11 -11
- package/src/cookies.js +121 -121
- package/src/errors.js +18 -18
- package/src/formdata.js +229 -229
- package/src/index.js +83 -83
- package/src/mediatypes.js +6 -6
- package/src/mixin.js +118 -118
- package/src/postflight.js +64 -64
- package/src/preflight.js +84 -84
- package/src/redirects.js +86 -86
- package/src/transfer.js +104 -106
- package/src/transform.js +112 -112
- package/src/utils.js +198 -198
- package/src/validation.js +33 -33
package/README.md
CHANGED
|
@@ -1,260 +1,264 @@
|
|
|
1
|
-
The robust request library that humanity deserves 🌐
|
|
2
|
-
---
|
|
3
|
-
This package provides highly likely functional and **easy-to-use** abstraction atop of
|
|
4
|
-
native [http(s).request](https://nodejs.org/api/https.html#httpsrequesturl-options-callback)
|
|
5
|
-
and [http2.request](https://nodejs.org/api/http2.html#clienthttp2sessionrequestheaders-options).
|
|
6
|
-
|
|
7
|
-
## Abstract
|
|
8
|
-
|
|
9
|
-
* Fetch-alike 🥏
|
|
10
|
-
* Cool-beans
|
|
11
|
-
* Automatic HTTP/2 support (ALPN negotiation) 💼
|
|
12
|
-
* Automatic or opt-in body parse (with non-UTF-8 charset decoding) 🉑
|
|
13
|
-
* Automatic and simplistic `Cookies` treatment (with **TTL** support) 🍪
|
|
14
|
-
* Automatic body decoding (and opt-in request body encoding) 🗜️
|
|
15
|
-
* Better error management 🚥
|
|
16
|
-
* Built-in streamable `FormData` interface 🔌
|
|
17
|
-
* Support
|
|
18
|
-
* Support
|
|
19
|
-
* Support
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
[
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
console.
|
|
63
|
-
console.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
import
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
fd.append('
|
|
93
|
-
fd.append('
|
|
94
|
-
fd.append('
|
|
95
|
-
fd.append('
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
[
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
console.
|
|
113
|
-
console.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
* `
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
* `
|
|
129
|
-
* `
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
* `
|
|
141
|
-
* `
|
|
142
|
-
|
|
143
|
-
* `
|
|
144
|
-
* `
|
|
145
|
-
* `
|
|
146
|
-
* `
|
|
147
|
-
* `
|
|
148
|
-
* `
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
* `
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
* **
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
* `body` **{
|
|
173
|
-
|
|
174
|
-
* `
|
|
175
|
-
* `
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
* `
|
|
181
|
-
* `
|
|
182
|
-
* `
|
|
183
|
-
* `
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
} from '
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
1
|
+
The robust request library that humanity deserves 🌐
|
|
2
|
+
---
|
|
3
|
+
This package provides highly likely functional and **easy-to-use** abstraction atop of
|
|
4
|
+
native [http(s).request](https://nodejs.org/api/https.html#httpsrequesturl-options-callback)
|
|
5
|
+
and [http2.request](https://nodejs.org/api/http2.html#clienthttp2sessionrequestheaders-options).
|
|
6
|
+
|
|
7
|
+
## Abstract
|
|
8
|
+
|
|
9
|
+
* Fetch-alike 🥏
|
|
10
|
+
* Cool-beans 🫛 config options (with defaults) 📋
|
|
11
|
+
* Automatic HTTP/2 support (ALPN negotiation) 💼
|
|
12
|
+
* Automatic or opt-in body parse (with non-UTF-8 charset decoding) 🉑
|
|
13
|
+
* Automatic and simplistic `Cookies` treatment (with **TTL** support) 🍪
|
|
14
|
+
* Automatic body decoding (and opt-in request body encoding) 🗜️
|
|
15
|
+
* Better error management 🚥
|
|
16
|
+
* Built-in streamable `FormData` interface 🔌
|
|
17
|
+
* Support certificate pinning for enhanced TLS security 🛡️
|
|
18
|
+
* Support redirects & retries with fine-grained tune-ups 🪛
|
|
19
|
+
* Support plenty request body types (include blobs & streams) 📦
|
|
20
|
+
* Support both CJS and ESM module systems 🧩
|
|
21
|
+
* Fully promise-able ⏳ and pipe-able 🌀
|
|
22
|
+
* Zero dependencies 🗽
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
|
|
26
|
+
* Node.js `>=22.0.0`
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install rekwest --save
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Usage
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
import rekwest, { constants } from 'rekwest';
|
|
38
|
+
|
|
39
|
+
const {
|
|
40
|
+
HTTP2_HEADER_AUTHORIZATION,
|
|
41
|
+
HTTP2_HEADER_CONTENT_ENCODING,
|
|
42
|
+
HTTP2_METHOD_POST,
|
|
43
|
+
HTTP_STATUS_OK,
|
|
44
|
+
} = constants;
|
|
45
|
+
|
|
46
|
+
const url = 'https://somewhe.re/somewhat/endpoint';
|
|
47
|
+
|
|
48
|
+
const res = await rekwest(url, {
|
|
49
|
+
body: { celestial: 'payload' },
|
|
50
|
+
headers: {
|
|
51
|
+
[HTTP2_HEADER_AUTHORIZATION]: 'Bearer [token]',
|
|
52
|
+
[HTTP2_HEADER_CONTENT_ENCODING]: 'br', // Enables: body encoding
|
|
53
|
+
/**
|
|
54
|
+
* [HTTP2_HEADER_CONTENT_TYPE] is undue for
|
|
55
|
+
* Array/Blob/File/FormData/Object/URLSearchParams body types
|
|
56
|
+
* and will be set automatically, with an option to override it here.
|
|
57
|
+
*/
|
|
58
|
+
},
|
|
59
|
+
method: HTTP2_METHOD_POST,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
console.assert(res.statusCode === HTTP_STATUS_OK);
|
|
63
|
+
console.info(res.headers);
|
|
64
|
+
console.log(res.body);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
import { Readable } from 'node:stream';
|
|
71
|
+
import rekwest, {
|
|
72
|
+
constants,
|
|
73
|
+
FormData,
|
|
74
|
+
} from 'rekwest';
|
|
75
|
+
|
|
76
|
+
const {
|
|
77
|
+
HTTP2_HEADER_AUTHORIZATION,
|
|
78
|
+
HTTP2_HEADER_CONTENT_ENCODING,
|
|
79
|
+
HTTP2_METHOD_POST,
|
|
80
|
+
HTTP_STATUS_OK,
|
|
81
|
+
} = constants;
|
|
82
|
+
|
|
83
|
+
const blob = new Blob(['bits']);
|
|
84
|
+
const file = new File(['bits'], 'file.xyz');
|
|
85
|
+
const rbl = Readable.from('bits');
|
|
86
|
+
const rds = ReadableStream.from('bits');
|
|
87
|
+
|
|
88
|
+
const fd = new FormData({
|
|
89
|
+
aux: new Date(), // Either [[key, value]] or kv sequenceable
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
fd.append('celestial', 'payload');
|
|
93
|
+
fd.append('blob', blob, 'blob.xyz');
|
|
94
|
+
fd.append('file', file);
|
|
95
|
+
fd.append('rbl', rbl, 'rbl.xyz');
|
|
96
|
+
fd.append('rds', rds, 'rds.xyz');
|
|
97
|
+
/**
|
|
98
|
+
* Streamable entries are consumed on request submittion.
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
const url = 'https://somewhe.re/somewhat/endpoint';
|
|
102
|
+
|
|
103
|
+
const res = await rekwest(url, {
|
|
104
|
+
body: fd,
|
|
105
|
+
headers: {
|
|
106
|
+
[HTTP2_HEADER_AUTHORIZATION]: 'Bearer [token]',
|
|
107
|
+
[HTTP2_HEADER_CONTENT_ENCODING]: 'zstd', // Enables: body encoding
|
|
108
|
+
},
|
|
109
|
+
method: HTTP2_METHOD_POST,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
console.assert(res.statusCode === HTTP_STATUS_OK);
|
|
113
|
+
console.info(res.headers);
|
|
114
|
+
console.log(res.body);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### API
|
|
118
|
+
|
|
119
|
+
#### `rekwest(url[, options])`
|
|
120
|
+
|
|
121
|
+
* `url` **{string | URL}** The URL to send the request to.
|
|
122
|
+
* `options` **{Object}**
|
|
123
|
+
Extends [http(s).RequestOptions](https://nodejs.org/api/https.html#httpsrequesturl-options-callback) along with
|
|
124
|
+
extra [http2.ClientSessionOptions](https://nodejs.org/api/http2.html#http2connectauthority-options-listener)
|
|
125
|
+
& [http2.ClientSessionRequestOptions](https://nodejs.org/api/http2.html#clienthttp2sessionrequestheaders-options)
|
|
126
|
+
and [tls.ConnectionOptions](https://nodejs.org/api/tls.html#tlsconnectoptions-callback)
|
|
127
|
+
for HTTP/2 attunes.
|
|
128
|
+
* `allowDowngrade` **{boolean}** `Default: false` Controls whether `https:` redirects to `http:` are allowed.
|
|
129
|
+
* `baseURL` **{string | URL}** The base URL to use in cases where `url` is a relative URL.
|
|
130
|
+
* `body` **{string | Array | ArrayBuffer | ArrayBufferView | AsyncIterator | Blob | Buffer | DataView | File |
|
|
131
|
+
FormData | Iterator | Object | Readable | ReadableStream | SharedArrayBuffer | URLSearchParams}** The body to send
|
|
132
|
+
with the request.
|
|
133
|
+
* `bufferBody` **{boolean}** `Default: false` Toggles the buffering of the streamable request bodies for redirects and
|
|
134
|
+
retries.
|
|
135
|
+
* `certPins` **{string[]}** `Default: []` A list of SHA-256 certificate fingerprints (colon-separated hex) used for
|
|
136
|
+
HTTPS certificate pinning. If the list is non-empty and none of the fingerprints match, the connection will be
|
|
137
|
+
rejected.
|
|
138
|
+
* `cookies` **{boolean | string | string[] | [k, v][] | Cookies | Object | URLSearchParams}** `Default: true` The
|
|
139
|
+
cookies to add to the request. Manually set `cookie` header to override.
|
|
140
|
+
* `cookiesTTL` **{boolean}** `Default: false` Controls enablement of TTL for the cookie cache.
|
|
141
|
+
* `credentials` **{include | omit | same-origin}** `Default: same-origin` Controls credentials in case of cross-origin
|
|
142
|
+
redirects.
|
|
143
|
+
* `decodersOptions` **{Object}** Configures decoder options, e.g.: `brotli`, `zlib`, `zstd`.
|
|
144
|
+
* `digest` **{boolean}** `Default: true` Controls whether to read the response stream or add a mixin.
|
|
145
|
+
* `encodersOptions` **{Object}** Configures encoder options, e.g.: `brotli`, `zlib`, `zstd`.
|
|
146
|
+
* `follow` **{number}** `Default: 20` The number of redirects to follow.
|
|
147
|
+
* `h2` **{boolean}** `Default: false` Forces the use of HTTP/2 protocol.
|
|
148
|
+
* `headers` **{Object}** The headers to add to the request.
|
|
149
|
+
* `params` **{Object}** The search params to add to the `url`.
|
|
150
|
+
* `parse` **{boolean}** `Default: true` Controls whether to parse response body or return a buffer.
|
|
151
|
+
* `redirect` **{error | follow | manual}** `Default: follow` Controls the redirect flows.
|
|
152
|
+
* `retry` **{Object}** Represents the retry options.
|
|
153
|
+
* `attempts` **{number}** `Default: 0` The number of retry attempts.
|
|
154
|
+
* `backoffStrategy` **{string}** `Default: interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)`
|
|
155
|
+
The backoff strategy uses a log-uniform algorithm. To fix the interval, set the value to `interval * 1`.
|
|
156
|
+
* `errorCodes` **{string[]}**
|
|
157
|
+
`Default: ['ECONNREFUSED', 'ECONNRESET', 'EHOSTDOWN', 'EHOSTUNREACH', 'ENETDOWN', 'ENETUNREACH', 'ENOTFOUND', 'ERR_HTTP2_STREAM_ERROR']`
|
|
158
|
+
The list of error codes to retry on.
|
|
159
|
+
* `interval` **{number}** `Default: 1e3` The initial retry interval.
|
|
160
|
+
* `maxRetryAfter` **{number}** `Default: 3e5` The maximum `retry-after` limit in milliseconds.
|
|
161
|
+
* `retryAfter` **{boolean}** `Default: true` Controls `retry-after` header receptiveness.
|
|
162
|
+
* `statusCodes` **{number[]}** `Default: [429, 500, 502, 503, 504]` The list of status codes to retry on.
|
|
163
|
+
* `stripTrailingSlash` **{boolean}** `Default: false` Controls whether to strip trailing slash at the end of the URL.
|
|
164
|
+
* `thenable` **{boolean}** `Default: false` Controls the promise resolutions.
|
|
165
|
+
* `timeout` **{number}** `Default: 3e5` The number of milliseconds a request can take before termination.
|
|
166
|
+
* `trimTrailingSlashes` **{boolean}** `Default: false` Controls whether to trim trailing slashes within the URL.
|
|
167
|
+
* **Returns:** Promise that resolves to
|
|
168
|
+
extended [http.IncomingMessage](https://nodejs.org/api/http.html#class-httpincomingmessage)
|
|
169
|
+
or [http2.ClientHttp2Stream](https://nodejs.org/api/http2.html#class-clienthttp2stream) which are respectively
|
|
170
|
+
readable and duplex streams.
|
|
171
|
+
* if `digest: true` & `parse: true`
|
|
172
|
+
* `body` **{string | Array | Buffer | Object}** The body based on its content type.
|
|
173
|
+
* if `digest: false`
|
|
174
|
+
* `arrayBuffer` **{AsyncFunction}** Reads the response and returns **ArrayBuffer**.
|
|
175
|
+
* `blob` **{AsyncFunction}** Reads the response and returns **Blob**.
|
|
176
|
+
* `body` **{AsyncFunction}** Reads the response and returns **Buffer** if `parse: false`.
|
|
177
|
+
* `bytes` **{AsyncFunction}** Reads the response and returns **Uint8Array**.
|
|
178
|
+
* `json` **{AsyncFunction}** Reads the response and returns **Object**.
|
|
179
|
+
* `text` **{AsyncFunction}** Reads the response and returns **String**.
|
|
180
|
+
* `bodyUsed` **{boolean}** Indicates whether the response was read or not.
|
|
181
|
+
* `cookies` **{undefined | Cookies}** The cookies sent and received with the response.
|
|
182
|
+
* `headers` **{Object}** The headers received with the response.
|
|
183
|
+
* `httpVersion` **{string}** Indicates a protocol version negotiated with the server.
|
|
184
|
+
* `ok` **{boolean}** Indicates if the response was successful (statusCode: **200-299**).
|
|
185
|
+
* `redirected` **{boolean}** Indicates if the response is the result of a redirect.
|
|
186
|
+
* `statusCode` **{number}** Indicates the status code of the response.
|
|
187
|
+
* `trailers` **{undefined | Object}** The trailer headers received with the response.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
#### `rekwest.defaults`
|
|
192
|
+
|
|
193
|
+
The object to fulfill with default [options](#rekwesturl-options).
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
#### `rekwest.extend(options)`
|
|
198
|
+
|
|
199
|
+
The method to extend default [options](#rekwesturl-options) per instance.
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
import rekwest, { constants } from 'rekwest';
|
|
203
|
+
|
|
204
|
+
const {
|
|
205
|
+
HTTP_STATUS_OK,
|
|
206
|
+
} = constants;
|
|
207
|
+
|
|
208
|
+
const rk = rekwest.extend({
|
|
209
|
+
baseURL: 'https://somewhe.re',
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const params = {
|
|
213
|
+
id: '[uid]',
|
|
214
|
+
signature: '[code]',
|
|
215
|
+
variant: '[any]',
|
|
216
|
+
};
|
|
217
|
+
const signal = AbortSignal.timeout(3e4);
|
|
218
|
+
const url = '/somewhat/endpoint';
|
|
219
|
+
|
|
220
|
+
const res = await rk(url, {
|
|
221
|
+
params,
|
|
222
|
+
signal,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
console.assert(res.statusCode === HTTP_STATUS_OK);
|
|
226
|
+
console.info(res.headers);
|
|
227
|
+
console.log(res.body);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
#### `rekwest.stream(url[, options])`
|
|
233
|
+
|
|
234
|
+
The method with limited functionality to use with streams and/or pipes.
|
|
235
|
+
|
|
236
|
+
* No automata (redirects & retries).
|
|
237
|
+
* Pass `h2: true` in options to use HTTP/2 protocol.
|
|
238
|
+
* Use `ackn({ url: URL })` method in advance to check the available protocols.
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
import fs from 'node:fs';
|
|
242
|
+
import { pipeline } from 'node:stream/promises';
|
|
243
|
+
import rekwest, {
|
|
244
|
+
ackn,
|
|
245
|
+
constants,
|
|
246
|
+
} from 'rekwest';
|
|
247
|
+
|
|
248
|
+
const {
|
|
249
|
+
HTTP2_METHOD_POST,
|
|
250
|
+
} = constants;
|
|
251
|
+
|
|
252
|
+
const url = new URL('https://somewhe.re/somewhat/endpoint');
|
|
253
|
+
const options = await ackn({ url });
|
|
254
|
+
|
|
255
|
+
await pipeline(
|
|
256
|
+
fs.createReadStream('/path/to/read/inlet.xyz'),
|
|
257
|
+
rekwest.stream(url, { ...options, method: HTTP2_METHOD_POST }),
|
|
258
|
+
fs.createWriteStream('/path/to/write/outlet.xyz'),
|
|
259
|
+
);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
For more details, please check tests (coverage: **>97%**) in the repository.
|
package/dist/ackn.cjs
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.ackn = void 0;
|
|
7
7
|
var _nodeTls = require("node:tls");
|
|
8
|
+
var _errors = require("./errors.cjs");
|
|
8
9
|
const ackn = (options = {}) => new Promise((resolve, reject) => {
|
|
9
10
|
const url = new URL(options.url);
|
|
10
11
|
const socket = (0, _nodeTls.connect)({
|
|
@@ -14,6 +15,14 @@ const ackn = (options = {}) => new Promise((resolve, reject) => {
|
|
|
14
15
|
port: parseInt(url.port, 10) || 443,
|
|
15
16
|
servername: url.hostname
|
|
16
17
|
}, () => {
|
|
18
|
+
const cert = socket.getPeerCertificate();
|
|
19
|
+
if (options.certPins?.length) {
|
|
20
|
+
const fp = cert.fingerprint256;
|
|
21
|
+
if (!options.certPins.includes(fp) && !socket.isSessionReused()) {
|
|
22
|
+
socket.destroy();
|
|
23
|
+
return reject(new _errors.RequestError(`Certificate pins mismatch for ${url.hostname}`));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
17
26
|
socket.off('error', reject);
|
|
18
27
|
socket.off('timeout', reject);
|
|
19
28
|
const {
|
package/dist/config.cjs
CHANGED
package/dist/cookies.cjs
CHANGED
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.splitCookie = exports.maxCookieSize = exports.maxCookieLifetimeCap = exports.isValidCookie = exports.illegalCookieChars = exports.cookieRex = exports.cookiePairRex = exports.Cookies = void 0;
|
|
7
7
|
var _utils = require("./utils.cjs");
|
|
8
8
|
const cookieRex = exports.cookieRex = /^[^=]+=(?:"[^"]*"|[^\p{Control};]*)(?:;\s*(?:[^=]+=(?:"[^"]*"|[^\p{Control};]*)|[^=]+))*$/u;
|
|
9
|
-
const cookiePairRex = exports.cookiePairRex = /[^;\s]+=(?:"[^"]*"|[
|
|
9
|
+
const cookiePairRex = exports.cookiePairRex = /[^;\s]+=(?:"[^"]*"|[^;]*)/g;
|
|
10
10
|
const illegalCookieChars = exports.illegalCookieChars = /\p{Control}/u;
|
|
11
11
|
const isValidCookie = str => str?.constructor === String && cookieRex.test(str);
|
|
12
12
|
exports.isValidCookie = isValidCookie;
|
package/dist/transfer.cjs
CHANGED
|
@@ -26,11 +26,7 @@ const transfer = async options => {
|
|
|
26
26
|
throw new _errors.RequestError(`Maximum redirect reached at: ${url.href}`);
|
|
27
27
|
}
|
|
28
28
|
if (url.protocol === 'https:') {
|
|
29
|
-
options =
|
|
30
|
-
...options,
|
|
31
|
-
createConnection: null,
|
|
32
|
-
protocol: url.protocol
|
|
33
|
-
};
|
|
29
|
+
options = await (0, _ackn.ackn)(options);
|
|
34
30
|
} else if (Reflect.has(options, 'alpnProtocol')) {
|
|
35
31
|
for (const it of ['alpnProtocol', 'createConnection', 'h2', 'protocol']) {
|
|
36
32
|
Reflect.deleteProperty(options, it);
|