rezo 1.0.21 → 1.0.23
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/adapters/entries/curl.d.ts +9 -0
- package/dist/adapters/entries/fetch.d.ts +9 -0
- package/dist/adapters/entries/http.d.ts +9 -0
- package/dist/adapters/entries/http2.d.ts +9 -0
- package/dist/adapters/entries/react-native.d.ts +9 -0
- package/dist/adapters/entries/xhr.d.ts +9 -0
- package/dist/adapters/fetch.cjs +59 -6
- package/dist/adapters/fetch.js +59 -6
- package/dist/adapters/http.cjs +120 -8
- package/dist/adapters/http.js +120 -8
- package/dist/adapters/http2.cjs +69 -8
- package/dist/adapters/http2.js +69 -8
- package/dist/adapters/index.cjs +6 -6
- package/dist/cache/index.cjs +13 -13
- package/dist/core/rezo.cjs +48 -2
- package/dist/core/rezo.js +48 -2
- package/dist/crawler.d.ts +9 -0
- package/dist/entries/crawler.cjs +5 -5
- package/dist/errors/rezo-error.cjs +2 -2
- package/dist/errors/rezo-error.js +2 -2
- package/dist/index.cjs +24 -24
- package/dist/index.d.ts +9 -0
- package/dist/platform/browser.d.ts +9 -0
- package/dist/platform/bun.d.ts +9 -0
- package/dist/platform/deno.d.ts +9 -0
- package/dist/platform/node.d.ts +9 -0
- package/dist/platform/react-native.d.ts +9 -0
- package/dist/platform/worker.d.ts +9 -0
- package/dist/plugin/index.cjs +36 -36
- package/dist/proxy/index.cjs +2 -2
- package/dist/queue/index.cjs +8 -8
- package/dist/utils/http-config.cjs +3 -0
- package/dist/utils/http-config.js +3 -0
- package/package.json +1 -1
|
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
|
|
|
1934
1934
|
* ```
|
|
1935
1935
|
*/
|
|
1936
1936
|
beforeRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
|
+
/** Alias for beforeRedirect */
|
|
1938
|
+
onRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
1939
|
/** Character encoding for request body and response data */
|
|
1938
1940
|
encoding?: BufferEncoding;
|
|
1939
1941
|
/**
|
|
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2684
2686
|
* ```
|
|
2685
2687
|
*/
|
|
2686
2688
|
beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2689
|
+
/**
|
|
2690
|
+
* Alias for beforeRedirect - callback invoked when a redirect response is received.
|
|
2691
|
+
* @see beforeRedirect
|
|
2692
|
+
*/
|
|
2693
|
+
onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2687
2694
|
/** Whether to send cookies and authorization headers with cross-origin requests */
|
|
2688
2695
|
withCredentials?: boolean;
|
|
2689
2696
|
/** Proxy configuration (URL string or detailed options) */
|
|
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
|
|
|
3233
3240
|
* ```
|
|
3234
3241
|
*/
|
|
3235
3242
|
beforeRedirect?: RezoHttpRequest["beforeRedirect"];
|
|
3243
|
+
/** Alias for beforeRedirect */
|
|
3244
|
+
onRedirect?: RezoHttpRequest["onRedirect"];
|
|
3236
3245
|
/** Array of functions to transform request data */
|
|
3237
3246
|
transformRequest?: RezoHttpRequest["transformRequest"];
|
|
3238
3247
|
/** Array of functions to transform response data */
|
|
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
|
|
|
1934
1934
|
* ```
|
|
1935
1935
|
*/
|
|
1936
1936
|
beforeRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
|
+
/** Alias for beforeRedirect */
|
|
1938
|
+
onRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
1939
|
/** Character encoding for request body and response data */
|
|
1938
1940
|
encoding?: BufferEncoding;
|
|
1939
1941
|
/**
|
|
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2684
2686
|
* ```
|
|
2685
2687
|
*/
|
|
2686
2688
|
beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2689
|
+
/**
|
|
2690
|
+
* Alias for beforeRedirect - callback invoked when a redirect response is received.
|
|
2691
|
+
* @see beforeRedirect
|
|
2692
|
+
*/
|
|
2693
|
+
onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2687
2694
|
/** Whether to send cookies and authorization headers with cross-origin requests */
|
|
2688
2695
|
withCredentials?: boolean;
|
|
2689
2696
|
/** Proxy configuration (URL string or detailed options) */
|
|
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
|
|
|
3233
3240
|
* ```
|
|
3234
3241
|
*/
|
|
3235
3242
|
beforeRedirect?: RezoHttpRequest["beforeRedirect"];
|
|
3243
|
+
/** Alias for beforeRedirect */
|
|
3244
|
+
onRedirect?: RezoHttpRequest["onRedirect"];
|
|
3236
3245
|
/** Array of functions to transform request data */
|
|
3237
3246
|
transformRequest?: RezoHttpRequest["transformRequest"];
|
|
3238
3247
|
/** Array of functions to transform response data */
|
|
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
|
|
|
1934
1934
|
* ```
|
|
1935
1935
|
*/
|
|
1936
1936
|
beforeRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
|
+
/** Alias for beforeRedirect */
|
|
1938
|
+
onRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
1939
|
/** Character encoding for request body and response data */
|
|
1938
1940
|
encoding?: BufferEncoding;
|
|
1939
1941
|
/**
|
|
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2684
2686
|
* ```
|
|
2685
2687
|
*/
|
|
2686
2688
|
beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2689
|
+
/**
|
|
2690
|
+
* Alias for beforeRedirect - callback invoked when a redirect response is received.
|
|
2691
|
+
* @see beforeRedirect
|
|
2692
|
+
*/
|
|
2693
|
+
onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2687
2694
|
/** Whether to send cookies and authorization headers with cross-origin requests */
|
|
2688
2695
|
withCredentials?: boolean;
|
|
2689
2696
|
/** Proxy configuration (URL string or detailed options) */
|
|
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
|
|
|
3233
3240
|
* ```
|
|
3234
3241
|
*/
|
|
3235
3242
|
beforeRedirect?: RezoHttpRequest["beforeRedirect"];
|
|
3243
|
+
/** Alias for beforeRedirect */
|
|
3244
|
+
onRedirect?: RezoHttpRequest["onRedirect"];
|
|
3236
3245
|
/** Array of functions to transform request data */
|
|
3237
3246
|
transformRequest?: RezoHttpRequest["transformRequest"];
|
|
3238
3247
|
/** Array of functions to transform response data */
|
|
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
|
|
|
1934
1934
|
* ```
|
|
1935
1935
|
*/
|
|
1936
1936
|
beforeRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
|
+
/** Alias for beforeRedirect */
|
|
1938
|
+
onRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
1939
|
/** Character encoding for request body and response data */
|
|
1938
1940
|
encoding?: BufferEncoding;
|
|
1939
1941
|
/**
|
|
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2684
2686
|
* ```
|
|
2685
2687
|
*/
|
|
2686
2688
|
beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2689
|
+
/**
|
|
2690
|
+
* Alias for beforeRedirect - callback invoked when a redirect response is received.
|
|
2691
|
+
* @see beforeRedirect
|
|
2692
|
+
*/
|
|
2693
|
+
onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2687
2694
|
/** Whether to send cookies and authorization headers with cross-origin requests */
|
|
2688
2695
|
withCredentials?: boolean;
|
|
2689
2696
|
/** Proxy configuration (URL string or detailed options) */
|
|
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
|
|
|
3233
3240
|
* ```
|
|
3234
3241
|
*/
|
|
3235
3242
|
beforeRedirect?: RezoHttpRequest["beforeRedirect"];
|
|
3243
|
+
/** Alias for beforeRedirect */
|
|
3244
|
+
onRedirect?: RezoHttpRequest["onRedirect"];
|
|
3236
3245
|
/** Array of functions to transform request data */
|
|
3237
3246
|
transformRequest?: RezoHttpRequest["transformRequest"];
|
|
3238
3247
|
/** Array of functions to transform response data */
|
|
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
|
|
|
1934
1934
|
* ```
|
|
1935
1935
|
*/
|
|
1936
1936
|
beforeRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
|
+
/** Alias for beforeRedirect */
|
|
1938
|
+
onRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
1939
|
/** Character encoding for request body and response data */
|
|
1938
1940
|
encoding?: BufferEncoding;
|
|
1939
1941
|
/**
|
|
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2684
2686
|
* ```
|
|
2685
2687
|
*/
|
|
2686
2688
|
beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2689
|
+
/**
|
|
2690
|
+
* Alias for beforeRedirect - callback invoked when a redirect response is received.
|
|
2691
|
+
* @see beforeRedirect
|
|
2692
|
+
*/
|
|
2693
|
+
onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2687
2694
|
/** Whether to send cookies and authorization headers with cross-origin requests */
|
|
2688
2695
|
withCredentials?: boolean;
|
|
2689
2696
|
/** Proxy configuration (URL string or detailed options) */
|
|
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
|
|
|
3233
3240
|
* ```
|
|
3234
3241
|
*/
|
|
3235
3242
|
beforeRedirect?: RezoHttpRequest["beforeRedirect"];
|
|
3243
|
+
/** Alias for beforeRedirect */
|
|
3244
|
+
onRedirect?: RezoHttpRequest["onRedirect"];
|
|
3236
3245
|
/** Array of functions to transform request data */
|
|
3237
3246
|
transformRequest?: RezoHttpRequest["transformRequest"];
|
|
3238
3247
|
/** Array of functions to transform response data */
|
|
@@ -1934,6 +1934,8 @@ export interface RezoConfig {
|
|
|
1934
1934
|
* ```
|
|
1935
1935
|
*/
|
|
1936
1936
|
beforeRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
|
+
/** Alias for beforeRedirect */
|
|
1938
|
+
onRedirect?: RezoRequestConfig["beforeRedirect"];
|
|
1937
1939
|
/** Character encoding for request body and response data */
|
|
1938
1940
|
encoding?: BufferEncoding;
|
|
1939
1941
|
/**
|
|
@@ -2684,6 +2686,11 @@ export interface RezoRequestConfig<D = any> {
|
|
|
2684
2686
|
* ```
|
|
2685
2687
|
*/
|
|
2686
2688
|
beforeRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2689
|
+
/**
|
|
2690
|
+
* Alias for beforeRedirect - callback invoked when a redirect response is received.
|
|
2691
|
+
* @see beforeRedirect
|
|
2692
|
+
*/
|
|
2693
|
+
onRedirect?: (options: OnRedirectOptions) => OnRedirectResponse;
|
|
2687
2694
|
/** Whether to send cookies and authorization headers with cross-origin requests */
|
|
2688
2695
|
withCredentials?: boolean;
|
|
2689
2696
|
/** Proxy configuration (URL string or detailed options) */
|
|
@@ -3233,6 +3240,8 @@ export interface RezoDefaultOptions {
|
|
|
3233
3240
|
* ```
|
|
3234
3241
|
*/
|
|
3235
3242
|
beforeRedirect?: RezoHttpRequest["beforeRedirect"];
|
|
3243
|
+
/** Alias for beforeRedirect */
|
|
3244
|
+
onRedirect?: RezoHttpRequest["onRedirect"];
|
|
3236
3245
|
/** Array of functions to transform request data */
|
|
3237
3246
|
transformRequest?: RezoHttpRequest["transformRequest"];
|
|
3238
3247
|
/** Array of functions to transform response data */
|
package/dist/adapters/fetch.cjs
CHANGED
|
@@ -129,7 +129,7 @@ function sanitizeConfig(config) {
|
|
|
129
129
|
delete sanitized.data;
|
|
130
130
|
return sanitized;
|
|
131
131
|
}
|
|
132
|
-
function parseCookiesFromHeaders(headers, url, config) {
|
|
132
|
+
async function parseCookiesFromHeaders(headers, url, config) {
|
|
133
133
|
let setCookieHeaders = [];
|
|
134
134
|
if (typeof headers.getSetCookie === "function") {
|
|
135
135
|
setCookieHeaders = headers.getSetCookie() || [];
|
|
@@ -149,13 +149,59 @@ function parseCookiesFromHeaders(headers, url, config) {
|
|
|
149
149
|
setCookiesString: []
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
+
const tempJar = new RezoCookieJar;
|
|
153
|
+
tempJar.setCookiesSync(setCookieHeaders, url);
|
|
154
|
+
const parsedCookies = tempJar.cookies();
|
|
155
|
+
const acceptedCookies = [];
|
|
156
|
+
let hookError = null;
|
|
157
|
+
if (config?.hooks?.beforeCookie && config.hooks.beforeCookie.length > 0) {
|
|
158
|
+
for (const cookie of parsedCookies.array) {
|
|
159
|
+
let shouldAccept = true;
|
|
160
|
+
for (const hook of config.hooks.beforeCookie) {
|
|
161
|
+
try {
|
|
162
|
+
const result = await hook({
|
|
163
|
+
cookie,
|
|
164
|
+
source: "response",
|
|
165
|
+
url,
|
|
166
|
+
isValid: true
|
|
167
|
+
}, config);
|
|
168
|
+
if (result === false) {
|
|
169
|
+
shouldAccept = false;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
} catch (err) {
|
|
173
|
+
hookError = err;
|
|
174
|
+
if (config.debug) {
|
|
175
|
+
console.log("[Rezo Debug] beforeCookie hook error:", err);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (shouldAccept) {
|
|
180
|
+
acceptedCookies.push(cookie);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
acceptedCookies.push(...parsedCookies.array);
|
|
185
|
+
}
|
|
186
|
+
const acceptedCookieStrings = acceptedCookies.map((c) => c.cookieString());
|
|
152
187
|
const jar = new RezoCookieJar;
|
|
153
|
-
jar.setCookiesSync(
|
|
188
|
+
jar.setCookiesSync(acceptedCookieStrings, url);
|
|
154
189
|
if (config?.enableCookieJar && config?.cookieJar) {
|
|
155
|
-
config.cookieJar.setCookiesSync(
|
|
190
|
+
config.cookieJar.setCookiesSync(acceptedCookieStrings, url);
|
|
156
191
|
}
|
|
157
192
|
const cookies = jar.cookies();
|
|
158
193
|
cookies.setCookiesString = setCookieHeaders;
|
|
194
|
+
if (!hookError && config?.hooks?.afterCookie && config.hooks.afterCookie.length > 0) {
|
|
195
|
+
for (const hook of config.hooks.afterCookie) {
|
|
196
|
+
try {
|
|
197
|
+
await hook(acceptedCookies, config);
|
|
198
|
+
} catch (err) {
|
|
199
|
+
if (config.debug) {
|
|
200
|
+
console.log("[Rezo Debug] afterCookie hook error:", err);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
159
205
|
return cookies;
|
|
160
206
|
}
|
|
161
207
|
function mergeRequestAndResponseCookies(config, responseCookies, url) {
|
|
@@ -385,8 +431,14 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
|
|
|
385
431
|
}
|
|
386
432
|
retries++;
|
|
387
433
|
config.retryAttempts++;
|
|
434
|
+
const currentDelay = incrementDelay ? retryDelay * retries : retryDelay;
|
|
435
|
+
if (config.hooks?.beforeRetry && config.hooks.beforeRetry.length > 0) {
|
|
436
|
+
for (const hook of config.hooks.beforeRetry) {
|
|
437
|
+
await hook(config, response, retries);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
388
440
|
if (retryDelay > 0) {
|
|
389
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
441
|
+
await new Promise((resolve) => setTimeout(resolve, currentDelay));
|
|
390
442
|
}
|
|
391
443
|
}
|
|
392
444
|
continue;
|
|
@@ -435,7 +487,8 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
|
|
|
435
487
|
visitedUrls.add(normalizedRedirectUrl);
|
|
436
488
|
}
|
|
437
489
|
const redirectCode = response.status;
|
|
438
|
-
const
|
|
490
|
+
const redirectCallback = config.beforeRedirect || config.onRedirect;
|
|
491
|
+
const onRedirect = redirectCallback ? redirectCallback({
|
|
439
492
|
url: new URL(location),
|
|
440
493
|
status: response.status,
|
|
441
494
|
headers: response.headers,
|
|
@@ -583,7 +636,7 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
|
|
|
583
636
|
const responseHeaders = fromFetchHeaders(response.headers);
|
|
584
637
|
const contentType = response.headers.get("content-type") || "";
|
|
585
638
|
const contentLength = response.headers.get("content-length");
|
|
586
|
-
const cookies = parseCookiesFromHeaders(response.headers, url.href, config);
|
|
639
|
+
const cookies = await parseCookiesFromHeaders(response.headers, url.href, config);
|
|
587
640
|
config.responseCookies = cookies;
|
|
588
641
|
const location = response.headers.get("location");
|
|
589
642
|
const isRedirect = status >= 300 && status < 400 && location;
|
package/dist/adapters/fetch.js
CHANGED
|
@@ -129,7 +129,7 @@ function sanitizeConfig(config) {
|
|
|
129
129
|
delete sanitized.data;
|
|
130
130
|
return sanitized;
|
|
131
131
|
}
|
|
132
|
-
function parseCookiesFromHeaders(headers, url, config) {
|
|
132
|
+
async function parseCookiesFromHeaders(headers, url, config) {
|
|
133
133
|
let setCookieHeaders = [];
|
|
134
134
|
if (typeof headers.getSetCookie === "function") {
|
|
135
135
|
setCookieHeaders = headers.getSetCookie() || [];
|
|
@@ -149,13 +149,59 @@ function parseCookiesFromHeaders(headers, url, config) {
|
|
|
149
149
|
setCookiesString: []
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
+
const tempJar = new RezoCookieJar;
|
|
153
|
+
tempJar.setCookiesSync(setCookieHeaders, url);
|
|
154
|
+
const parsedCookies = tempJar.cookies();
|
|
155
|
+
const acceptedCookies = [];
|
|
156
|
+
let hookError = null;
|
|
157
|
+
if (config?.hooks?.beforeCookie && config.hooks.beforeCookie.length > 0) {
|
|
158
|
+
for (const cookie of parsedCookies.array) {
|
|
159
|
+
let shouldAccept = true;
|
|
160
|
+
for (const hook of config.hooks.beforeCookie) {
|
|
161
|
+
try {
|
|
162
|
+
const result = await hook({
|
|
163
|
+
cookie,
|
|
164
|
+
source: "response",
|
|
165
|
+
url,
|
|
166
|
+
isValid: true
|
|
167
|
+
}, config);
|
|
168
|
+
if (result === false) {
|
|
169
|
+
shouldAccept = false;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
} catch (err) {
|
|
173
|
+
hookError = err;
|
|
174
|
+
if (config.debug) {
|
|
175
|
+
console.log("[Rezo Debug] beforeCookie hook error:", err);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (shouldAccept) {
|
|
180
|
+
acceptedCookies.push(cookie);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
acceptedCookies.push(...parsedCookies.array);
|
|
185
|
+
}
|
|
186
|
+
const acceptedCookieStrings = acceptedCookies.map((c) => c.cookieString());
|
|
152
187
|
const jar = new RezoCookieJar;
|
|
153
|
-
jar.setCookiesSync(
|
|
188
|
+
jar.setCookiesSync(acceptedCookieStrings, url);
|
|
154
189
|
if (config?.enableCookieJar && config?.cookieJar) {
|
|
155
|
-
config.cookieJar.setCookiesSync(
|
|
190
|
+
config.cookieJar.setCookiesSync(acceptedCookieStrings, url);
|
|
156
191
|
}
|
|
157
192
|
const cookies = jar.cookies();
|
|
158
193
|
cookies.setCookiesString = setCookieHeaders;
|
|
194
|
+
if (!hookError && config?.hooks?.afterCookie && config.hooks.afterCookie.length > 0) {
|
|
195
|
+
for (const hook of config.hooks.afterCookie) {
|
|
196
|
+
try {
|
|
197
|
+
await hook(acceptedCookies, config);
|
|
198
|
+
} catch (err) {
|
|
199
|
+
if (config.debug) {
|
|
200
|
+
console.log("[Rezo Debug] afterCookie hook error:", err);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
159
205
|
return cookies;
|
|
160
206
|
}
|
|
161
207
|
function mergeRequestAndResponseCookies(config, responseCookies, url) {
|
|
@@ -385,8 +431,14 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
|
|
|
385
431
|
}
|
|
386
432
|
retries++;
|
|
387
433
|
config.retryAttempts++;
|
|
434
|
+
const currentDelay = incrementDelay ? retryDelay * retries : retryDelay;
|
|
435
|
+
if (config.hooks?.beforeRetry && config.hooks.beforeRetry.length > 0) {
|
|
436
|
+
for (const hook of config.hooks.beforeRetry) {
|
|
437
|
+
await hook(config, response, retries);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
388
440
|
if (retryDelay > 0) {
|
|
389
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
441
|
+
await new Promise((resolve) => setTimeout(resolve, currentDelay));
|
|
390
442
|
}
|
|
391
443
|
}
|
|
392
444
|
continue;
|
|
@@ -435,7 +487,8 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
|
|
|
435
487
|
visitedUrls.add(normalizedRedirectUrl);
|
|
436
488
|
}
|
|
437
489
|
const redirectCode = response.status;
|
|
438
|
-
const
|
|
490
|
+
const redirectCallback = config.beforeRedirect || config.onRedirect;
|
|
491
|
+
const onRedirect = redirectCallback ? redirectCallback({
|
|
439
492
|
url: new URL(location),
|
|
440
493
|
status: response.status,
|
|
441
494
|
headers: response.headers,
|
|
@@ -583,7 +636,7 @@ async function executeSingleFetchRequest(config, fetchOptions, requestCount, tim
|
|
|
583
636
|
const responseHeaders = fromFetchHeaders(response.headers);
|
|
584
637
|
const contentType = response.headers.get("content-type") || "";
|
|
585
638
|
const contentLength = response.headers.get("content-length");
|
|
586
|
-
const cookies = parseCookiesFromHeaders(response.headers, url.href, config);
|
|
639
|
+
const cookies = await parseCookiesFromHeaders(response.headers, url.href, config);
|
|
587
640
|
config.responseCookies = cookies;
|
|
588
641
|
const location = response.headers.get("location");
|
|
589
642
|
const isRedirect = status >= 300 && status < 400 && location;
|
package/dist/adapters/http.cjs
CHANGED
|
@@ -386,6 +386,11 @@ async function executeHttp1Request(fetchOptions, config, options, perform, fs, s
|
|
|
386
386
|
retries++;
|
|
387
387
|
const currentDelay = incrementDelay ? retryDelay * retries : retryDelay;
|
|
388
388
|
debugLog.retry(config, retries, maxRetries, responseStatusCode, currentDelay);
|
|
389
|
+
if (config.hooks?.beforeRetry && config.hooks.beforeRetry.length > 0) {
|
|
390
|
+
for (const hook of config.hooks.beforeRetry) {
|
|
391
|
+
await hook(config, response, retries);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
389
394
|
if (retryDelay > 0) {
|
|
390
395
|
await new Promise((resolve) => setTimeout(resolve, currentDelay));
|
|
391
396
|
}
|
|
@@ -427,7 +432,8 @@ async function executeHttp1Request(fetchOptions, config, options, perform, fs, s
|
|
|
427
432
|
}
|
|
428
433
|
const redirectCode = response.status;
|
|
429
434
|
const customHeaders = undefined;
|
|
430
|
-
const
|
|
435
|
+
const redirectCallback = config.beforeRedirect || config.onRedirect;
|
|
436
|
+
const onRedirect = redirectCallback ? redirectCallback({
|
|
431
437
|
url: new URL(_stats.redirectUrl),
|
|
432
438
|
status: response.status,
|
|
433
439
|
headers: response.headers,
|
|
@@ -573,7 +579,7 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
573
579
|
const location = headers["location"] || headers["Location"];
|
|
574
580
|
const contentLength = headers["content-length"];
|
|
575
581
|
const cookies = headers["set-cookie"];
|
|
576
|
-
updateCookies(config, headers, url.href);
|
|
582
|
+
await updateCookies(config, headers, url.href);
|
|
577
583
|
const cookieArray = config.responseCookies?.array || [];
|
|
578
584
|
delete headers["set-cookie"];
|
|
579
585
|
_stats.redirectUrl = undefined;
|
|
@@ -876,13 +882,31 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
876
882
|
}
|
|
877
883
|
timing.dnsStart = performance.now();
|
|
878
884
|
config.timing.domainLookupStart = timing.dnsStart;
|
|
879
|
-
socket.on("lookup", () => {
|
|
885
|
+
socket.on("lookup", (err, address, family) => {
|
|
880
886
|
if (!timing.dnsEnd) {
|
|
881
887
|
timing.dnsEnd = performance.now();
|
|
882
888
|
config.timing.domainLookupEnd = timing.dnsEnd;
|
|
883
889
|
timing.tcpStart = performance.now();
|
|
884
890
|
config.timing.connectStart = timing.tcpStart;
|
|
885
891
|
}
|
|
892
|
+
if (config.hooks?.onDns && config.hooks.onDns.length > 0) {
|
|
893
|
+
const familyNum = typeof family === "number" ? family : family === "IPv6" ? 6 : 4;
|
|
894
|
+
for (const hook of config.hooks.onDns) {
|
|
895
|
+
try {
|
|
896
|
+
hook({
|
|
897
|
+
hostname: url.hostname,
|
|
898
|
+
address: address || "",
|
|
899
|
+
family: familyNum,
|
|
900
|
+
duration: timing.dnsEnd - timing.dnsStart,
|
|
901
|
+
timestamp: Date.now()
|
|
902
|
+
}, config);
|
|
903
|
+
} catch (err) {
|
|
904
|
+
if (config.debug) {
|
|
905
|
+
console.log("[Rezo Debug] onDns hook error:", err);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
886
910
|
});
|
|
887
911
|
socket.on("secureConnect", () => {
|
|
888
912
|
if (!timing.tlsEnd && timing.tlsStart) {
|
|
@@ -909,6 +933,31 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
909
933
|
hostnameMatch: cert.subject?.CN === url.hostname,
|
|
910
934
|
chainValid: true
|
|
911
935
|
};
|
|
936
|
+
if (config.hooks?.onTls && config.hooks.onTls.length > 0) {
|
|
937
|
+
for (const hook of config.hooks.onTls) {
|
|
938
|
+
try {
|
|
939
|
+
hook({
|
|
940
|
+
protocol: tlsVersion,
|
|
941
|
+
cipher: cipher?.name || "",
|
|
942
|
+
authorized: !socket.authorizationError,
|
|
943
|
+
authorizationError: socket.authorizationError,
|
|
944
|
+
certificate: cert ? {
|
|
945
|
+
subject: cert.subject?.CN || "",
|
|
946
|
+
issuer: cert.issuer?.CN || "",
|
|
947
|
+
validFrom: cert.valid_from || "",
|
|
948
|
+
validTo: cert.valid_to || "",
|
|
949
|
+
fingerprint: cert.fingerprint || ""
|
|
950
|
+
} : undefined,
|
|
951
|
+
duration: timing.tlsEnd - timing.tlsStart,
|
|
952
|
+
timestamp: Date.now()
|
|
953
|
+
}, config);
|
|
954
|
+
} catch (err) {
|
|
955
|
+
if (config.debug) {
|
|
956
|
+
console.log("[Rezo Debug] onTls hook error:", err);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}
|
|
912
961
|
});
|
|
913
962
|
socket.on("connect", () => {
|
|
914
963
|
if (!timing.tcpEnd) {
|
|
@@ -927,6 +976,24 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
927
976
|
config.network.localPort = localPort;
|
|
928
977
|
config.network.family = remoteFamily;
|
|
929
978
|
}
|
|
979
|
+
if (config.hooks?.onSocket && config.hooks.onSocket.length > 0) {
|
|
980
|
+
for (const hook of config.hooks.onSocket) {
|
|
981
|
+
try {
|
|
982
|
+
hook({
|
|
983
|
+
type: "connect",
|
|
984
|
+
localAddress,
|
|
985
|
+
localPort,
|
|
986
|
+
remoteAddress,
|
|
987
|
+
remotePort,
|
|
988
|
+
timestamp: Date.now()
|
|
989
|
+
}, socket);
|
|
990
|
+
} catch (err) {
|
|
991
|
+
if (config.debug) {
|
|
992
|
+
console.log("[Rezo Debug] onSocket hook error:", err);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
930
997
|
});
|
|
931
998
|
});
|
|
932
999
|
req.on("error", (error) => {
|
|
@@ -1322,18 +1389,52 @@ function parseProxy(proxy, isScure = true, rejectUnauthorized = false) {
|
|
|
1322
1389
|
}
|
|
1323
1390
|
return rezoProxy(proxy);
|
|
1324
1391
|
}
|
|
1325
|
-
function updateCookies(config, headers, url) {
|
|
1392
|
+
async function updateCookies(config, headers, url) {
|
|
1326
1393
|
const cookies = headers["set-cookie"];
|
|
1327
1394
|
if (cookies) {
|
|
1328
1395
|
const jar = new RezoCookieJar;
|
|
1396
|
+
const tempJar = new RezoCookieJar;
|
|
1397
|
+
tempJar.setCookiesSync(cookies, url);
|
|
1398
|
+
const parsedCookies = tempJar.cookies();
|
|
1399
|
+
const acceptedCookies = [];
|
|
1400
|
+
let hookError = null;
|
|
1401
|
+
if (config.hooks?.beforeCookie && config.hooks.beforeCookie.length > 0) {
|
|
1402
|
+
for (const cookie of parsedCookies.array) {
|
|
1403
|
+
let shouldAccept = true;
|
|
1404
|
+
for (const hook of config.hooks.beforeCookie) {
|
|
1405
|
+
try {
|
|
1406
|
+
const result = await hook({
|
|
1407
|
+
cookie,
|
|
1408
|
+
source: "response",
|
|
1409
|
+
url,
|
|
1410
|
+
isValid: true
|
|
1411
|
+
}, config);
|
|
1412
|
+
if (result === false) {
|
|
1413
|
+
shouldAccept = false;
|
|
1414
|
+
break;
|
|
1415
|
+
}
|
|
1416
|
+
} catch (err) {
|
|
1417
|
+
hookError = err;
|
|
1418
|
+
if (config.debug) {
|
|
1419
|
+
console.log("[Rezo Debug] beforeCookie hook error:", err);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
if (shouldAccept) {
|
|
1424
|
+
acceptedCookies.push(cookie);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
} else {
|
|
1428
|
+
acceptedCookies.push(...parsedCookies.array);
|
|
1429
|
+
}
|
|
1430
|
+
const acceptedCookieStrings = acceptedCookies.map((c) => c.cookieString());
|
|
1329
1431
|
if (config.enableCookieJar && config.cookieJar) {
|
|
1330
|
-
config.cookieJar.setCookiesSync(
|
|
1432
|
+
config.cookieJar.setCookiesSync(acceptedCookieStrings, url);
|
|
1331
1433
|
}
|
|
1332
|
-
jar.setCookiesSync(
|
|
1434
|
+
jar.setCookiesSync(acceptedCookieStrings, url);
|
|
1333
1435
|
if (config.useCookies) {
|
|
1334
|
-
const parsedCookies = jar.cookies();
|
|
1335
1436
|
const existingArray = config.responseCookies?.array || [];
|
|
1336
|
-
for (const cookie of
|
|
1437
|
+
for (const cookie of acceptedCookies) {
|
|
1337
1438
|
const existingIndex = existingArray.findIndex((c) => c.key === cookie.key && c.domain === cookie.domain);
|
|
1338
1439
|
if (existingIndex >= 0) {
|
|
1339
1440
|
existingArray[existingIndex] = cookie;
|
|
@@ -1344,6 +1445,17 @@ function updateCookies(config, headers, url) {
|
|
|
1344
1445
|
const mergedJar = new RezoCookieJar(existingArray, url);
|
|
1345
1446
|
config.responseCookies = mergedJar.cookies();
|
|
1346
1447
|
}
|
|
1448
|
+
if (!hookError && config.hooks?.afterCookie && config.hooks.afterCookie.length > 0) {
|
|
1449
|
+
for (const hook of config.hooks.afterCookie) {
|
|
1450
|
+
try {
|
|
1451
|
+
await hook(acceptedCookies, config);
|
|
1452
|
+
} catch (err) {
|
|
1453
|
+
if (config.debug) {
|
|
1454
|
+
console.log("[Rezo Debug] afterCookie hook error:", err);
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1347
1459
|
}
|
|
1348
1460
|
}
|
|
1349
1461
|
|