@crawlee/impit-client 3.17.1-beta.71 → 3.17.1-beta.72
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/index.d.ts +7 -2
- package/index.js +45 -8
- package/package.json +2 -2
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BaseHttpClient, HttpRequest, HttpResponse, ResponseTypes, StreamingHttpResponse } from '@crawlee/core';
|
|
1
|
+
import type { BaseHttpClient, HttpRequest, HttpResponse, RedirectHandler, ResponseTypes, StreamingHttpResponse } from '@crawlee/core';
|
|
2
2
|
import type { ImpitOptions } from 'impit';
|
|
3
3
|
export declare const Browser: {
|
|
4
4
|
readonly Chrome: "chrome";
|
|
@@ -35,6 +35,11 @@ export declare class ImpitHttpClient implements BaseHttpClient {
|
|
|
35
35
|
private intoHeaders;
|
|
36
36
|
private intoImpitBody;
|
|
37
37
|
private shouldRewriteRedirectToGet;
|
|
38
|
+
/**
|
|
39
|
+
* Converts Fetch/Impit headers into a simple header map.
|
|
40
|
+
* `Object.fromEntries` would keep only the last `set-cookie` value, so those are collected separately.
|
|
41
|
+
*/
|
|
42
|
+
private intoSimpleHeaders;
|
|
38
43
|
/**
|
|
39
44
|
* Common implementation for `sendRequest` and `stream` methods.
|
|
40
45
|
* @param request `HttpRequest` object
|
|
@@ -49,5 +54,5 @@ export declare class ImpitHttpClient implements BaseHttpClient {
|
|
|
49
54
|
/**
|
|
50
55
|
* @inheritDoc
|
|
51
56
|
*/
|
|
52
|
-
stream(request: HttpRequest): Promise<StreamingHttpResponse>;
|
|
57
|
+
stream(request: HttpRequest, onRedirect?: RedirectHandler): Promise<StreamingHttpResponse>;
|
|
53
58
|
}
|
package/index.js
CHANGED
|
@@ -111,12 +111,29 @@ class ImpitHttpClient {
|
|
|
111
111
|
return method !== 'HEAD';
|
|
112
112
|
return false;
|
|
113
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Converts Fetch/Impit headers into a simple header map.
|
|
116
|
+
* `Object.fromEntries` would keep only the last `set-cookie` value, so those are collected separately.
|
|
117
|
+
*/
|
|
118
|
+
intoSimpleHeaders(headers) {
|
|
119
|
+
const result = {};
|
|
120
|
+
for (const [key, value] of headers.entries()) {
|
|
121
|
+
if (key === 'set-cookie')
|
|
122
|
+
continue;
|
|
123
|
+
result[key] = value;
|
|
124
|
+
}
|
|
125
|
+
const setCookies = headers.getSetCookie();
|
|
126
|
+
if (setCookies.length > 0) {
|
|
127
|
+
result['set-cookie'] = setCookies.length === 1 ? setCookies[0] : setCookies;
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
114
131
|
/**
|
|
115
132
|
* Common implementation for `sendRequest` and `stream` methods.
|
|
116
133
|
* @param request `HttpRequest` object
|
|
117
134
|
* @returns `HttpResponse` object
|
|
118
135
|
*/
|
|
119
|
-
async getResponse(request, redirects) {
|
|
136
|
+
async getResponse(request, redirects, onRedirect) {
|
|
120
137
|
if ((redirects?.redirectCount ?? 0) > this.maxRedirects) {
|
|
121
138
|
throw new Error(`Too many redirects, maximum is ${this.maxRedirects}.`);
|
|
122
139
|
}
|
|
@@ -139,14 +156,34 @@ class ImpitHttpClient {
|
|
|
139
156
|
if (!location) {
|
|
140
157
|
throw new Error('Redirect response missing location header.');
|
|
141
158
|
}
|
|
159
|
+
const nextRedirectUrls = [...(redirects?.redirectUrls ?? []), redirectUrl];
|
|
160
|
+
const updatedRequest = {
|
|
161
|
+
url: redirectUrl.href,
|
|
162
|
+
headers: { ...(request.headers ?? {}) },
|
|
163
|
+
};
|
|
164
|
+
// Match GotScrapingHttpClient: allow HttpCrawler to persist redirect cookies into the session
|
|
165
|
+
// and mutate Cookie / URL for the next hop.
|
|
166
|
+
onRedirect?.({
|
|
167
|
+
redirectUrls: nextRedirectUrls,
|
|
168
|
+
url,
|
|
169
|
+
statusCode: response.status,
|
|
170
|
+
statusMessage: response.statusText,
|
|
171
|
+
headers: this.intoSimpleHeaders(response.headers),
|
|
172
|
+
trailers: {},
|
|
173
|
+
complete: true,
|
|
174
|
+
}, updatedRequest);
|
|
175
|
+
const nextUrl = typeof updatedRequest.url === 'string'
|
|
176
|
+
? updatedRequest.url
|
|
177
|
+
: (updatedRequest.url?.href ?? redirectUrl.href);
|
|
142
178
|
return this.getResponse({
|
|
143
179
|
...request,
|
|
144
180
|
method: this.shouldRewriteRedirectToGet(response.status, request.method) ? 'GET' : request.method,
|
|
145
|
-
url:
|
|
181
|
+
url: nextUrl,
|
|
182
|
+
headers: updatedRequest.headers,
|
|
146
183
|
}, {
|
|
147
184
|
redirectCount: (redirects?.redirectCount ?? 0) + 1,
|
|
148
|
-
redirectUrls:
|
|
149
|
-
});
|
|
185
|
+
redirectUrls: nextRedirectUrls,
|
|
186
|
+
}, onRedirect);
|
|
150
187
|
}
|
|
151
188
|
return {
|
|
152
189
|
response,
|
|
@@ -173,7 +210,7 @@ class ImpitHttpClient {
|
|
|
173
210
|
throw new Error('Unsupported response type.');
|
|
174
211
|
}
|
|
175
212
|
return {
|
|
176
|
-
headers:
|
|
213
|
+
headers: this.intoSimpleHeaders(response.headers),
|
|
177
214
|
statusCode: response.status,
|
|
178
215
|
url: response.url,
|
|
179
216
|
request,
|
|
@@ -207,8 +244,8 @@ class ImpitHttpClient {
|
|
|
207
244
|
/**
|
|
208
245
|
* @inheritDoc
|
|
209
246
|
*/
|
|
210
|
-
async stream(request) {
|
|
211
|
-
const { response, redirectUrls } = await this.getResponse(request);
|
|
247
|
+
async stream(request, onRedirect) {
|
|
248
|
+
const { response, redirectUrls } = await this.getResponse(request, undefined, onRedirect);
|
|
212
249
|
const [stream, getDownloadProgress] = this.getStreamWithProgress(response);
|
|
213
250
|
return {
|
|
214
251
|
request,
|
|
@@ -221,7 +258,7 @@ class ImpitHttpClient {
|
|
|
221
258
|
},
|
|
222
259
|
uploadProgress: { percent: 100, transferred: 0 },
|
|
223
260
|
redirectUrls,
|
|
224
|
-
headers:
|
|
261
|
+
headers: this.intoSimpleHeaders(response.headers),
|
|
225
262
|
trailers: {},
|
|
226
263
|
};
|
|
227
264
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crawlee/impit-client",
|
|
3
|
-
"version": "3.17.1-beta.
|
|
3
|
+
"version": "3.17.1-beta.72",
|
|
4
4
|
"description": "impit-based HTTP client implementation for Crawlee. Impersonates browser requests to avoid bot detection.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.0.0"
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "b28c3cd14324b806ed2d4691790a423fb1760ea0"
|
|
74
74
|
}
|