mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	chore: improve http request utilities (#9031)
This commit is contained in:
		
							parent
							
								
									e5b8c02c93
								
							
						
					
					
						commit
						5200134749
					
				@ -605,7 +605,7 @@ export class Registry {
 | 
			
		||||
  private async _installMSEdgeChannel(channel: 'msedge'|'msedge-beta'|'msedge-dev', scripts: Record<'linux' | 'darwin' | 'win32', string>) {
 | 
			
		||||
    const scriptArgs: string[] = [];
 | 
			
		||||
    if (process.platform !== 'linux') {
 | 
			
		||||
      const products = JSON.parse(await fetchData('https://edgeupdates.microsoft.com/api/products'));
 | 
			
		||||
      const products = JSON.parse(await fetchData({ url: 'https://edgeupdates.microsoft.com/api/products' }));
 | 
			
		||||
      const productName = {
 | 
			
		||||
        'msedge': 'Stable',
 | 
			
		||||
        'msedge-beta': 'Beta',
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,8 @@ import stream from 'stream';
 | 
			
		||||
import removeFolder from 'rimraf';
 | 
			
		||||
import * as crypto from 'crypto';
 | 
			
		||||
import os from 'os';
 | 
			
		||||
import http from 'http';
 | 
			
		||||
import https from 'https';
 | 
			
		||||
import { spawn, SpawnOptions } from 'child_process';
 | 
			
		||||
import { getProxyForUrl } from 'proxy-from-env';
 | 
			
		||||
import * as URL from 'url';
 | 
			
		||||
@ -37,53 +39,63 @@ const ProxyAgent = require('https-proxy-agent');
 | 
			
		||||
 | 
			
		||||
export const existsAsync = (path: string): Promise<boolean> => new Promise(resolve => fs.stat(path, err => resolve(!err)));
 | 
			
		||||
 | 
			
		||||
function httpRequest(url: string, method: string, response: (r: any) => void) {
 | 
			
		||||
  let options: any = URL.parse(url);
 | 
			
		||||
  options.method = method;
 | 
			
		||||
type HTTPRequestParams = {
 | 
			
		||||
  url: string,
 | 
			
		||||
  method?: string,
 | 
			
		||||
  headers?: http.OutgoingHttpHeaders,
 | 
			
		||||
  data?: string | Buffer,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  const proxyURL = getProxyForUrl(url);
 | 
			
		||||
function httpRequest(params: HTTPRequestParams, onResponse: (r: http.IncomingMessage) => void, onError: (error: Error) => void) {
 | 
			
		||||
  const parsedUrl = URL.parse(params.url);
 | 
			
		||||
  let options: https.RequestOptions = { ...parsedUrl };
 | 
			
		||||
  options.method = params.method || 'GET';
 | 
			
		||||
  options.headers = params.headers;
 | 
			
		||||
 | 
			
		||||
  const proxyURL = getProxyForUrl(params.url);
 | 
			
		||||
  if (proxyURL) {
 | 
			
		||||
    if (url.startsWith('http:')) {
 | 
			
		||||
    if (params.url.startsWith('http:')) {
 | 
			
		||||
      const proxy = URL.parse(proxyURL);
 | 
			
		||||
      options = {
 | 
			
		||||
        path: options.href,
 | 
			
		||||
        path: parsedUrl.href,
 | 
			
		||||
        host: proxy.hostname,
 | 
			
		||||
        port: proxy.port,
 | 
			
		||||
      };
 | 
			
		||||
    } else {
 | 
			
		||||
      const parsedProxyURL: any = URL.parse(proxyURL);
 | 
			
		||||
      parsedProxyURL.secureProxy = parsedProxyURL.protocol === 'https:';
 | 
			
		||||
      const parsedProxyURL = URL.parse(proxyURL);
 | 
			
		||||
      (parsedProxyURL as any).secureProxy = parsedProxyURL.protocol === 'https:';
 | 
			
		||||
 | 
			
		||||
      options.agent = new ProxyAgent(parsedProxyURL);
 | 
			
		||||
      options.rejectUnauthorized = false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const requestCallback = (res: any) => {
 | 
			
		||||
    if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location)
 | 
			
		||||
      httpRequest(res.headers.location, method, response);
 | 
			
		||||
  const requestCallback = (res: http.IncomingMessage) => {
 | 
			
		||||
    const statusCode = res.statusCode || 0;
 | 
			
		||||
    if (statusCode >= 300 && statusCode < 400 && res.headers.location)
 | 
			
		||||
      httpRequest({ ...params, url: res.headers.location }, onResponse, onError);
 | 
			
		||||
    else
 | 
			
		||||
      response(res);
 | 
			
		||||
      onResponse(res);
 | 
			
		||||
  };
 | 
			
		||||
  const request = options.protocol === 'https:' ?
 | 
			
		||||
    require('https').request(options, requestCallback) :
 | 
			
		||||
    require('http').request(options, requestCallback);
 | 
			
		||||
  request.end();
 | 
			
		||||
  return request;
 | 
			
		||||
    https.request(options, requestCallback) :
 | 
			
		||||
    http.request(options, requestCallback);
 | 
			
		||||
  request.on('error', onError);
 | 
			
		||||
  request.end(params.data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function fetchData(url: string): Promise<string> {
 | 
			
		||||
export function fetchData(params: HTTPRequestParams): Promise<string> {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    httpRequest(url, 'GET', function(response){
 | 
			
		||||
    httpRequest(params, response => {
 | 
			
		||||
      if (response.statusCode !== 200) {
 | 
			
		||||
        reject(new Error(`fetch failed: server returned code ${response.statusCode}. URL: ${url}`));
 | 
			
		||||
        reject(new Error(`fetch failed: server returned code ${response.statusCode}. URL: ${params.url}`));
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      let body = '';
 | 
			
		||||
      response.on('data', (chunk: string) => body += chunk);
 | 
			
		||||
      response.on('error', (error: any) => reject(error));
 | 
			
		||||
      response.on('end', () => resolve(body));
 | 
			
		||||
    }).on('error', (error: any) => reject(error));
 | 
			
		||||
    }, reject);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -104,7 +116,7 @@ export function downloadFile(url: string, destinationPath: string, options: {pro
 | 
			
		||||
 | 
			
		||||
  const promise: Promise<{error: any}> = new Promise(x => { fulfill = x; });
 | 
			
		||||
 | 
			
		||||
  const request = httpRequest(url, 'GET', response => {
 | 
			
		||||
  httpRequest({ url }, response => {
 | 
			
		||||
    log(`-- response status code: ${response.statusCode}`);
 | 
			
		||||
    if (response.statusCode !== 200) {
 | 
			
		||||
      const error = new Error(`Download failed: server returned code ${response.statusCode}. URL: ${url}`);
 | 
			
		||||
@ -117,12 +129,11 @@ export function downloadFile(url: string, destinationPath: string, options: {pro
 | 
			
		||||
    file.on('finish', () => fulfill({error: null}));
 | 
			
		||||
    file.on('error', error => fulfill({error}));
 | 
			
		||||
    response.pipe(file);
 | 
			
		||||
    totalBytes = parseInt(response.headers['content-length'], 10);
 | 
			
		||||
    totalBytes = parseInt(response.headers['content-length'] || '0', 10);
 | 
			
		||||
    log(`-- total bytes: ${totalBytes}`);
 | 
			
		||||
    if (progressCallback)
 | 
			
		||||
      response.on('data', onData);
 | 
			
		||||
  });
 | 
			
		||||
  request.on('error', (error: any) => fulfill({error}));
 | 
			
		||||
  }, (error: any) => fulfill({error}));
 | 
			
		||||
  return promise;
 | 
			
		||||
 | 
			
		||||
  function onData(chunk: string) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user