2022-03-07 10:12:26 +00:00
/ * *
* Copyright 2021 Google Inc . All rights reserved .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
import expect from 'expect' ;
import http from 'http' ;
import os from 'os' ;
import {
getTestState ,
describeFailsFirefox ,
itFailsWindows ,
} from './mocha-utils' ; // eslint-disable-line import/extensions
import type { Server , IncomingMessage , ServerResponse } from 'http' ;
import type { Browser } from '../lib/cjs/puppeteer/common/Browser.js' ;
import type { AddressInfo } from 'net' ;
const HOSTNAME = os . hostname ( ) . toLowerCase ( ) ;
/ * *
* Requests to localhost do not get proxied by default . Create a URL using the hostname
* instead .
* /
function getEmptyPageUrl ( server : { PORT : number ; EMPTY_PAGE : string } ) : string {
const emptyPagePath = new URL ( server . EMPTY_PAGE ) . pathname ;
return ` http:// ${ HOSTNAME } : ${ server . PORT } ${ emptyPagePath } ` ;
}
describeFailsFirefox ( 'request proxy' , ( ) = > {
let browser : Browser ;
let proxiedRequestUrls : string [ ] ;
let proxyServer : Server ;
let proxyServerUrl : string ;
2022-05-02 09:37:21 +00:00
const defaultArgs = [
'--disable-features=NetworkTimeServiceQuerying' , // We disable this in tests so that proxy-related tests don't intercept queries from this service in headful.
] ;
2022-03-07 10:12:26 +00:00
beforeEach ( ( ) = > {
proxiedRequestUrls = [ ] ;
proxyServer = http
. createServer (
(
originalRequest : IncomingMessage ,
originalResponse : ServerResponse
) = > {
proxiedRequestUrls . push ( originalRequest . url as string ) ;
const proxyRequest = http . request (
originalRequest . url as string ,
{
method : originalRequest.method ,
headers : originalRequest.headers ,
} ,
( proxyResponse ) = > {
originalResponse . writeHead (
proxyResponse . statusCode as number ,
proxyResponse . headers
) ;
proxyResponse . pipe ( originalResponse , { end : true } ) ;
}
) ;
originalRequest . pipe ( proxyRequest , { end : true } ) ;
}
)
. listen ( ) ;
proxyServerUrl = ` http:// ${ HOSTNAME } : ${
( proxyServer . address ( ) as AddressInfo ) . port
} ` ;
} ) ;
afterEach ( async ( ) = > {
await browser . close ( ) ;
await new Promise ( ( resolve , reject ) = > {
proxyServer . close ( ( error ) = > {
if ( error ) {
reject ( error ) ;
} else {
resolve ( undefined ) ;
}
} ) ;
} ) ;
} ) ;
it ( 'should proxy requests when configured' , async ( ) = > {
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
const emptyPageUrl = getEmptyPageUrl ( server ) ;
browser = await puppeteer . launch ( {
. . . defaultBrowserOptions ,
2022-05-02 09:37:21 +00:00
args : [ . . . defaultArgs , ` --proxy-server= ${ proxyServerUrl } ` ] ,
2022-03-07 10:12:26 +00:00
} ) ;
const page = await browser . newPage ( ) ;
const response = await page . goto ( emptyPageUrl ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ emptyPageUrl ] ) ;
} ) ;
it ( 'should respect proxy bypass list' , async ( ) = > {
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
const emptyPageUrl = getEmptyPageUrl ( server ) ;
browser = await puppeteer . launch ( {
. . . defaultBrowserOptions ,
args : [
2022-05-02 09:37:21 +00:00
. . . defaultArgs ,
2022-03-07 10:12:26 +00:00
` --proxy-server= ${ proxyServerUrl } ` ,
` --proxy-bypass-list= ${ new URL ( emptyPageUrl ) . host } ` ,
] ,
} ) ;
const page = await browser . newPage ( ) ;
const response = await page . goto ( emptyPageUrl ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ ] ) ;
} ) ;
describe ( 'in incognito browser context' , ( ) = > {
it ( 'should proxy requests when configured at browser level' , async ( ) = > {
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
const emptyPageUrl = getEmptyPageUrl ( server ) ;
browser = await puppeteer . launch ( {
. . . defaultBrowserOptions ,
2022-05-02 09:37:21 +00:00
args : [ . . . defaultArgs , ` --proxy-server= ${ proxyServerUrl } ` ] ,
2022-03-07 10:12:26 +00:00
} ) ;
const context = await browser . createIncognitoBrowserContext ( ) ;
const page = await context . newPage ( ) ;
const response = await page . goto ( emptyPageUrl ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ emptyPageUrl ] ) ;
} ) ;
it ( 'should respect proxy bypass list when configured at browser level' , async ( ) = > {
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
const emptyPageUrl = getEmptyPageUrl ( server ) ;
browser = await puppeteer . launch ( {
. . . defaultBrowserOptions ,
args : [
2022-05-02 09:37:21 +00:00
. . . defaultArgs ,
2022-03-07 10:12:26 +00:00
` --proxy-server= ${ proxyServerUrl } ` ,
` --proxy-bypass-list= ${ new URL ( emptyPageUrl ) . host } ` ,
] ,
} ) ;
const context = await browser . createIncognitoBrowserContext ( ) ;
const page = await context . newPage ( ) ;
const response = await page . goto ( emptyPageUrl ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ ] ) ;
} ) ;
/ * *
* See issues # 7873 , # 7719 , and # 7698 .
* /
itFailsWindows (
'should proxy requests when configured at context level' ,
async ( ) = > {
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
const emptyPageUrl = getEmptyPageUrl ( server ) ;
2022-05-02 09:37:21 +00:00
browser = await puppeteer . launch ( {
. . . defaultBrowserOptions ,
args : defaultArgs ,
} ) ;
2022-03-07 10:12:26 +00:00
const context = await browser . createIncognitoBrowserContext ( {
proxyServer : proxyServerUrl ,
} ) ;
const page = await context . newPage ( ) ;
const response = await page . goto ( emptyPageUrl ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ emptyPageUrl ] ) ;
}
) ;
it ( 'should respect proxy bypass list when configured at context level' , async ( ) = > {
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
const emptyPageUrl = getEmptyPageUrl ( server ) ;
2022-05-02 09:37:21 +00:00
browser = await puppeteer . launch ( {
. . . defaultBrowserOptions ,
args : defaultArgs ,
} ) ;
2022-03-07 10:12:26 +00:00
const context = await browser . createIncognitoBrowserContext ( {
proxyServer : proxyServerUrl ,
proxyBypassList : [ new URL ( emptyPageUrl ) . host ] ,
} ) ;
const page = await context . newPage ( ) ;
const response = await page . goto ( emptyPageUrl ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ ] ) ;
} ) ;
} ) ;
} ) ;