UNPKG

3.05 kBPlain TextView Raw
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License. See License.txt in the project root for license information.
3
4import * as tough from "tough-cookie";
5import * as http from "http";
6import * as https from "https";
7import node_fetch from "node-fetch";
8
9import {
10 CommonRequestInfo,
11 CommonRequestInit,
12 CommonResponse,
13 FetchHttpClient,
14} from "./fetchHttpClient";
15import { HttpOperationResponse } from "./httpOperationResponse";
16import { WebResourceLike } from "./webResource";
17import { createProxyAgent, ProxyAgent } from "./proxyAgent";
18
19export class NodeFetchHttpClient extends FetchHttpClient {
20 private readonly cookieJar = new tough.CookieJar(undefined, { looseMode: true });
21
22 async fetch(input: CommonRequestInfo, init?: CommonRequestInit): Promise<CommonResponse> {
23 return (node_fetch(input, init) as unknown) as Promise<CommonResponse>;
24 }
25
26 async prepareRequest(httpRequest: WebResourceLike): Promise<Partial<RequestInit>> {
27 const requestInit: Partial<RequestInit & { agent?: any }> = {};
28
29 if (this.cookieJar && !httpRequest.headers.get("Cookie")) {
30 const cookieString = await new Promise<string>((resolve, reject) => {
31 this.cookieJar!.getCookieString(httpRequest.url, (err, cookie) => {
32 if (err) {
33 reject(err);
34 } else {
35 resolve(cookie);
36 }
37 });
38 });
39
40 httpRequest.headers.set("Cookie", cookieString);
41 }
42
43 if (httpRequest.agentSettings) {
44 const { http: httpAgent, https: httpsAgent } = httpRequest.agentSettings;
45 if (httpsAgent && httpRequest.url.startsWith("https")) {
46 requestInit.agent = httpsAgent;
47 } else if (httpAgent) {
48 requestInit.agent = httpAgent;
49 }
50 } else if (httpRequest.proxySettings) {
51 const tunnel: ProxyAgent = createProxyAgent(
52 httpRequest.url,
53 httpRequest.proxySettings,
54 httpRequest.headers
55 );
56 requestInit.agent = tunnel.agent;
57 }
58
59 if (httpRequest.keepAlive === true) {
60 if (requestInit.agent) {
61 requestInit.agent.keepAlive = true;
62 } else {
63 const options: http.AgentOptions | https.AgentOptions = { keepAlive: true };
64 const agent = httpRequest.url.startsWith("https")
65 ? new https.Agent(options)
66 : new http.Agent(options);
67 requestInit.agent = agent;
68 }
69 }
70
71 return requestInit;
72 }
73
74 async processRequest(operationResponse: HttpOperationResponse): Promise<void> {
75 if (this.cookieJar) {
76 const setCookieHeader = operationResponse.headers.get("Set-Cookie");
77 if (setCookieHeader != undefined) {
78 await new Promise((resolve, reject) => {
79 this.cookieJar!.setCookie(
80 setCookieHeader,
81 operationResponse.request.url,
82 { ignoreError: true },
83 (err) => {
84 if (err) {
85 reject(err);
86 } else {
87 resolve();
88 }
89 }
90 );
91 });
92 }
93 }
94 }
95}
96
\No newline at end of file