Skip to content

Commit d6e2974

Browse files
authored
fix: patch GotScrapingHttpClient header handling and proxies (#3308)
Fixes the response header handling in `GotScrapingHttpClient` (`got-scraping` headers contain unexpected `Symbol`s and HTTP2 pseudoheaders). Fixes omission from one of the previous commits - `GotScrapingHttpClient.stream` now uses proxy correctly again. Closes #2917
1 parent 9fc056d commit d6e2974

2 files changed

Lines changed: 32 additions & 14 deletions

File tree

packages/core/src/http_clients/got-scraping-http-client.ts

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,29 @@ export class GotScrapingHttpClient implements BaseHttpClient {
2020
return !['CONNECT', 'connect'].includes(request.method!);
2121
}
2222

23+
private *iterateHeaders(
24+
headers: Record<string, string | string[] | undefined>,
25+
): Generator<[string, string], void, unknown> {
26+
for (const [key, value] of Object.entries(headers)) {
27+
// Filter out pseudo-headers
28+
if (key.startsWith(':') || value === undefined) {
29+
continue;
30+
}
31+
32+
if (Array.isArray(value)) {
33+
for (const v of value) {
34+
yield [key, v];
35+
}
36+
} else {
37+
yield [key, value];
38+
}
39+
}
40+
}
41+
42+
private parseHeaders(headers: Record<string, string | string[] | undefined>): Headers {
43+
return new Headers([...this.iterateHeaders(headers)]);
44+
}
45+
2346
/**
2447
* @inheritDoc
2548
*/
@@ -43,20 +66,10 @@ export class GotScrapingHttpClient implements BaseHttpClient {
4366
cookieJar: undefined,
4467
});
4568

46-
const parsedHeaders = Object.entries(gotResult.headers)
47-
.map(([key, value]) => {
48-
if (value === undefined) return [];
49-
50-
if (Array.isArray(value)) {
51-
return value.map((v) => [key, v]);
52-
}
53-
54-
return [[key, value]];
55-
})
56-
.flat() as [string, string][];
69+
const responseHeaders = this.parseHeaders(gotResult.headers);
5770

5871
return new ResponseWithUrl(new Uint8Array(gotResult.rawBody), {
59-
headers: new Headers(parsedHeaders),
72+
headers: responseHeaders,
6073
status: gotResult.statusCode,
6174
statusText: gotResult.statusMessage ?? '',
6275
url: gotResult.url,
@@ -67,6 +80,8 @@ export class GotScrapingHttpClient implements BaseHttpClient {
6780
* @inheritDoc
6881
*/
6982
async stream(request: Request, options?: StreamOptions): Promise<Response> {
83+
const { session, timeout } = options ?? {};
84+
7085
if (!this.validateRequest(request)) {
7186
throw new Error(`The HTTP method CONNECT is not supported by the GotScrapingHttpClient.`);
7287
}
@@ -78,6 +93,8 @@ export class GotScrapingHttpClient implements BaseHttpClient {
7893
headers: Object.fromEntries(request.headers.entries()),
7994
body: request.body ? Readable.fromWeb(request.body as any) : undefined,
8095
isStream: true,
96+
proxyUrl: session?.proxyInfo?.url,
97+
timeout: { request: timeout },
8198
cookieJar: undefined,
8299
});
83100

@@ -111,12 +128,13 @@ export class GotScrapingHttpClient implements BaseHttpClient {
111128
stream.on('error', reject);
112129

113130
stream.on('response', (response: PlainResponse) => {
131+
const headers = this.parseHeaders(response.headers);
114132
// Cast shouldn't be needed here, undici might have a different `ReadableStream` type
115133
resolve(
116134
new ResponseWithUrl(Readable.toWeb(stream) as any, {
117135
status: response.statusCode,
118136
statusText: response.statusMessage ?? '',
119-
headers: response.headers as HeadersInit,
137+
headers,
120138
url: response.url,
121139
}),
122140
);

packages/http-crawler/src/internals/http-crawler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ export class HttpCrawler<
686686
url: request.url,
687687
method: request.method,
688688
proxyUrl,
689-
timeout: { request: this.navigationTimeoutMillis },
689+
timeout: this.navigationTimeoutMillis,
690690
cookieJar: this.persistCookiesPerSession ? session?.cookieJar : undefined,
691691
sessionToken: session,
692692
headers: request.headers,

0 commit comments

Comments
 (0)