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 ,
2022-06-15 10:09:22 +00:00
} from './mocha-utils.js' ;
2022-06-22 13:25:44 +00:00
import type { Server , IncomingMessage , ServerResponse } from 'http' ;
import type { Browser } from '../../lib/cjs/puppeteer/common/Browser.js' ;
import type { AddressInfo } from 'net' ;
import { TestServer } from '../../utils/testserver/lib/index.js' ;
2022-03-07 10:12:26 +00:00
2022-08-08 14:31:12 +00:00
let HOSTNAME = os . hostname ( ) ;
// Hostname might not be always accessible in environments other than GitHub
// Actions. Therefore, we try to find an external IPv4 address to be used as a
// hostname in these tests.
const networkInterfaces = os . networkInterfaces ( ) ;
for ( const key of Object . keys ( networkInterfaces ) ) {
const interfaces = networkInterfaces [ key ] ;
for ( const net of interfaces || [ ] ) {
if ( net . family === 'IPv4' && ! net . internal ) {
HOSTNAME = net . address ;
break ;
}
}
}
2022-03-07 10:12:26 +00:00
/ * *
* Requests to localhost do not get proxied by default . Create a URL using the hostname
* instead .
* /
2022-06-15 10:05:25 +00:00
function getEmptyPageUrl ( server : TestServer ) : string {
2022-03-07 10:12:26 +00:00
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 ,
} ,
2022-06-22 13:25:44 +00:00
proxyResponse = > {
2022-03-07 10:12:26 +00:00
originalResponse . writeHead (
proxyResponse . statusCode as number ,
proxyResponse . headers
) ;
2022-06-22 13:25:44 +00:00
proxyResponse . pipe ( originalResponse , { end : true } ) ;
2022-03-07 10:12:26 +00:00
}
) ;
2022-06-22 13:25:44 +00:00
originalRequest . pipe ( proxyRequest , { end : true } ) ;
2022-03-07 10:12:26 +00:00
}
)
. listen ( ) ;
proxyServerUrl = ` http:// ${ HOSTNAME } : ${
( proxyServer . address ( ) as AddressInfo ) . port
} ` ;
} ) ;
afterEach ( async ( ) = > {
await browser . close ( ) ;
await new Promise ( ( resolve , reject ) = > {
2022-06-22 13:25:44 +00:00
proxyServer . close ( error = > {
2022-03-07 10:12:26 +00:00
if ( error ) {
reject ( error ) ;
} else {
resolve ( undefined ) ;
}
} ) ;
} ) ;
} ) ;
it ( 'should proxy requests when configured' , async ( ) = > {
2022-06-22 13:25:44 +00:00
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
2022-03-07 10:12:26 +00:00
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 ( ) ;
2022-06-15 10:09:22 +00:00
const response = ( await page . goto ( emptyPageUrl ) ) ! ;
2022-03-07 10:12:26 +00:00
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ emptyPageUrl ] ) ;
} ) ;
it ( 'should respect proxy bypass list' , async ( ) = > {
2022-06-22 13:25:44 +00:00
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
2022-03-07 10:12:26 +00:00
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 ( ) ;
2022-06-15 10:09:22 +00:00
const response = ( await page . goto ( emptyPageUrl ) ) ! ;
2022-03-07 10:12:26 +00:00
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ ] ) ;
} ) ;
describe ( 'in incognito browser context' , ( ) = > {
it ( 'should proxy requests when configured at browser level' , async ( ) = > {
2022-06-22 13:25:44 +00:00
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
2022-03-07 10:12:26 +00:00
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 ( ) ;
2022-06-15 10:09:22 +00:00
const response = ( await page . goto ( emptyPageUrl ) ) ! ;
2022-03-07 10:12:26 +00:00
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ emptyPageUrl ] ) ;
} ) ;
it ( 'should respect proxy bypass list when configured at browser level' , async ( ) = > {
2022-06-22 13:25:44 +00:00
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
2022-03-07 10:12:26 +00:00
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 ( ) ;
2022-06-15 10:09:22 +00:00
const response = ( await page . goto ( emptyPageUrl ) ) ! ;
2022-03-07 10:12:26 +00:00
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ ] ) ;
} ) ;
/ * *
* See issues # 7873 , # 7719 , and # 7698 .
* /
itFailsWindows (
'should proxy requests when configured at context level' ,
async ( ) = > {
2022-06-22 13:25:44 +00:00
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
2022-03-07 10:12:26 +00:00
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 ( ) ;
2022-06-15 10:09:22 +00:00
const response = ( await page . goto ( emptyPageUrl ) ) ! ;
2022-03-07 10:12:26 +00:00
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ emptyPageUrl ] ) ;
}
) ;
it ( 'should respect proxy bypass list when configured at context level' , async ( ) = > {
2022-06-22 13:25:44 +00:00
const { puppeteer , defaultBrowserOptions , server } = getTestState ( ) ;
2022-03-07 10:12:26 +00:00
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 ( ) ;
2022-06-15 10:09:22 +00:00
const response = ( await page . goto ( emptyPageUrl ) ) ! ;
2022-03-07 10:12:26 +00:00
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( proxiedRequestUrls ) . toEqual ( [ ] ) ;
} ) ;
} ) ;
} ) ;