1 |
|
2 |
|
3 |
|
4 | import * as http from "http";
|
5 | import * as https from "https";
|
6 | import * as tunnel from "tunnel";
|
7 |
|
8 | import { ProxySettings } from "./serviceClient";
|
9 | import { URLBuilder } from "./url";
|
10 | import { HttpHeadersLike } from "./httpHeaders";
|
11 |
|
12 | export type ProxyAgent = { isHttps: boolean; agent: http.Agent | https.Agent };
|
13 | export function createProxyAgent(
|
14 | requestUrl: string,
|
15 | proxySettings: ProxySettings,
|
16 | headers?: HttpHeadersLike
|
17 | ): ProxyAgent {
|
18 | const tunnelOptions: tunnel.HttpsOverHttpsOptions = {
|
19 | proxy: {
|
20 | host: URLBuilder.parse(proxySettings.host).getHost() as string,
|
21 | port: proxySettings.port,
|
22 | headers: (headers && headers.rawHeaders()) || {},
|
23 | },
|
24 | };
|
25 |
|
26 | if (proxySettings.username && proxySettings.password) {
|
27 | tunnelOptions.proxy!.proxyAuth = `${proxySettings.username}:${proxySettings.password}`;
|
28 | } else if (proxySettings.username) {
|
29 | tunnelOptions.proxy!.proxyAuth = `${proxySettings.username}`;
|
30 | }
|
31 |
|
32 | const requestScheme = URLBuilder.parse(requestUrl).getScheme() || "";
|
33 | const isRequestHttps = requestScheme.toLowerCase() === "https";
|
34 | const proxyScheme = URLBuilder.parse(proxySettings.host).getScheme() || "";
|
35 | const isProxyHttps = proxyScheme.toLowerCase() === "https";
|
36 |
|
37 | const proxyAgent = {
|
38 | isHttps: isRequestHttps,
|
39 | agent: createTunnel(isRequestHttps, isProxyHttps, tunnelOptions),
|
40 | };
|
41 |
|
42 | return proxyAgent;
|
43 | }
|
44 |
|
45 |
|
46 |
|
47 | export interface HttpsProxyOptions {
|
48 | host: string;
|
49 | port: number;
|
50 | localAddress?: string;
|
51 | proxyAuth?: string;
|
52 | headers?: { [key: string]: any };
|
53 | ca?: Buffer[];
|
54 | servername?: string;
|
55 | key?: Buffer;
|
56 | cert?: Buffer;
|
57 | }
|
58 |
|
59 | interface HttpsOverHttpsOptions {
|
60 | maxSockets?: number;
|
61 | ca?: Buffer[];
|
62 | key?: Buffer;
|
63 | cert?: Buffer;
|
64 | proxy?: HttpsProxyOptions;
|
65 | }
|
66 |
|
67 | export function createTunnel(
|
68 | isRequestHttps: boolean,
|
69 | isProxyHttps: boolean,
|
70 | tunnelOptions: HttpsOverHttpsOptions
|
71 | ): http.Agent | https.Agent {
|
72 | if (isRequestHttps && isProxyHttps) {
|
73 | return tunnel.httpsOverHttps(tunnelOptions);
|
74 | } else if (isRequestHttps && !isProxyHttps) {
|
75 | return tunnel.httpsOverHttp(tunnelOptions);
|
76 | } else if (!isRequestHttps && isProxyHttps) {
|
77 | return tunnel.httpOverHttps(tunnelOptions);
|
78 | } else {
|
79 | return tunnel.httpOverHttp(tunnelOptions);
|
80 | }
|
81 | }
|