rekwest 5.0.2 → 5.0.3

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/src/preflight.mjs CHANGED
@@ -1,87 +1,87 @@
1
- import http2 from 'node:http2';
2
- import { requestCredentials } from './constants.mjs';
3
- import { Cookies } from './cookies.mjs';
4
- import {
5
- APPLICATION_JSON,
6
- TEXT_PLAIN,
7
- WILDCARD,
8
- } from './mediatypes.mjs';
9
-
10
- const {
11
- HTTP2_HEADER_ACCEPT,
12
- HTTP2_HEADER_ACCEPT_ENCODING,
13
- HTTP2_HEADER_AUTHORITY,
14
- HTTP2_HEADER_AUTHORIZATION,
15
- HTTP2_HEADER_COOKIE,
16
- HTTP2_HEADER_METHOD,
17
- HTTP2_HEADER_PATH,
18
- HTTP2_HEADER_SCHEME,
19
- HTTP2_METHOD_GET,
20
- HTTP2_METHOD_HEAD,
21
- } = http2.constants;
22
-
23
- export const preflight = (options) => {
24
- const { cookies, credentials, h2, headers, method, url } = options;
25
-
26
- if (h2) {
27
- options.endStream = [
28
- HTTP2_METHOD_GET,
29
- HTTP2_METHOD_HEAD,
30
- ].includes(method);
31
- }
32
-
33
- if (cookies !== false && credentials !== requestCredentials.omit) {
34
- let cookie = Cookies.jar.has(url.origin);
35
-
36
- if (cookies === Object(cookies) && [
37
- requestCredentials.include,
38
- requestCredentials.sameOrigin,
39
- ].includes(credentials)) {
40
- if (cookie) {
41
- cookie = new Cookies(cookies, options);
42
-
43
- Cookies.jar.get(url.origin).forEach((val, key) => {
44
- if (!cookie.has(key)) {
45
- cookie.set(key, val);
46
- }
47
- });
48
- Cookies.jar.set(url.origin, cookie);
49
- } else {
50
- cookie = new Cookies(cookies, options);
51
- Cookies.jar.set(url.origin, cookie);
52
- }
53
- } else {
54
- cookie &&= Cookies.jar.get(url.origin);
55
- }
56
-
57
- options.headers = {
58
- ...cookie && { [HTTP2_HEADER_COOKIE]: cookie },
59
- ...headers,
60
- };
61
- }
62
-
63
- if (credentials === requestCredentials.omit) {
64
- options.cookies = false;
65
- Object.keys(options.headers ?? {})
66
- .filter((it) => new RegExp(`^(${
67
- HTTP2_HEADER_AUTHORIZATION }|${ HTTP2_HEADER_COOKIE
68
- })$`, 'i').test(it))
69
- .forEach((it) => Reflect.deleteProperty(options.headers, it));
70
- url.password = url.username = '';
71
- }
72
-
73
- options.headers = {
74
- [HTTP2_HEADER_ACCEPT]: `${ APPLICATION_JSON }, ${ TEXT_PLAIN }, ${ WILDCARD }`,
75
- [HTTP2_HEADER_ACCEPT_ENCODING]: 'br, deflate, deflate-raw, gzip, identity',
76
- ...Object.entries(options.headers ?? {})
77
- .reduce((acc, [key, val]) => (acc[key.toLowerCase()] = val, acc), {}),
78
- ...h2 && {
79
- [HTTP2_HEADER_AUTHORITY]: url.host,
80
- [HTTP2_HEADER_METHOD]: method,
81
- [HTTP2_HEADER_PATH]: `${ url.pathname }${ url.search }`,
82
- [HTTP2_HEADER_SCHEME]: url.protocol.replace(/\p{Punctuation}/gu, ''),
83
- },
84
- };
85
-
86
- return options;
87
- };
1
+ import http2 from 'node:http2';
2
+ import { requestCredentials } from './constants.mjs';
3
+ import { Cookies } from './cookies.mjs';
4
+ import {
5
+ APPLICATION_JSON,
6
+ TEXT_PLAIN,
7
+ WILDCARD,
8
+ } from './mediatypes.mjs';
9
+
10
+ const {
11
+ HTTP2_HEADER_ACCEPT,
12
+ HTTP2_HEADER_ACCEPT_ENCODING,
13
+ HTTP2_HEADER_AUTHORITY,
14
+ HTTP2_HEADER_AUTHORIZATION,
15
+ HTTP2_HEADER_COOKIE,
16
+ HTTP2_HEADER_METHOD,
17
+ HTTP2_HEADER_PATH,
18
+ HTTP2_HEADER_SCHEME,
19
+ HTTP2_METHOD_GET,
20
+ HTTP2_METHOD_HEAD,
21
+ } = http2.constants;
22
+
23
+ export const preflight = (options) => {
24
+ const { cookies, credentials, h2, headers, method, url } = options;
25
+
26
+ if (h2) {
27
+ options.endStream = [
28
+ HTTP2_METHOD_GET,
29
+ HTTP2_METHOD_HEAD,
30
+ ].includes(method);
31
+ }
32
+
33
+ if (cookies !== false && credentials !== requestCredentials.omit) {
34
+ let cookie = Cookies.jar.has(url.origin);
35
+
36
+ if (cookies === Object(cookies) && [
37
+ requestCredentials.include,
38
+ requestCredentials.sameOrigin,
39
+ ].includes(credentials)) {
40
+ if (cookie) {
41
+ cookie = new Cookies(cookies, options);
42
+
43
+ Cookies.jar.get(url.origin).forEach((val, key) => {
44
+ if (!cookie.has(key)) {
45
+ cookie.set(key, val);
46
+ }
47
+ });
48
+ Cookies.jar.set(url.origin, cookie);
49
+ } else {
50
+ cookie = new Cookies(cookies, options);
51
+ Cookies.jar.set(url.origin, cookie);
52
+ }
53
+ } else {
54
+ cookie &&= Cookies.jar.get(url.origin);
55
+ }
56
+
57
+ options.headers = {
58
+ ...cookie && { [HTTP2_HEADER_COOKIE]: cookie },
59
+ ...headers,
60
+ };
61
+ }
62
+
63
+ if (credentials === requestCredentials.omit) {
64
+ options.cookies = false;
65
+ for (const it of Object.keys(options.headers ?? {})
66
+ .filter((val) => new RegExp(`^(${
67
+ HTTP2_HEADER_AUTHORIZATION }|${ HTTP2_HEADER_COOKIE
68
+ })$`, 'i').test(val))) { Reflect.deleteProperty(options.headers, it); }
69
+
70
+ url.password = url.username = '';
71
+ }
72
+
73
+ options.headers = {
74
+ [HTTP2_HEADER_ACCEPT]: `${ APPLICATION_JSON }, ${ TEXT_PLAIN }, ${ WILDCARD }`,
75
+ [HTTP2_HEADER_ACCEPT_ENCODING]: 'br, deflate, deflate-raw, gzip, identity',
76
+ ...Object.entries(options.headers ?? {})
77
+ .reduce((acc, [key, val]) => (acc[key.toLowerCase()] = val, acc), {}),
78
+ ...h2 && {
79
+ [HTTP2_HEADER_AUTHORITY]: url.host,
80
+ [HTTP2_HEADER_METHOD]: method,
81
+ [HTTP2_HEADER_PATH]: `${ url.pathname }${ url.search }`,
82
+ [HTTP2_HEADER_SCHEME]: url.protocol.replace(/\p{Punctuation}/gu, ''),
83
+ },
84
+ };
85
+
86
+ return options;
87
+ };
package/src/transfer.mjs CHANGED
@@ -1,114 +1,114 @@
1
- import http from 'node:http';
2
- import http2 from 'node:http2';
3
- import https from 'node:https';
4
- import { setTimeout as setTimeoutPromise } from 'node:timers/promises';
5
- import { ackn } from './ackn.mjs';
6
- import { RequestError } from './errors.mjs';
7
- import { postflight } from './postflight.mjs';
8
- import { preflight } from './preflight.mjs';
9
- import { transform } from './transform.mjs';
10
- import {
11
- affix,
12
- dispatch,
13
- maxRetryAfterError,
14
- } from './utils.mjs';
15
-
16
- const {
17
- HTTP2_HEADER_RETRY_AFTER,
18
- } = http2.constants;
19
-
20
- export const transfer = async (options, overact) => {
21
- const { digest, redirected, thenable, url } = options;
22
-
23
- if (options.follow === 0) {
24
- throw new RequestError(`Maximum redirect reached at: ${ url.href }`);
25
- }
26
-
27
- if (url.protocol === 'https:') {
28
- options = !options.h2 ? await ackn(options) : {
29
- ...options,
30
- createConnection: null,
31
- protocol: url.protocol,
32
- };
33
- } else if (Reflect.has(options, 'alpnProtocol')) {
34
- [
35
- 'alpnProtocol',
36
- 'createConnection',
37
- 'h2',
38
- 'protocol',
39
- ].forEach((it) => Reflect.deleteProperty(options, it));
40
- }
41
-
42
- try {
43
- options = await transform(preflight(options));
44
- } catch (ex) {
45
- options.createConnection?.().destroy();
46
- throw ex;
47
- }
48
-
49
- const promise = new Promise((resolve, reject) => {
50
- let client, req;
51
-
52
- if (options.h2) {
53
- client = http2.connect(url.origin, options);
54
- req = client.request(options.headers, options);
55
- } else {
56
- const { request } = url.protocol === 'http:' ? http : https;
57
-
58
- req = request(url, options);
59
- }
60
-
61
- affix(client, req, options);
62
-
63
- req.once('error', reject);
64
- req.once('frameError', reject);
65
- req.once('goaway', reject);
66
- req.once('response', (res) => postflight(req, res, options, {
67
- reject,
68
- resolve,
69
- }));
70
-
71
- dispatch(options, req);
72
- });
73
-
74
- try {
75
- const res = await promise;
76
-
77
- if (digest && !redirected) {
78
- res.body = await res.body();
79
- }
80
-
81
- return res;
82
- } catch (ex) {
83
- const { maxRetryAfter, retry } = options;
84
-
85
- if (retry?.attempts && retry?.statusCodes.includes(ex.statusCode)) {
86
- let { interval } = retry;
87
-
88
- if (retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
89
- interval = ex.headers[HTTP2_HEADER_RETRY_AFTER];
90
- interval = Number(interval) * 1000 || new Date(interval) - Date.now();
91
- if (interval > maxRetryAfter) {
92
- throw maxRetryAfterError(interval, { cause: ex });
93
- }
94
- } else {
95
- interval = new Function('interval', `return Math.ceil(${ retry.backoffStrategy });`)(interval);
96
- }
97
-
98
- retry.attempts--;
99
- retry.interval = interval;
100
-
101
- return setTimeoutPromise(interval).then(() => overact(url, options));
102
- }
103
-
104
- if (digest && !redirected && ex.body) {
105
- ex.body = await ex.body();
106
- }
107
-
108
- if (!thenable) {
109
- throw ex;
110
- } else {
111
- return ex;
112
- }
113
- }
114
- };
1
+ import http from 'node:http';
2
+ import http2 from 'node:http2';
3
+ import https from 'node:https';
4
+ import { setTimeout as setTimeoutPromise } from 'node:timers/promises';
5
+ import { ackn } from './ackn.mjs';
6
+ import { RequestError } from './errors.mjs';
7
+ import { postflight } from './postflight.mjs';
8
+ import { preflight } from './preflight.mjs';
9
+ import { transform } from './transform.mjs';
10
+ import {
11
+ affix,
12
+ dispatch,
13
+ maxRetryAfterError,
14
+ } from './utils.mjs';
15
+
16
+ const {
17
+ HTTP2_HEADER_RETRY_AFTER,
18
+ } = http2.constants;
19
+
20
+ export const transfer = async (options, overact) => {
21
+ const { digest, redirected, thenable, url } = options;
22
+
23
+ if (options.follow === 0) {
24
+ throw new RequestError(`Maximum redirect reached at: ${ url.href }`);
25
+ }
26
+
27
+ if (url.protocol === 'https:') {
28
+ options = !options.h2 ? await ackn(options) : {
29
+ ...options,
30
+ createConnection: null,
31
+ protocol: url.protocol,
32
+ };
33
+ } else if (Reflect.has(options, 'alpnProtocol')) {
34
+ for (const it of [
35
+ 'alpnProtocol',
36
+ 'createConnection',
37
+ 'h2',
38
+ 'protocol',
39
+ ]) { Reflect.deleteProperty(options, it); }
40
+ }
41
+
42
+ try {
43
+ options = await transform(preflight(options));
44
+ } catch (ex) {
45
+ options.createConnection?.().destroy();
46
+ throw ex;
47
+ }
48
+
49
+ const promise = new Promise((resolve, reject) => {
50
+ let client, req;
51
+
52
+ if (options.h2) {
53
+ client = http2.connect(url.origin, options);
54
+ req = client.request(options.headers, options);
55
+ } else {
56
+ const { request } = url.protocol === 'http:' ? http : https;
57
+
58
+ req = request(url, options);
59
+ }
60
+
61
+ affix(client, req, options);
62
+
63
+ req.once('error', reject);
64
+ req.once('frameError', reject);
65
+ req.once('goaway', reject);
66
+ req.once('response', (res) => postflight(req, res, options, {
67
+ reject,
68
+ resolve,
69
+ }));
70
+
71
+ dispatch(options, req);
72
+ });
73
+
74
+ try {
75
+ const res = await promise;
76
+
77
+ if (digest && !redirected) {
78
+ res.body = await res.body();
79
+ }
80
+
81
+ return res;
82
+ } catch (ex) {
83
+ const { maxRetryAfter, retry } = options;
84
+
85
+ if (retry?.attempts && retry?.statusCodes.includes(ex.statusCode)) {
86
+ let { interval } = retry;
87
+
88
+ if (retry.retryAfter && ex.headers[HTTP2_HEADER_RETRY_AFTER]) {
89
+ interval = ex.headers[HTTP2_HEADER_RETRY_AFTER];
90
+ interval = Number(interval) * 1000 || new Date(interval) - Date.now();
91
+ if (interval > maxRetryAfter) {
92
+ throw maxRetryAfterError(interval, { cause: ex });
93
+ }
94
+ } else {
95
+ interval = new Function('interval', `return Math.ceil(${ retry.backoffStrategy });`)(interval);
96
+ }
97
+
98
+ retry.attempts--;
99
+ retry.interval = interval;
100
+
101
+ return setTimeoutPromise(interval).then(() => overact(url, options));
102
+ }
103
+
104
+ if (digest && !redirected && ex.body) {
105
+ ex.body = await ex.body();
106
+ }
107
+
108
+ if (!thenable) {
109
+ throw ex;
110
+ } else {
111
+ return ex;
112
+ }
113
+ }
114
+ };