blob: cf95ab2a0e583b2d964e55fe4ca9aa64d1d90d86 [file] [log] [blame]
Randolf Jungbcb3bc82023-06-26 16:30:141/**
2 * Copyright 2023 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import { createWriteStream } from 'fs';
17import * as http from 'http';
18import * as https from 'https';
19import { URL, urlToHttpOptions } from 'url';
Randolf Jung3e526312023-08-08 06:20:3920import { ProxyAgent } from 'proxy-agent';
Randolf Jungbcb3bc82023-06-26 16:30:1421export function headHttpRequest(url) {
22 return new Promise(resolve => {
23 const request = httpRequest(url, 'HEAD', response => {
Randolf Jung3e526312023-08-08 06:20:3924 // consume response data free node process
25 response.resume();
Randolf Jungbcb3bc82023-06-26 16:30:1426 resolve(response.statusCode === 200);
27 }, false);
28 request.on('error', () => {
29 resolve(false);
30 });
31 });
32}
33export function httpRequest(url, method, response, keepAlive = true) {
34 const options = {
35 protocol: url.protocol,
36 hostname: url.hostname,
37 port: url.port,
38 path: url.pathname + url.search,
39 method,
40 headers: keepAlive ? { Connection: 'keep-alive' } : undefined,
41 auth: urlToHttpOptions(url).auth,
Randolf Jung3e526312023-08-08 06:20:3942 agent: new ProxyAgent(),
Randolf Jungbcb3bc82023-06-26 16:30:1443 };
44 const requestCallback = (res) => {
45 if (res.statusCode &&
46 res.statusCode >= 300 &&
47 res.statusCode < 400 &&
48 res.headers.location) {
49 httpRequest(new URL(res.headers.location), method, response);
50 }
51 else {
52 response(res);
53 }
54 };
55 const request = options.protocol === 'https:'
56 ? https.request(options, requestCallback)
57 : http.request(options, requestCallback);
58 request.end();
59 return request;
60}
61/**
62 * @internal
63 */
64export function downloadFile(url, destinationPath, progressCallback) {
65 return new Promise((resolve, reject) => {
66 let downloadedBytes = 0;
67 let totalBytes = 0;
68 function onData(chunk) {
69 downloadedBytes += chunk.length;
70 progressCallback(downloadedBytes, totalBytes);
71 }
72 const request = httpRequest(url, 'GET', response => {
73 if (response.statusCode !== 200) {
74 const error = new Error(`Download failed: server returned code ${response.statusCode}. URL: ${url}`);
75 // consume response data to free up memory
76 response.resume();
77 reject(error);
78 return;
79 }
80 const file = createWriteStream(destinationPath);
81 file.on('finish', () => {
82 return resolve();
83 });
84 file.on('error', error => {
85 return reject(error);
86 });
87 response.pipe(file);
88 totalBytes = parseInt(response.headers['content-length'], 10);
89 if (progressCallback) {
90 response.on('data', onData);
91 }
92 });
93 request.on('error', error => {
94 return reject(error);
95 });
96 });
97}
98export async function getJSON(url) {
99 const text = await getText(url);
100 try {
101 return JSON.parse(text);
102 }
103 catch {
104 throw new Error('Could not parse JSON from ' + url.toString());
105 }
106}
107export function getText(url) {
108 return new Promise((resolve, reject) => {
109 const request = httpRequest(url, 'GET', response => {
110 let data = '';
111 if (response.statusCode && response.statusCode >= 400) {
112 return reject(new Error(`Got status code ${response.statusCode}`));
113 }
114 response.on('data', chunk => {
115 data += chunk;
116 });
117 response.on('end', () => {
118 try {
119 return resolve(String(data));
120 }
121 catch {
122 return reject(new Error('Chrome version not found'));
123 }
124 });
125 }, false);
126 request.on('error', err => {
127 reject(err);
128 });
129 });
130}
131//# sourceMappingURL=httpUtil.js.map