@openclaw/msteams 2026.6.11 → 2026.6.33
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/dist/api.js +1 -1
- package/dist/{channel-D6Se2irO.js → channel-De7IU_NC.js} +2 -2
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-DIplgUVW.js → channel.runtime-DNzD6A6c.js} +2 -2
- package/dist/{probe-Cl6_-FSx.js → probe-BrPEeWJe.js} +19 -8
- package/dist/{src-DgSUjtxR.js → src-_fXCY2NI.js} +2 -2
- package/node_modules/axios/CHANGELOG.md +165 -1
- package/node_modules/axios/README.md +310 -247
- package/node_modules/axios/dist/axios.js +533 -197
- package/node_modules/axios/dist/axios.min.js +3 -3
- package/node_modules/axios/dist/axios.min.js.map +1 -1
- package/node_modules/axios/dist/browser/axios.cjs +564 -161
- package/node_modules/axios/dist/esm/axios.js +564 -161
- package/node_modules/axios/dist/esm/axios.min.js +2 -2
- package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
- package/node_modules/axios/dist/node/axios.cjs +839 -281
- package/node_modules/axios/index.d.cts +11 -4
- package/node_modules/axios/index.d.ts +7 -2
- package/node_modules/axios/lib/adapters/fetch.js +196 -37
- package/node_modules/axios/lib/adapters/http.js +328 -185
- package/node_modules/axios/lib/adapters/xhr.js +2 -1
- package/node_modules/axios/lib/core/Axios.js +4 -2
- package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
- package/node_modules/axios/lib/core/buildFullPath.js +29 -1
- package/node_modules/axios/lib/core/mergeConfig.js +34 -0
- package/node_modules/axios/lib/defaults/transitional.js +2 -0
- package/node_modules/axios/lib/env/data.js +1 -1
- package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
- package/node_modules/axios/lib/helpers/buildURL.js +6 -4
- package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
- package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
- package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
- package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
- package/node_modules/axios/lib/helpers/fromDataURI.js +18 -5
- package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
- package/node_modules/axios/lib/helpers/resolveConfig.js +17 -9
- package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
- package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
- package/node_modules/axios/lib/helpers/toFormData.js +41 -11
- package/node_modules/axios/lib/utils.js +105 -19
- package/node_modules/axios/node_modules/agent-base/README.md +145 -0
- package/node_modules/axios/node_modules/agent-base/dist/src/index.d.ts +78 -0
- package/node_modules/axios/node_modules/agent-base/dist/src/index.js +203 -0
- package/node_modules/axios/node_modules/agent-base/dist/src/index.js.map +1 -0
- package/node_modules/axios/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
- package/node_modules/axios/node_modules/agent-base/dist/src/promisify.js +18 -0
- package/node_modules/axios/node_modules/agent-base/dist/src/promisify.js.map +1 -0
- package/node_modules/axios/node_modules/agent-base/package.json +64 -0
- package/node_modules/axios/node_modules/agent-base/src/index.ts +345 -0
- package/node_modules/axios/node_modules/agent-base/src/promisify.ts +33 -0
- package/node_modules/axios/node_modules/https-proxy-agent/README.md +137 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/agent.js +177 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/index.js +14 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/index.js.map +1 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
- package/node_modules/axios/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
- package/node_modules/axios/node_modules/https-proxy-agent/package.json +56 -0
- package/node_modules/axios/package.json +31 -13
- package/npm-shrinkwrap.json +32 -6
- package/package.json +4 -4
- package/node_modules/axios/dist/axios.js.map +0 -1
- package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
- package/node_modules/axios/dist/esm/axios.js.map +0 -1
- package/node_modules/axios/dist/node/axios.cjs.map +0 -1
|
@@ -35,7 +35,7 @@ const encodeUTF8 = (str) =>
|
|
|
35
35
|
String.fromCharCode(parseInt(hex, 16))
|
|
36
36
|
);
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
function resolveConfig(config) {
|
|
39
39
|
const newConfig = mergeConfig({}, config);
|
|
40
40
|
|
|
41
41
|
// Read only own properties to prevent prototype pollution gadgets
|
|
@@ -55,23 +55,29 @@ export default (config) => {
|
|
|
55
55
|
newConfig.headers = headers = AxiosHeaders.from(headers);
|
|
56
56
|
|
|
57
57
|
newConfig.url = buildURL(
|
|
58
|
-
buildFullPath(baseURL, url, allowAbsoluteUrls),
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
buildFullPath(baseURL, url, allowAbsoluteUrls, newConfig),
|
|
59
|
+
own('params'),
|
|
60
|
+
own('paramsSerializer')
|
|
61
61
|
);
|
|
62
62
|
|
|
63
63
|
// HTTP basic authentication
|
|
64
64
|
if (auth) {
|
|
65
|
+
const username = utils.getSafeProp(auth, 'username') || '';
|
|
66
|
+
const password = utils.getSafeProp(auth, 'password') || '';
|
|
67
|
+
|
|
65
68
|
headers.set(
|
|
66
69
|
'Authorization',
|
|
67
|
-
'Basic ' +
|
|
68
|
-
btoa((auth.username || '') + ':' + (auth.password ? encodeUTF8(auth.password) : ''))
|
|
70
|
+
'Basic ' + btoa(username + ':' + (password ? encodeUTF8(password) : ''))
|
|
69
71
|
);
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
if (utils.isFormData(data)) {
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
+
if (
|
|
76
|
+
platform.hasStandardBrowserEnv ||
|
|
77
|
+
platform.hasStandardBrowserWebWorkerEnv ||
|
|
78
|
+
utils.isReactNative(data)
|
|
79
|
+
) {
|
|
80
|
+
headers.setContentType(undefined); // browser/web worker/RN handles it
|
|
75
81
|
} else if (utils.isFunction(data.getHeaders)) {
|
|
76
82
|
// Node.js FormData (like form-data package)
|
|
77
83
|
setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
|
|
@@ -103,4 +109,6 @@ export default (config) => {
|
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
return newConfig;
|
|
106
|
-
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default resolveConfig;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import utils from '../utils.js';
|
|
4
|
+
|
|
5
|
+
function trimSPorHTAB(str) {
|
|
6
|
+
let start = 0;
|
|
7
|
+
let end = str.length;
|
|
8
|
+
|
|
9
|
+
while (start < end) {
|
|
10
|
+
const code = str.charCodeAt(start);
|
|
11
|
+
|
|
12
|
+
if (code !== 0x09 && code !== 0x20) {
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
start += 1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
while (end > start) {
|
|
20
|
+
const code = str.charCodeAt(end - 1);
|
|
21
|
+
|
|
22
|
+
if (code !== 0x09 && code !== 0x20) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
end -= 1;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return start === 0 && end === str.length ? str : str.slice(start, end);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// The control-code ranges are intentional: header sanitization strips C0/DEL bytes.
|
|
33
|
+
// eslint-disable-next-line no-control-regex
|
|
34
|
+
const INVALID_UNICODE_HEADER_VALUE_CHARS = new RegExp('[\\u0000-\\u0008\\u000a-\\u001f\\u007f]+', 'g');
|
|
35
|
+
// eslint-disable-next-line no-control-regex
|
|
36
|
+
const INVALID_BYTE_STRING_HEADER_VALUE_CHARS = new RegExp('[^\\u0009\\u0020-\\u007e\\u0080-\\u00ff]+', 'g');
|
|
37
|
+
|
|
38
|
+
function sanitizeValue(value, invalidChars) {
|
|
39
|
+
if (utils.isArray(value)) {
|
|
40
|
+
return value.map((item) => sanitizeValue(item, invalidChars));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return trimSPorHTAB(String(value).replace(invalidChars, ''));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const sanitizeHeaderValue = (value) =>
|
|
47
|
+
sanitizeValue(value, INVALID_UNICODE_HEADER_VALUE_CHARS);
|
|
48
|
+
|
|
49
|
+
export const sanitizeByteStringHeaderValue = (value) =>
|
|
50
|
+
sanitizeValue(value, INVALID_BYTE_STRING_HEADER_VALUE_CHARS);
|
|
51
|
+
|
|
52
|
+
export function toByteStringHeaderObject(headers) {
|
|
53
|
+
const byteStringHeaders = Object.create(null);
|
|
54
|
+
|
|
55
|
+
utils.forEach(headers.toJSON(), (value, header) => {
|
|
56
|
+
byteStringHeaders[header] = sanitizeByteStringHeaderValue(value);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return byteStringHeaders;
|
|
60
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const LOOPBACK_HOSTNAMES = new Set(['localhost']);
|
|
1
|
+
const LOOPBACK_HOSTNAMES = new Set(['localhost', '0.0.0.0']);
|
|
2
2
|
|
|
3
3
|
const isIPv4Loopback = (host) => {
|
|
4
4
|
const parts = host.split('.');
|
|
@@ -7,6 +7,37 @@ const isIPv4Loopback = (host) => {
|
|
|
7
7
|
return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
+
const isIPv6ZeroGroup = (group) => /^0{1,4}$/.test(group);
|
|
11
|
+
|
|
12
|
+
// The unspecified address (IPv4 0.0.0.0 / IPv6 ::) resolves to the local host
|
|
13
|
+
// for outbound connections, so treat it as loopback-equivalent for NO_PROXY
|
|
14
|
+
// matching. 0.0.0.0 is covered by LOOPBACK_HOSTNAMES; this handles compressed
|
|
15
|
+
// and full IPv6 all-zero forms so both families bypass symmetrically.
|
|
16
|
+
const isIPv6Unspecified = (host) => {
|
|
17
|
+
if (host === '::') return true;
|
|
18
|
+
|
|
19
|
+
const compressionIndex = host.indexOf('::');
|
|
20
|
+
|
|
21
|
+
if (compressionIndex !== -1) {
|
|
22
|
+
if (compressionIndex !== host.lastIndexOf('::')) return false;
|
|
23
|
+
|
|
24
|
+
const left = host.slice(0, compressionIndex);
|
|
25
|
+
const right = host.slice(compressionIndex + 2);
|
|
26
|
+
const leftGroups = left ? left.split(':') : [];
|
|
27
|
+
const rightGroups = right ? right.split(':') : [];
|
|
28
|
+
const explicitGroups = leftGroups.length + rightGroups.length;
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
explicitGroups < 8 &&
|
|
32
|
+
leftGroups.every(isIPv6ZeroGroup) &&
|
|
33
|
+
rightGroups.every(isIPv6ZeroGroup)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const groups = host.split(':');
|
|
38
|
+
return groups.length === 8 && groups.every(isIPv6ZeroGroup);
|
|
39
|
+
};
|
|
40
|
+
|
|
10
41
|
const isIPv6Loopback = (host) => {
|
|
11
42
|
// Collapse all-zero groups: any form of ::1 / 0:0:...:0:1
|
|
12
43
|
// First, strip any leading "::" by normalising with Set lookup of common forms,
|
|
@@ -42,6 +73,7 @@ const isLoopback = (host) => {
|
|
|
42
73
|
if (!host) return false;
|
|
43
74
|
if (LOOPBACK_HOSTNAMES.has(host)) return true;
|
|
44
75
|
if (isIPv4Loopback(host)) return true;
|
|
76
|
+
if (isIPv6Unspecified(host)) return true;
|
|
45
77
|
return isIPv6Loopback(host);
|
|
46
78
|
};
|
|
47
79
|
|
|
@@ -5,6 +5,10 @@ import AxiosError from '../core/AxiosError.js';
|
|
|
5
5
|
// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored
|
|
6
6
|
import PlatformFormData from '../platform/node/classes/FormData.js';
|
|
7
7
|
|
|
8
|
+
// Default nesting limit shared with the inverse transform (formDataToJSON) so
|
|
9
|
+
// the FormData <-> JSON round-trip stays symmetric.
|
|
10
|
+
export const DEFAULT_FORM_DATA_MAX_DEPTH = 100;
|
|
11
|
+
|
|
8
12
|
/**
|
|
9
13
|
* Determines if the given thing is a array or js object.
|
|
10
14
|
*
|
|
@@ -115,8 +119,9 @@ function toFormData(obj, formData, options) {
|
|
|
115
119
|
const dots = options.dots;
|
|
116
120
|
const indexes = options.indexes;
|
|
117
121
|
const _Blob = options.Blob || (typeof Blob !== 'undefined' && Blob);
|
|
118
|
-
const maxDepth = options.maxDepth === undefined ?
|
|
122
|
+
const maxDepth = options.maxDepth === undefined ? DEFAULT_FORM_DATA_MAX_DEPTH : options.maxDepth;
|
|
119
123
|
const useBlob = _Blob && utils.isSpecCompliantForm(formData);
|
|
124
|
+
const stack = [];
|
|
120
125
|
|
|
121
126
|
if (!utils.isFunction(visitor)) {
|
|
122
127
|
throw new TypeError('visitor must be a function');
|
|
@@ -144,6 +149,38 @@ function toFormData(obj, formData, options) {
|
|
|
144
149
|
return value;
|
|
145
150
|
}
|
|
146
151
|
|
|
152
|
+
function throwIfMaxDepthExceeded(depth) {
|
|
153
|
+
if (depth > maxDepth) {
|
|
154
|
+
throw new AxiosError(
|
|
155
|
+
'Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth,
|
|
156
|
+
AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function stringifyWithDepthLimit(value, depth) {
|
|
162
|
+
if (maxDepth === Infinity) {
|
|
163
|
+
return JSON.stringify(value);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const ancestors = [];
|
|
167
|
+
|
|
168
|
+
return JSON.stringify(value, function limitDepth(_key, currentValue) {
|
|
169
|
+
if (!utils.isObject(currentValue)) {
|
|
170
|
+
return currentValue;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
while (ancestors.length && ancestors[ancestors.length - 1] !== this) {
|
|
174
|
+
ancestors.pop();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
ancestors.push(currentValue);
|
|
178
|
+
throwIfMaxDepthExceeded(depth + ancestors.length - 1);
|
|
179
|
+
|
|
180
|
+
return currentValue;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
147
184
|
/**
|
|
148
185
|
* Default visitor.
|
|
149
186
|
*
|
|
@@ -167,7 +204,7 @@ function toFormData(obj, formData, options) {
|
|
|
167
204
|
// eslint-disable-next-line no-param-reassign
|
|
168
205
|
key = metaTokens ? key : key.slice(0, -2);
|
|
169
206
|
// eslint-disable-next-line no-param-reassign
|
|
170
|
-
value =
|
|
207
|
+
value = stringifyWithDepthLimit(value, 1);
|
|
171
208
|
} else if (
|
|
172
209
|
(utils.isArray(value) && isFlatArray(value)) ||
|
|
173
210
|
((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value)))
|
|
@@ -200,8 +237,6 @@ function toFormData(obj, formData, options) {
|
|
|
200
237
|
return false;
|
|
201
238
|
}
|
|
202
239
|
|
|
203
|
-
const stack = [];
|
|
204
|
-
|
|
205
240
|
const exposedHelpers = Object.assign(predicates, {
|
|
206
241
|
defaultVisitor,
|
|
207
242
|
convertValue,
|
|
@@ -211,15 +246,10 @@ function toFormData(obj, formData, options) {
|
|
|
211
246
|
function build(value, path, depth = 0) {
|
|
212
247
|
if (utils.isUndefined(value)) return;
|
|
213
248
|
|
|
214
|
-
|
|
215
|
-
throw new AxiosError(
|
|
216
|
-
'Object is too deeply nested (' + depth + ' levels). Max depth: ' + maxDepth,
|
|
217
|
-
AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED
|
|
218
|
-
);
|
|
219
|
-
}
|
|
249
|
+
throwIfMaxDepthExceeded(depth);
|
|
220
250
|
|
|
221
251
|
if (stack.indexOf(value) !== -1) {
|
|
222
|
-
throw Error('Circular reference detected in ' + path.join('.'));
|
|
252
|
+
throw new Error('Circular reference detected in ' + path.join('.'));
|
|
223
253
|
}
|
|
224
254
|
|
|
225
255
|
stack.push(value);
|
|
@@ -8,6 +8,57 @@ const { toString } = Object.prototype;
|
|
|
8
8
|
const { getPrototypeOf } = Object;
|
|
9
9
|
const { iterator, toStringTag } = Symbol;
|
|
10
10
|
|
|
11
|
+
/* Creating a function that will check if an object has a property. */
|
|
12
|
+
const hasOwnProperty = (
|
|
13
|
+
({ hasOwnProperty }) =>
|
|
14
|
+
(obj, prop) =>
|
|
15
|
+
hasOwnProperty.call(obj, prop)
|
|
16
|
+
)(Object.prototype);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Walk the prototype chain (excluding the shared Object.prototype) looking for
|
|
20
|
+
* an own `prop`. This distinguishes genuine own/inherited members — including
|
|
21
|
+
* class accessors and template prototypes — from members injected via
|
|
22
|
+
* Object.prototype pollution (e.g. `Object.prototype.username = '...'`), which
|
|
23
|
+
* live on Object.prototype itself and are therefore never matched.
|
|
24
|
+
*
|
|
25
|
+
* @param {*} thing The value whose chain to inspect
|
|
26
|
+
* @param {string|symbol} prop The property key to look for
|
|
27
|
+
*
|
|
28
|
+
* @returns {boolean} True when `prop` is owned below Object.prototype
|
|
29
|
+
*/
|
|
30
|
+
const hasOwnInPrototypeChain = (thing, prop) => {
|
|
31
|
+
let obj = thing;
|
|
32
|
+
const seen = [];
|
|
33
|
+
|
|
34
|
+
while (obj != null && obj !== Object.prototype) {
|
|
35
|
+
if (seen.indexOf(obj) !== -1) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
seen.push(obj);
|
|
39
|
+
|
|
40
|
+
if (hasOwnProperty(obj, prop)) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
obj = getPrototypeOf(obj);
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Read `obj[prop]` only when it is safe from Object.prototype pollution. Own
|
|
50
|
+
* properties and members inherited from a non-Object.prototype source (a class
|
|
51
|
+
* instance or template object) are honored; a value reachable only through a
|
|
52
|
+
* polluted Object.prototype is ignored and `undefined` is returned.
|
|
53
|
+
*
|
|
54
|
+
* @param {*} obj The source object
|
|
55
|
+
* @param {string|symbol} prop The property key to read
|
|
56
|
+
*
|
|
57
|
+
* @returns {*} The resolved value, or undefined when unsafe/absent
|
|
58
|
+
*/
|
|
59
|
+
const getSafeProp = (obj, prop) =>
|
|
60
|
+
obj != null && hasOwnInPrototypeChain(obj, prop) ? obj[prop] : undefined;
|
|
61
|
+
|
|
11
62
|
const kindOf = ((cache) => (thing) => {
|
|
12
63
|
const str = toString.call(thing);
|
|
13
64
|
return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
|
|
@@ -133,7 +184,7 @@ const isBoolean = (thing) => thing === true || thing === false;
|
|
|
133
184
|
* @returns {boolean} True if value is a plain Object, otherwise false
|
|
134
185
|
*/
|
|
135
186
|
const isPlainObject = (val) => {
|
|
136
|
-
if (
|
|
187
|
+
if (!isObject(val)) {
|
|
137
188
|
return false;
|
|
138
189
|
}
|
|
139
190
|
|
|
@@ -141,9 +192,12 @@ const isPlainObject = (val) => {
|
|
|
141
192
|
return (
|
|
142
193
|
(prototype === null ||
|
|
143
194
|
prototype === Object.prototype ||
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
195
|
+
getPrototypeOf(prototype) === null) &&
|
|
196
|
+
// Treat any genuine (non-Object.prototype-polluted) Symbol.toStringTag or
|
|
197
|
+
// Symbol.iterator as evidence the value is a tagged/iterable type rather
|
|
198
|
+
// than a plain object, while ignoring keys injected onto Object.prototype.
|
|
199
|
+
!hasOwnInPrototypeChain(val, toStringTag) &&
|
|
200
|
+
!hasOwnInPrototypeChain(val, iterator)
|
|
147
201
|
);
|
|
148
202
|
};
|
|
149
203
|
|
|
@@ -412,7 +466,9 @@ function merge(...objs) {
|
|
|
412
466
|
return;
|
|
413
467
|
}
|
|
414
468
|
|
|
415
|
-
|
|
469
|
+
// findKey lowercases the key, so caseless lookup only applies to strings —
|
|
470
|
+
// symbol keys are identity-matched.
|
|
471
|
+
const targetKey = (caseless && typeof key === 'string' && findKey(result, key)) || key;
|
|
416
472
|
// Read via own-prop only — a bare `result[targetKey]` walks the prototype
|
|
417
473
|
// chain, so a polluted Object.prototype value could surface here and get
|
|
418
474
|
// copied into the merged result.
|
|
@@ -429,7 +485,24 @@ function merge(...objs) {
|
|
|
429
485
|
};
|
|
430
486
|
|
|
431
487
|
for (let i = 0, l = objs.length; i < l; i++) {
|
|
432
|
-
|
|
488
|
+
const source = objs[i];
|
|
489
|
+
if (!source || isBuffer(source)) {
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
forEach(source, assignValue);
|
|
494
|
+
|
|
495
|
+
if (typeof source !== 'object' || isArray(source)) {
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const symbols = Object.getOwnPropertySymbols(source);
|
|
500
|
+
for (let j = 0; j < symbols.length; j++) {
|
|
501
|
+
const symbol = symbols[j];
|
|
502
|
+
if (propertyIsEnumerable.call(source, symbol)) {
|
|
503
|
+
assignValue(source[symbol], symbol);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
433
506
|
}
|
|
434
507
|
return result;
|
|
435
508
|
}
|
|
@@ -651,12 +724,7 @@ const toCamelCase = (str) => {
|
|
|
651
724
|
});
|
|
652
725
|
};
|
|
653
726
|
|
|
654
|
-
|
|
655
|
-
const hasOwnProperty = (
|
|
656
|
-
({ hasOwnProperty }) =>
|
|
657
|
-
(obj, prop) =>
|
|
658
|
-
hasOwnProperty.call(obj, prop)
|
|
659
|
-
)(Object.prototype);
|
|
727
|
+
const { propertyIsEnumerable } = Object.prototype;
|
|
660
728
|
|
|
661
729
|
/**
|
|
662
730
|
* Determine if a value is a RegExp object
|
|
@@ -763,11 +831,11 @@ function isSpecCompliantForm(thing) {
|
|
|
763
831
|
* @returns {Object} The JSON-compatible object.
|
|
764
832
|
*/
|
|
765
833
|
const toJSONObject = (obj) => {
|
|
766
|
-
const
|
|
834
|
+
const visited = new WeakSet();
|
|
767
835
|
|
|
768
|
-
const visit = (source
|
|
836
|
+
const visit = (source) => {
|
|
769
837
|
if (isObject(source)) {
|
|
770
|
-
if (
|
|
838
|
+
if (visited.has(source)) {
|
|
771
839
|
return;
|
|
772
840
|
}
|
|
773
841
|
|
|
@@ -777,15 +845,16 @@ const toJSONObject = (obj) => {
|
|
|
777
845
|
}
|
|
778
846
|
|
|
779
847
|
if (!('toJSON' in source)) {
|
|
780
|
-
|
|
848
|
+
// add-on descent / delete-on-ascent: preserves path semantics, so DAG nodes serialise at every occurrence (see #7230).
|
|
849
|
+
visited.add(source);
|
|
781
850
|
const target = isArray(source) ? [] : {};
|
|
782
851
|
|
|
783
852
|
forEach(source, (value, key) => {
|
|
784
|
-
const reducedValue = visit(value
|
|
853
|
+
const reducedValue = visit(value);
|
|
785
854
|
!isUndefined(reducedValue) && (target[key] = reducedValue);
|
|
786
855
|
});
|
|
787
856
|
|
|
788
|
-
|
|
857
|
+
visited.delete(source);
|
|
789
858
|
|
|
790
859
|
return target;
|
|
791
860
|
}
|
|
@@ -794,7 +863,7 @@ const toJSONObject = (obj) => {
|
|
|
794
863
|
return source;
|
|
795
864
|
};
|
|
796
865
|
|
|
797
|
-
return visit(obj
|
|
866
|
+
return visit(obj);
|
|
798
867
|
};
|
|
799
868
|
|
|
800
869
|
/**
|
|
@@ -868,6 +937,20 @@ const asap =
|
|
|
868
937
|
|
|
869
938
|
const isIterable = (thing) => thing != null && isFunction(thing[iterator]);
|
|
870
939
|
|
|
940
|
+
/**
|
|
941
|
+
* Determine if a value is iterable via an iterator that is NOT sourced solely
|
|
942
|
+
* from a polluted Object.prototype. Use this instead of `isIterable` whenever
|
|
943
|
+
* the iterable comes from untrusted input (e.g. user-supplied header sources),
|
|
944
|
+
* so `Object.prototype[Symbol.iterator] = ...` cannot turn an ordinary object
|
|
945
|
+
* into an attacker-controlled entries iterator.
|
|
946
|
+
*
|
|
947
|
+
* @param {*} thing The value to test
|
|
948
|
+
*
|
|
949
|
+
* @returns {boolean} True if value has a non-polluted iterator
|
|
950
|
+
*/
|
|
951
|
+
const isSafeIterable = (thing) =>
|
|
952
|
+
thing != null && hasOwnInPrototypeChain(thing, iterator) && isIterable(thing);
|
|
953
|
+
|
|
871
954
|
export default {
|
|
872
955
|
isArray,
|
|
873
956
|
isArrayBuffer,
|
|
@@ -912,6 +995,8 @@ export default {
|
|
|
912
995
|
isHTMLForm,
|
|
913
996
|
hasOwnProperty,
|
|
914
997
|
hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection
|
|
998
|
+
hasOwnInPrototypeChain,
|
|
999
|
+
getSafeProp,
|
|
915
1000
|
reduceDescriptors,
|
|
916
1001
|
freezeMethods,
|
|
917
1002
|
toObjectSet,
|
|
@@ -928,4 +1013,5 @@ export default {
|
|
|
928
1013
|
setImmediate: _setImmediate,
|
|
929
1014
|
asap,
|
|
930
1015
|
isIterable,
|
|
1016
|
+
isSafeIterable,
|
|
931
1017
|
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
agent-base
|
|
2
|
+
==========
|
|
3
|
+
### Turn a function into an [`http.Agent`][http.Agent] instance
|
|
4
|
+
[](https://github.com/TooTallNate/node-agent-base/actions?workflow=Node+CI)
|
|
5
|
+
|
|
6
|
+
This module provides an `http.Agent` generator. That is, you pass it an async
|
|
7
|
+
callback function, and it returns a new `http.Agent` instance that will invoke the
|
|
8
|
+
given callback function when sending outbound HTTP requests.
|
|
9
|
+
|
|
10
|
+
#### Some subclasses:
|
|
11
|
+
|
|
12
|
+
Here's some more interesting uses of `agent-base`.
|
|
13
|
+
Send a pull request to list yours!
|
|
14
|
+
|
|
15
|
+
* [`http-proxy-agent`][http-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTP endpoints
|
|
16
|
+
* [`https-proxy-agent`][https-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTPS endpoints
|
|
17
|
+
* [`pac-proxy-agent`][pac-proxy-agent]: A PAC file proxy `http.Agent` implementation for HTTP and HTTPS
|
|
18
|
+
* [`socks-proxy-agent`][socks-proxy-agent]: A SOCKS proxy `http.Agent` implementation for HTTP and HTTPS
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Installation
|
|
22
|
+
------------
|
|
23
|
+
|
|
24
|
+
Install with `npm`:
|
|
25
|
+
|
|
26
|
+
``` bash
|
|
27
|
+
$ npm install agent-base
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
Example
|
|
32
|
+
-------
|
|
33
|
+
|
|
34
|
+
Here's a minimal example that creates a new `net.Socket` connection to the server
|
|
35
|
+
for every HTTP request (i.e. the equivalent of `agent: false` option):
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
var net = require('net');
|
|
39
|
+
var tls = require('tls');
|
|
40
|
+
var url = require('url');
|
|
41
|
+
var http = require('http');
|
|
42
|
+
var agent = require('agent-base');
|
|
43
|
+
|
|
44
|
+
var endpoint = 'http://nodejs.org/api/';
|
|
45
|
+
var parsed = url.parse(endpoint);
|
|
46
|
+
|
|
47
|
+
// This is the important part!
|
|
48
|
+
parsed.agent = agent(function (req, opts) {
|
|
49
|
+
var socket;
|
|
50
|
+
// `secureEndpoint` is true when using the https module
|
|
51
|
+
if (opts.secureEndpoint) {
|
|
52
|
+
socket = tls.connect(opts);
|
|
53
|
+
} else {
|
|
54
|
+
socket = net.connect(opts);
|
|
55
|
+
}
|
|
56
|
+
return socket;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Everything else works just like normal...
|
|
60
|
+
http.get(parsed, function (res) {
|
|
61
|
+
console.log('"response" event!', res.headers);
|
|
62
|
+
res.pipe(process.stdout);
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Returning a Promise or using an `async` function is also supported:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
agent(async function (req, opts) {
|
|
70
|
+
await sleep(1000);
|
|
71
|
+
// etc…
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Return another `http.Agent` instance to "pass through" the responsibility
|
|
76
|
+
for that HTTP request to that agent:
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
agent(function (req, opts) {
|
|
80
|
+
return opts.secureEndpoint ? https.globalAgent : http.globalAgent;
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
API
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Agent(Function callback[, Object options]) → [http.Agent][]
|
|
89
|
+
|
|
90
|
+
Creates a base `http.Agent` that will execute the callback function `callback`
|
|
91
|
+
for every HTTP request that it is used as the `agent` for. The callback function
|
|
92
|
+
is responsible for creating a `stream.Duplex` instance of some kind that will be
|
|
93
|
+
used as the underlying socket in the HTTP request.
|
|
94
|
+
|
|
95
|
+
The `options` object accepts the following properties:
|
|
96
|
+
|
|
97
|
+
* `timeout` - Number - Timeout for the `callback()` function in milliseconds. Defaults to Infinity (optional).
|
|
98
|
+
|
|
99
|
+
The callback function should have the following signature:
|
|
100
|
+
|
|
101
|
+
### callback(http.ClientRequest req, Object options, Function cb) → undefined
|
|
102
|
+
|
|
103
|
+
The ClientRequest `req` can be accessed to read request headers and
|
|
104
|
+
and the path, etc. The `options` object contains the options passed
|
|
105
|
+
to the `http.request()`/`https.request()` function call, and is formatted
|
|
106
|
+
to be directly passed to `net.connect()`/`tls.connect()`, or however
|
|
107
|
+
else you want a Socket to be created. Pass the created socket to
|
|
108
|
+
the callback function `cb` once created, and the HTTP request will
|
|
109
|
+
continue to proceed.
|
|
110
|
+
|
|
111
|
+
If the `https` module is used to invoke the HTTP request, then the
|
|
112
|
+
`secureEndpoint` property on `options` _will be set to `true`_.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
License
|
|
116
|
+
-------
|
|
117
|
+
|
|
118
|
+
(The MIT License)
|
|
119
|
+
|
|
120
|
+
Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>
|
|
121
|
+
|
|
122
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
123
|
+
a copy of this software and associated documentation files (the
|
|
124
|
+
'Software'), to deal in the Software without restriction, including
|
|
125
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
126
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
127
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
128
|
+
the following conditions:
|
|
129
|
+
|
|
130
|
+
The above copyright notice and this permission notice shall be
|
|
131
|
+
included in all copies or substantial portions of the Software.
|
|
132
|
+
|
|
133
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
134
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
135
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
136
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
137
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
138
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
139
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
140
|
+
|
|
141
|
+
[http-proxy-agent]: https://github.com/TooTallNate/node-http-proxy-agent
|
|
142
|
+
[https-proxy-agent]: https://github.com/TooTallNate/node-https-proxy-agent
|
|
143
|
+
[pac-proxy-agent]: https://github.com/TooTallNate/node-pac-proxy-agent
|
|
144
|
+
[socks-proxy-agent]: https://github.com/TooTallNate/node-socks-proxy-agent
|
|
145
|
+
[http.Agent]: https://nodejs.org/api/http.html#http_class_http_agent
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import net from 'net';
|
|
3
|
+
import http from 'http';
|
|
4
|
+
import https from 'https';
|
|
5
|
+
import { Duplex } from 'stream';
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
declare function createAgent(opts?: createAgent.AgentOptions): createAgent.Agent;
|
|
8
|
+
declare function createAgent(callback: createAgent.AgentCallback, opts?: createAgent.AgentOptions): createAgent.Agent;
|
|
9
|
+
declare namespace createAgent {
|
|
10
|
+
interface ClientRequest extends http.ClientRequest {
|
|
11
|
+
_last?: boolean;
|
|
12
|
+
_hadError?: boolean;
|
|
13
|
+
method: string;
|
|
14
|
+
}
|
|
15
|
+
interface AgentRequestOptions {
|
|
16
|
+
host?: string;
|
|
17
|
+
path?: string;
|
|
18
|
+
port: number;
|
|
19
|
+
}
|
|
20
|
+
interface HttpRequestOptions extends AgentRequestOptions, Omit<http.RequestOptions, keyof AgentRequestOptions> {
|
|
21
|
+
secureEndpoint: false;
|
|
22
|
+
}
|
|
23
|
+
interface HttpsRequestOptions extends AgentRequestOptions, Omit<https.RequestOptions, keyof AgentRequestOptions> {
|
|
24
|
+
secureEndpoint: true;
|
|
25
|
+
}
|
|
26
|
+
type RequestOptions = HttpRequestOptions | HttpsRequestOptions;
|
|
27
|
+
type AgentLike = Pick<createAgent.Agent, 'addRequest'> | http.Agent;
|
|
28
|
+
type AgentCallbackReturn = Duplex | AgentLike;
|
|
29
|
+
type AgentCallbackCallback = (err?: Error | null, socket?: createAgent.AgentCallbackReturn) => void;
|
|
30
|
+
type AgentCallbackPromise = (req: createAgent.ClientRequest, opts: createAgent.RequestOptions) => createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>;
|
|
31
|
+
type AgentCallback = typeof Agent.prototype.callback;
|
|
32
|
+
type AgentOptions = {
|
|
33
|
+
timeout?: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Base `http.Agent` implementation.
|
|
37
|
+
* No pooling/keep-alive is implemented by default.
|
|
38
|
+
*
|
|
39
|
+
* @param {Function} callback
|
|
40
|
+
* @api public
|
|
41
|
+
*/
|
|
42
|
+
class Agent extends EventEmitter {
|
|
43
|
+
timeout: number | null;
|
|
44
|
+
maxFreeSockets: number;
|
|
45
|
+
maxTotalSockets: number;
|
|
46
|
+
maxSockets: number;
|
|
47
|
+
sockets: {
|
|
48
|
+
[key: string]: net.Socket[];
|
|
49
|
+
};
|
|
50
|
+
freeSockets: {
|
|
51
|
+
[key: string]: net.Socket[];
|
|
52
|
+
};
|
|
53
|
+
requests: {
|
|
54
|
+
[key: string]: http.IncomingMessage[];
|
|
55
|
+
};
|
|
56
|
+
options: https.AgentOptions;
|
|
57
|
+
private promisifiedCallback?;
|
|
58
|
+
private explicitDefaultPort?;
|
|
59
|
+
private explicitProtocol?;
|
|
60
|
+
constructor(callback?: createAgent.AgentCallback | createAgent.AgentOptions, _opts?: createAgent.AgentOptions);
|
|
61
|
+
get defaultPort(): number;
|
|
62
|
+
set defaultPort(v: number);
|
|
63
|
+
get protocol(): string;
|
|
64
|
+
set protocol(v: string);
|
|
65
|
+
callback(req: createAgent.ClientRequest, opts: createAgent.RequestOptions, fn: createAgent.AgentCallbackCallback): void;
|
|
66
|
+
callback(req: createAgent.ClientRequest, opts: createAgent.RequestOptions): createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>;
|
|
67
|
+
/**
|
|
68
|
+
* Called by node-core's "_http_client.js" module when creating
|
|
69
|
+
* a new HTTP request with this Agent instance.
|
|
70
|
+
*
|
|
71
|
+
* @api public
|
|
72
|
+
*/
|
|
73
|
+
addRequest(req: ClientRequest, _opts: RequestOptions): void;
|
|
74
|
+
freeSocket(socket: net.Socket, opts: AgentOptions): void;
|
|
75
|
+
destroy(): void;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export = createAgent;
|