@crawlee/http 3.0.3-beta.13

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.
@@ -0,0 +1,629 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createHttpRouter = exports.HttpCrawler = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const timeout_1 = require("@apify/timeout");
6
+ const utilities_1 = require("@apify/utilities");
7
+ const basic_1 = require("@crawlee/basic");
8
+ const content_type_1 = tslib_1.__importDefault(require("content-type"));
9
+ const mime_types_1 = tslib_1.__importDefault(require("mime-types"));
10
+ const got_scraping_1 = require("got-scraping");
11
+ const path_1 = require("path");
12
+ const iconv_lite_1 = tslib_1.__importDefault(require("iconv-lite"));
13
+ const ow_1 = tslib_1.__importDefault(require("ow"));
14
+ const node_util_1 = tslib_1.__importDefault(require("node:util"));
15
+ /**
16
+ * Default mime types, which HttpScraper supports.
17
+ */
18
+ const HTML_AND_XML_MIME_TYPES = ['text/html', 'text/xml', 'application/xhtml+xml', 'application/xml'];
19
+ const APPLICATION_JSON_MIME_TYPE = 'application/json';
20
+ const HTTP_OPTIMIZED_AUTOSCALED_POOL_OPTIONS = {
21
+ desiredConcurrency: 10,
22
+ snapshotterOptions: {
23
+ eventLoopSnapshotIntervalSecs: 2,
24
+ maxBlockedMillis: 100,
25
+ },
26
+ systemStatusOptions: {
27
+ maxEventLoopOverloadedRatio: 0.7,
28
+ },
29
+ };
30
+ /**
31
+ * Provides a framework for the parallel crawling of web pages using plain HTTP requests.
32
+ * The URLs to crawl are fed either from a static list of URLs
33
+ * or from a dynamic queue of URLs enabling recursive crawling of websites.
34
+ *
35
+ * It is very fast and efficient on data bandwidth. However, if the target website requires JavaScript
36
+ * to display the content, you might need to use {@apilink PuppeteerCrawler} or {@apilink PlaywrightCrawler} instead,
37
+ * because it loads the pages using full-featured headless Chrome browser.
38
+ *
39
+ * This crawler downloads each URL using a plain HTTP request and doesn't do any HTML parsing.
40
+ *
41
+ * The source URLs are represented using {@apilink Request} objects that are fed from
42
+ * {@apilink RequestList} or {@apilink RequestQueue} instances provided by the {@apilink HttpCrawlerOptions.requestList}
43
+ * or {@apilink HttpCrawlerOptions.requestQueue} constructor options, respectively.
44
+ *
45
+ * If both {@apilink HttpCrawlerOptions.requestList} and {@apilink HttpCrawlerOptions.requestQueue} are used,
46
+ * the instance first processes URLs from the {@apilink RequestList} and automatically enqueues all of them
47
+ * to {@apilink RequestQueue} before it starts their processing. This ensures that a single URL is not crawled multiple times.
48
+ *
49
+ * The crawler finishes when there are no more {@apilink Request} objects to crawl.
50
+ *
51
+ * We can use the `preNavigationHooks` to adjust `gotOptions`:
52
+ *
53
+ * ```javascript
54
+ * preNavigationHooks: [
55
+ * (crawlingContext, gotOptions) => {
56
+ * // ...
57
+ * },
58
+ * ]
59
+ * ```
60
+ *
61
+ * By default, this crawler only processes web pages with the `text/html`
62
+ * and `application/xhtml+xml` MIME content types (as reported by the `Content-Type` HTTP header),
63
+ * and skips pages with other content types. If you want the crawler to process other content types,
64
+ * use the {@apilink HttpCrawlerOptions.additionalMimeTypes} constructor option.
65
+ * Beware that the parsing behavior differs for HTML, XML, JSON and other types of content.
66
+ * For details, see {@apilink HttpCrawlerOptions.requestHandler}.
67
+ *
68
+ * New requests are only dispatched when there is enough free CPU and memory available,
69
+ * using the functionality provided by the {@apilink AutoscaledPool} class.
70
+ * All {@apilink AutoscaledPool} configuration options can be passed to the `autoscaledPoolOptions`
71
+ * parameter of the constructor. For user convenience, the `minConcurrency` and `maxConcurrency`
72
+ * {@apilink AutoscaledPool} options are available directly in the constructor.
73
+ *
74
+ * **Example usage:**
75
+ *
76
+ * ```javascript
77
+ * import { HttpCrawler, Dataset } from '@crawlee/http';
78
+ *
79
+ * const crawler = new HttpCrawler({
80
+ * requestList,
81
+ * async requestHandler({ request, response, body, contentType }) {
82
+ * // Save the data to dataset.
83
+ * await Dataset.pushData({
84
+ * url: request.url,
85
+ * html: body,
86
+ * });
87
+ * },
88
+ * });
89
+ *
90
+ * await crawler.run([
91
+ * 'http://www.example.com/page-1',
92
+ * 'http://www.example.com/page-2',
93
+ * ]);
94
+ * ```
95
+ * @category Crawlers
96
+ */
97
+ class HttpCrawler extends basic_1.BasicCrawler {
98
+ /**
99
+ * All `HttpCrawlerOptions` parameters are passed via an options object.
100
+ */
101
+ constructor(options = {}, config = basic_1.Configuration.getGlobalConfig()) {
102
+ (0, ow_1.default)(options, 'HttpCrawlerOptions', ow_1.default.object.exactShape(HttpCrawler.optionsShape));
103
+ const { requestHandler, handlePageFunction, requestHandlerTimeoutSecs = 60, navigationTimeoutSecs = 30, ignoreSslErrors = true, additionalMimeTypes = [], suggestResponseEncoding, forceResponseEncoding, proxyConfiguration, persistCookiesPerSession, preNavigationHooks = [], postNavigationHooks = [],
104
+ // Ignored
105
+ handleRequestFunction,
106
+ // BasicCrawler
107
+ autoscaledPoolOptions = HTTP_OPTIMIZED_AUTOSCALED_POOL_OPTIONS, ...basicCrawlerOptions } = options;
108
+ super({
109
+ ...basicCrawlerOptions,
110
+ requestHandler,
111
+ autoscaledPoolOptions,
112
+ // We need to add some time for internal functions to finish,
113
+ // but not too much so that we would stall the crawler.
114
+ requestHandlerTimeoutSecs: navigationTimeoutSecs + requestHandlerTimeoutSecs + basic_1.BASIC_CRAWLER_TIMEOUT_BUFFER_SECS,
115
+ }, config);
116
+ Object.defineProperty(this, "config", {
117
+ enumerable: true,
118
+ configurable: true,
119
+ writable: true,
120
+ value: config
121
+ });
122
+ /**
123
+ * A reference to the underlying {@apilink ProxyConfiguration} class that manages the crawler's proxies.
124
+ * Only available if used by the crawler.
125
+ */
126
+ Object.defineProperty(this, "proxyConfiguration", {
127
+ enumerable: true,
128
+ configurable: true,
129
+ writable: true,
130
+ value: void 0
131
+ });
132
+ Object.defineProperty(this, "userRequestHandlerTimeoutMillis", {
133
+ enumerable: true,
134
+ configurable: true,
135
+ writable: true,
136
+ value: void 0
137
+ });
138
+ Object.defineProperty(this, "preNavigationHooks", {
139
+ enumerable: true,
140
+ configurable: true,
141
+ writable: true,
142
+ value: void 0
143
+ });
144
+ Object.defineProperty(this, "postNavigationHooks", {
145
+ enumerable: true,
146
+ configurable: true,
147
+ writable: true,
148
+ value: void 0
149
+ });
150
+ Object.defineProperty(this, "persistCookiesPerSession", {
151
+ enumerable: true,
152
+ configurable: true,
153
+ writable: true,
154
+ value: void 0
155
+ });
156
+ Object.defineProperty(this, "navigationTimeoutMillis", {
157
+ enumerable: true,
158
+ configurable: true,
159
+ writable: true,
160
+ value: void 0
161
+ });
162
+ Object.defineProperty(this, "ignoreSslErrors", {
163
+ enumerable: true,
164
+ configurable: true,
165
+ writable: true,
166
+ value: void 0
167
+ });
168
+ Object.defineProperty(this, "suggestResponseEncoding", {
169
+ enumerable: true,
170
+ configurable: true,
171
+ writable: true,
172
+ value: void 0
173
+ });
174
+ Object.defineProperty(this, "forceResponseEncoding", {
175
+ enumerable: true,
176
+ configurable: true,
177
+ writable: true,
178
+ value: void 0
179
+ });
180
+ Object.defineProperty(this, "supportedMimeTypes", {
181
+ enumerable: true,
182
+ configurable: true,
183
+ writable: true,
184
+ value: void 0
185
+ });
186
+ /**
187
+ * @internal wraps public utility for mocking purposes
188
+ */
189
+ Object.defineProperty(this, "_requestAsBrowser", {
190
+ enumerable: true,
191
+ configurable: true,
192
+ writable: true,
193
+ value: (options) => {
194
+ return new Promise((resolve, reject) => {
195
+ const stream = (0, got_scraping_1.gotScraping)(options);
196
+ stream.on('error', reject);
197
+ stream.on('response', () => {
198
+ resolve(addResponsePropertiesToStream(stream));
199
+ });
200
+ });
201
+ }
202
+ });
203
+ this._handlePropertyNameChange({
204
+ newName: 'requestHandler',
205
+ oldName: 'handlePageFunction',
206
+ propertyKey: 'requestHandler',
207
+ newProperty: requestHandler,
208
+ oldProperty: handlePageFunction,
209
+ allowUndefined: true,
210
+ });
211
+ if (!this.requestHandler) {
212
+ this.requestHandler = this.router;
213
+ }
214
+ // Cookies should be persisted per session only if session pool is used
215
+ if (!this.useSessionPool && persistCookiesPerSession) {
216
+ throw new Error('You cannot use "persistCookiesPerSession" without "useSessionPool" set to true.');
217
+ }
218
+ this.supportedMimeTypes = new Set([...HTML_AND_XML_MIME_TYPES, APPLICATION_JSON_MIME_TYPE]);
219
+ if (additionalMimeTypes.length)
220
+ this._extendSupportedMimeTypes(additionalMimeTypes);
221
+ if (suggestResponseEncoding && forceResponseEncoding) {
222
+ this.log.warning('Both forceResponseEncoding and suggestResponseEncoding options are set. Using forceResponseEncoding.');
223
+ }
224
+ this.userRequestHandlerTimeoutMillis = requestHandlerTimeoutSecs * 1000;
225
+ this.navigationTimeoutMillis = navigationTimeoutSecs * 1000;
226
+ this.ignoreSslErrors = ignoreSslErrors;
227
+ this.suggestResponseEncoding = suggestResponseEncoding;
228
+ this.forceResponseEncoding = forceResponseEncoding;
229
+ this.proxyConfiguration = proxyConfiguration;
230
+ this.preNavigationHooks = preNavigationHooks;
231
+ this.postNavigationHooks = [
232
+ ({ request, response }) => this._abortDownloadOfBody(request, response),
233
+ ...postNavigationHooks,
234
+ ];
235
+ if (this.useSessionPool) {
236
+ this.persistCookiesPerSession = persistCookiesPerSession ?? true;
237
+ }
238
+ else {
239
+ this.persistCookiesPerSession = false;
240
+ }
241
+ }
242
+ /**
243
+ * **EXPERIMENTAL**
244
+ * Function for attaching CrawlerExtensions such as the Unblockers.
245
+ * @param extension Crawler extension that overrides the crawler configuration.
246
+ */
247
+ use(extension) {
248
+ (0, ow_1.default)(extension, ow_1.default.object.instanceOf(basic_1.CrawlerExtension));
249
+ const className = this.constructor.name;
250
+ const extensionOptions = extension.getCrawlerOptions();
251
+ for (const [key, value] of Object.entries(extensionOptions)) {
252
+ const isConfigurable = this.hasOwnProperty(key);
253
+ const originalType = typeof this[key];
254
+ const extensionType = typeof value; // What if we want to null something? It is really needed?
255
+ const isSameType = originalType === extensionType || value == null; // fast track for deleting keys
256
+ const exists = this[key] != null;
257
+ if (!isConfigurable) { // Test if the property can be configured on the crawler
258
+ throw new Error(`${extension.name} tries to set property "${key}" that is not configurable on ${className} instance.`);
259
+ }
260
+ if (!isSameType && exists) { // Assuming that extensions will only add up configuration
261
+ throw new Error(`${extension.name} tries to set property of different type "${extensionType}". "${className}.${key}: ${originalType}".`);
262
+ }
263
+ this.log.warning(`${extension.name} is overriding "${className}.${key}: ${originalType}" with ${value}.`);
264
+ this[key] = value;
265
+ }
266
+ }
267
+ /**
268
+ * Wrapper around requestHandler that opens and closes pages etc.
269
+ */
270
+ async _runRequestHandler(crawlingContext) {
271
+ const { request, session } = crawlingContext;
272
+ if (this.proxyConfiguration) {
273
+ const sessionId = session ? session.id : undefined;
274
+ crawlingContext.proxyInfo = await this.proxyConfiguration.newProxyInfo(sessionId);
275
+ }
276
+ if (!request.skipNavigation) {
277
+ await this._handleNavigation(crawlingContext);
278
+ (0, timeout_1.tryCancel)();
279
+ const parsed = await this._parseResponse(request, crawlingContext.response, crawlingContext);
280
+ const response = parsed.response;
281
+ const contentType = parsed.contentType;
282
+ (0, timeout_1.tryCancel)();
283
+ if (this.useSessionPool) {
284
+ this._throwOnBlockedRequest(session, response.statusCode);
285
+ }
286
+ if (this.persistCookiesPerSession) {
287
+ session.setCookiesFromResponse(response);
288
+ }
289
+ request.loadedUrl = response.url;
290
+ Object.assign(crawlingContext, parsed);
291
+ Object.defineProperty(crawlingContext, 'json', {
292
+ get() {
293
+ if (contentType.type !== APPLICATION_JSON_MIME_TYPE)
294
+ return null;
295
+ const jsonString = parsed.body.toString(contentType.encoding);
296
+ return JSON.parse(jsonString);
297
+ },
298
+ });
299
+ }
300
+ return (0, timeout_1.addTimeoutToPromise)(() => Promise.resolve(this.requestHandler(crawlingContext)), this.userRequestHandlerTimeoutMillis, `requestHandler timed out after ${this.userRequestHandlerTimeoutMillis / 1000} seconds.`);
301
+ }
302
+ async _handleNavigation(crawlingContext) {
303
+ const gotOptions = {};
304
+ const { request, session } = crawlingContext;
305
+ const preNavigationHooksCookies = this._getCookieHeaderFromRequest(request);
306
+ // Execute pre navigation hooks before applying session pool cookies,
307
+ // as they may also set cookies in the session
308
+ await this._executeHooks(this.preNavigationHooks, crawlingContext, gotOptions);
309
+ (0, timeout_1.tryCancel)();
310
+ const postNavigationHooksCookies = this._getCookieHeaderFromRequest(request);
311
+ this._applyCookies(crawlingContext, gotOptions, preNavigationHooksCookies, postNavigationHooksCookies);
312
+ const proxyUrl = crawlingContext.proxyInfo?.url;
313
+ crawlingContext.response = await (0, timeout_1.addTimeoutToPromise)(() => this._requestFunction({ request, session, proxyUrl, gotOptions }), this.navigationTimeoutMillis, `request timed out after ${this.navigationTimeoutMillis / 1000} seconds.`);
314
+ (0, timeout_1.tryCancel)();
315
+ await this._executeHooks(this.postNavigationHooks, crawlingContext, gotOptions);
316
+ (0, timeout_1.tryCancel)();
317
+ }
318
+ /**
319
+ * Sets the cookie header to `gotOptions` based on the provided request and session headers, as well as any changes that occurred due to hooks.
320
+ */
321
+ _applyCookies({ session, request }, gotOptions, preHookCookies, postHookCookies) {
322
+ const sessionCookie = session?.getCookieString(request.url) ?? '';
323
+ let alteredGotOptionsCookies = (gotOptions.headers?.Cookie || gotOptions.headers?.cookie || '');
324
+ if (gotOptions.headers?.Cookie && gotOptions.headers?.cookie) {
325
+ const { Cookie: upperCaseHeader, cookie: lowerCaseHeader, } = gotOptions.headers;
326
+ // eslint-disable-next-line max-len
327
+ this.log.warning(`Encountered mixed casing for the cookie headers in the got options for request ${request.url} (${request.id}). Their values will be merged`);
328
+ const sourceCookies = [];
329
+ if (Array.isArray(lowerCaseHeader)) {
330
+ sourceCookies.push(...lowerCaseHeader);
331
+ }
332
+ else {
333
+ sourceCookies.push(lowerCaseHeader);
334
+ }
335
+ if (Array.isArray(upperCaseHeader)) {
336
+ sourceCookies.push(...upperCaseHeader);
337
+ }
338
+ else {
339
+ sourceCookies.push(upperCaseHeader);
340
+ }
341
+ alteredGotOptionsCookies = (0, basic_1.mergeCookies)(request.url, sourceCookies);
342
+ }
343
+ const sourceCookies = [
344
+ sessionCookie,
345
+ preHookCookies,
346
+ ];
347
+ if (Array.isArray(alteredGotOptionsCookies)) {
348
+ sourceCookies.push(...alteredGotOptionsCookies);
349
+ }
350
+ else {
351
+ sourceCookies.push(alteredGotOptionsCookies);
352
+ }
353
+ sourceCookies.push(postHookCookies);
354
+ const mergedCookie = (0, basic_1.mergeCookies)(request.url, sourceCookies);
355
+ gotOptions.headers ?? (gotOptions.headers = {});
356
+ Reflect.deleteProperty(gotOptions.headers, 'Cookie');
357
+ Reflect.deleteProperty(gotOptions.headers, 'cookie');
358
+ gotOptions.headers.Cookie = mergedCookie;
359
+ }
360
+ /**
361
+ * Function to make the HTTP request. It performs optimizations
362
+ * on the request such as only downloading the request body if the
363
+ * received content type matches text/html, application/xml, application/xhtml+xml.
364
+ */
365
+ async _requestFunction({ request, session, proxyUrl, gotOptions }) {
366
+ const opts = this._getRequestOptions(request, session, proxyUrl, gotOptions);
367
+ try {
368
+ return await this._requestAsBrowser(opts);
369
+ }
370
+ catch (e) {
371
+ if (e instanceof got_scraping_1.TimeoutError) {
372
+ this._handleRequestTimeout(session);
373
+ return undefined;
374
+ }
375
+ throw e;
376
+ }
377
+ }
378
+ /**
379
+ * Encodes and parses response according to the provided content type
380
+ */
381
+ async _parseResponse(request, responseStream, crawlingContext) {
382
+ const { statusCode } = responseStream;
383
+ const { type, charset } = parseContentTypeFromResponse(responseStream);
384
+ const { response, encoding } = this._encodeResponse(request, responseStream, charset);
385
+ const contentType = { type, encoding };
386
+ if (statusCode >= 500) {
387
+ const body = await (0, utilities_1.readStreamToString)(response, encoding);
388
+ // Errors are often sent as JSON, so attempt to parse them,
389
+ // despite Accept header being set to text/html.
390
+ if (type === APPLICATION_JSON_MIME_TYPE) {
391
+ const errorResponse = JSON.parse(body);
392
+ let { message } = errorResponse;
393
+ if (!message)
394
+ message = node_util_1.default.inspect(errorResponse, { depth: 1, maxArrayLength: 10 });
395
+ throw new Error(`${statusCode} - ${message}`);
396
+ }
397
+ // It's not a JSON, so it's probably some text. Get the first 100 chars of it.
398
+ throw new Error(`${statusCode} - Internal Server Error: ${body.slice(0, 100)}`);
399
+ }
400
+ else if (HTML_AND_XML_MIME_TYPES.includes(type)) {
401
+ const isXml = type.includes('xml');
402
+ const parsed = await this._parseHTML(response, isXml, crawlingContext);
403
+ return { ...parsed, isXml, response, contentType };
404
+ }
405
+ else {
406
+ const body = await (0, utilities_1.concatStreamToBuffer)(response);
407
+ return { body, response, contentType };
408
+ }
409
+ }
410
+ async _parseHTML(response, _isXml, _crawlingContext) {
411
+ return {
412
+ body: await (0, utilities_1.concatStreamToBuffer)(response),
413
+ };
414
+ }
415
+ /**
416
+ * Combines the provided `requestOptions` with mandatory (non-overridable) values.
417
+ */
418
+ _getRequestOptions(request, session, proxyUrl, gotOptions) {
419
+ const requestOptions = {
420
+ url: request.url,
421
+ method: request.method,
422
+ proxyUrl,
423
+ timeout: { request: this.navigationTimeoutMillis },
424
+ sessionToken: session,
425
+ ...gotOptions,
426
+ headers: { ...request.headers, ...gotOptions?.headers },
427
+ https: {
428
+ ...gotOptions?.https,
429
+ rejectUnauthorized: !this.ignoreSslErrors,
430
+ },
431
+ isStream: true,
432
+ };
433
+ // Delete any possible lowercased header for cookie as they are merged in _applyCookies under the uppercase Cookie header
434
+ Reflect.deleteProperty(requestOptions.headers, 'cookie');
435
+ // TODO this is incorrect, the check for man in the middle needs to be done
436
+ // on individual proxy level, not on the `proxyConfiguration` level,
437
+ // because users can use normal + MITM proxies in a single configuration.
438
+ // Disable SSL verification for MITM proxies
439
+ if (this.proxyConfiguration && this.proxyConfiguration.isManInTheMiddle) {
440
+ requestOptions.https = {
441
+ ...requestOptions.https,
442
+ rejectUnauthorized: false,
443
+ };
444
+ }
445
+ if (/PATCH|POST|PUT/.test(request.method))
446
+ requestOptions.body = request.payload;
447
+ return requestOptions;
448
+ }
449
+ _encodeResponse(request, response, encoding) {
450
+ if (this.forceResponseEncoding) {
451
+ encoding = this.forceResponseEncoding;
452
+ }
453
+ else if (!encoding && this.suggestResponseEncoding) {
454
+ encoding = this.suggestResponseEncoding;
455
+ }
456
+ // Fall back to utf-8 if we still don't have encoding.
457
+ const utf8 = 'utf8';
458
+ if (!encoding)
459
+ return { response, encoding: utf8 };
460
+ // This means that the encoding is one of Node.js supported
461
+ // encodings and we don't need to re-encode it.
462
+ if (Buffer.isEncoding(encoding))
463
+ return { response, encoding };
464
+ // Try to re-encode a variety of unsupported encodings to utf-8
465
+ if (iconv_lite_1.default.encodingExists(encoding)) {
466
+ const encodeStream = iconv_lite_1.default.encodeStream(utf8);
467
+ const decodeStream = iconv_lite_1.default.decodeStream(encoding).on('error', (err) => encodeStream.emit('error', err));
468
+ response.on('error', (err) => decodeStream.emit('error', err));
469
+ const encodedResponse = response.pipe(decodeStream).pipe(encodeStream);
470
+ encodedResponse.statusCode = response.statusCode;
471
+ encodedResponse.headers = response.headers;
472
+ encodedResponse.url = response.url;
473
+ return {
474
+ response: encodedResponse,
475
+ encoding: utf8,
476
+ };
477
+ }
478
+ throw new Error(`Resource ${request.url} served with unsupported charset/encoding: ${encoding}`);
479
+ }
480
+ /**
481
+ * Checks and extends supported mime types
482
+ */
483
+ _extendSupportedMimeTypes(additionalMimeTypes) {
484
+ for (const mimeType of additionalMimeTypes) {
485
+ if (mimeType === '*/*') {
486
+ this.supportedMimeTypes.add(mimeType);
487
+ continue;
488
+ }
489
+ try {
490
+ const parsedType = content_type_1.default.parse(mimeType);
491
+ this.supportedMimeTypes.add(parsedType.type);
492
+ }
493
+ catch (err) {
494
+ throw new Error(`Can not parse mime type ${mimeType} from "options.additionalMimeTypes".`);
495
+ }
496
+ }
497
+ }
498
+ /**
499
+ * Handles timeout request
500
+ */
501
+ _handleRequestTimeout(session) {
502
+ session?.markBad();
503
+ throw new Error(`request timed out after ${this.requestHandlerTimeoutMillis / 1000} seconds.`);
504
+ }
505
+ _abortDownloadOfBody(request, response) {
506
+ const { statusCode } = response;
507
+ const { type } = parseContentTypeFromResponse(response);
508
+ if (statusCode === 406) {
509
+ request.noRetry = true;
510
+ throw new Error(`Resource ${request.url} is not available in the format requested by the Accept header. Skipping resource.`);
511
+ }
512
+ if (!this.supportedMimeTypes.has(type) && !this.supportedMimeTypes.has('*/*') && statusCode < 500) {
513
+ request.noRetry = true;
514
+ throw new Error(`Resource ${request.url} served Content-Type ${type}, `
515
+ + `but only ${Array.from(this.supportedMimeTypes).join(', ')} are allowed. Skipping resource.`);
516
+ }
517
+ }
518
+ }
519
+ exports.HttpCrawler = HttpCrawler;
520
+ Object.defineProperty(HttpCrawler, "optionsShape", {
521
+ enumerable: true,
522
+ configurable: true,
523
+ writable: true,
524
+ value: {
525
+ ...basic_1.BasicCrawler.optionsShape,
526
+ handlePageFunction: ow_1.default.optional.function,
527
+ navigationTimeoutSecs: ow_1.default.optional.number,
528
+ ignoreSslErrors: ow_1.default.optional.boolean,
529
+ additionalMimeTypes: ow_1.default.optional.array.ofType(ow_1.default.string),
530
+ suggestResponseEncoding: ow_1.default.optional.string,
531
+ forceResponseEncoding: ow_1.default.optional.string,
532
+ proxyConfiguration: ow_1.default.optional.object.validate(basic_1.validators.proxyConfiguration),
533
+ persistCookiesPerSession: ow_1.default.optional.boolean,
534
+ preNavigationHooks: ow_1.default.optional.array,
535
+ postNavigationHooks: ow_1.default.optional.array,
536
+ }
537
+ });
538
+ /**
539
+ * The stream object returned from got does not have the below properties.
540
+ * At the same time, you can't read data directly from the response stream,
541
+ * because they won't get emitted unless you also read from the primary
542
+ * got stream. To be able to work with only one stream, we move the expected props
543
+ * from the response stream to the got stream.
544
+ * @internal
545
+ */
546
+ function addResponsePropertiesToStream(stream) {
547
+ const properties = [
548
+ 'statusCode', 'statusMessage', 'headers',
549
+ 'complete', 'httpVersion', 'rawHeaders',
550
+ 'rawTrailers', 'trailers', 'url',
551
+ 'request',
552
+ ];
553
+ const response = stream.response;
554
+ response.on('end', () => {
555
+ // @ts-expect-error
556
+ Object.assign(stream.rawTrailers, response.rawTrailers);
557
+ // @ts-expect-error
558
+ Object.assign(stream.trailers, response.trailers);
559
+ // @ts-expect-error
560
+ stream.complete = response.complete;
561
+ });
562
+ for (const prop of properties) {
563
+ if (!(prop in stream)) {
564
+ // @ts-expect-error
565
+ stream[prop] = response[prop];
566
+ }
567
+ }
568
+ return stream;
569
+ }
570
+ /**
571
+ * Gets parsed content type from response object
572
+ * @param response HTTP response object
573
+ */
574
+ function parseContentTypeFromResponse(response) {
575
+ (0, ow_1.default)(response, ow_1.default.object.partialShape({
576
+ url: ow_1.default.string.url,
577
+ headers: ow_1.default.object,
578
+ }));
579
+ const { url, headers } = response;
580
+ let parsedContentType;
581
+ if (headers['content-type']) {
582
+ try {
583
+ parsedContentType = content_type_1.default.parse(headers['content-type']);
584
+ }
585
+ catch {
586
+ // Can not parse content type from Content-Type header. Try to parse it from file extension.
587
+ }
588
+ }
589
+ // Parse content type from file extension as fallback
590
+ if (!parsedContentType) {
591
+ const parsedUrl = new URL(url);
592
+ const contentTypeFromExtname = mime_types_1.default.contentType((0, path_1.extname)(parsedUrl.pathname))
593
+ || 'application/octet-stream; charset=utf-8'; // Fallback content type, specified in https://tools.ietf.org/html/rfc7231#section-3.1.1.5
594
+ parsedContentType = content_type_1.default.parse(contentTypeFromExtname);
595
+ }
596
+ return {
597
+ type: parsedContentType.type,
598
+ charset: parsedContentType.parameters.charset,
599
+ };
600
+ }
601
+ /**
602
+ * Creates new {@apilink Router} instance that works based on request labels.
603
+ * This instance can then serve as a `requestHandler` of your {@apilink HttpCrawler}.
604
+ * Defaults to the {@apilink HttpCrawlingContext}.
605
+ *
606
+ * > Serves as a shortcut for using `Router.create<HttpCrawlingContext>()`.
607
+ *
608
+ * ```ts
609
+ * import { HttpCrawler, createHttpRouter } from 'crawlee';
610
+ *
611
+ * const router = createHttpRouter();
612
+ * router.addHandler('label-a', async (ctx) => {
613
+ * ctx.log.info('...');
614
+ * });
615
+ * router.addDefaultHandler(async (ctx) => {
616
+ * ctx.log.info('...');
617
+ * });
618
+ *
619
+ * const crawler = new HttpCrawler({
620
+ * requestHandler: router,
621
+ * });
622
+ * await crawler.run();
623
+ * ```
624
+ */
625
+ function createHttpRouter() {
626
+ return basic_1.Router.create();
627
+ }
628
+ exports.createHttpRouter = createHttpRouter;
629
+ //# sourceMappingURL=http-crawler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-crawler.js","sourceRoot":"","sources":["../../src/internals/http-crawler.ts"],"names":[],"mappings":"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"}