Skip to content
This repository has been archived by the owner on May 3, 2022. It is now read-only.

Fix noproxy conventions #49

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
185 changes: 97 additions & 88 deletions __tests__/proxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,109 +38,120 @@ describe('proxy', () => {
})
})

it('getProxyUrl does not return proxyUrl if variables not set', () => {
let proxyUrl = pm.getProxyUrl(new URL('https://github.com'))
expect(proxyUrl).toBeUndefined()
})
describe('getProxyUrl', () => {
it('does not return proxyUrl if variables not set', () => {
let proxyUrl = pm.getProxyUrl(new URL('https://github.com'))
expect(proxyUrl).toBeUndefined()
})

it('getProxyUrl returns proxyUrl if https_proxy set for https url', () => {
process.env['https_proxy'] = 'https://myproxysvr'
let proxyUrl = pm.getProxyUrl(new URL('https://github.com'))
expect(proxyUrl).toBeDefined()
})
it('returns proxyUrl if https_proxy set for https url', () => {
process.env['https_proxy'] = 'https://myproxysvr'
let proxyUrl = pm.getProxyUrl(new URL('https://github.com'))
expect(proxyUrl).toBeDefined()
})

it('getProxyUrl does not return proxyUrl if http_proxy set for https url', () => {
process.env['http_proxy'] = 'https://myproxysvr'
let proxyUrl = pm.getProxyUrl(new URL('https://github.com'))
expect(proxyUrl).toBeUndefined()
})
it('does not return proxyUrl if http_proxy set for https url', () => {
process.env['http_proxy'] = 'https://myproxysvr'
let proxyUrl = pm.getProxyUrl(new URL('https://github.com'))
expect(proxyUrl).toBeUndefined()
})

it('getProxyUrl returns proxyUrl if http_proxy set for http url', () => {
process.env['http_proxy'] = 'http://myproxysvr'
let proxyUrl = pm.getProxyUrl(new URL('http://github.com'))
expect(proxyUrl).toBeDefined()
})
it('returns proxyUrl if http_proxy set for http url', () => {
process.env['http_proxy'] = 'http://myproxysvr'
let proxyUrl = pm.getProxyUrl(new URL('http://github.com'))
expect(proxyUrl).toBeDefined()
})

it('getProxyUrl does not return proxyUrl if https_proxy set and in no_proxy list', () => {
process.env['https_proxy'] = 'https://myproxysvr'
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(new URL('https://myserver'))
expect(proxyUrl).toBeUndefined()
})
it('does not return proxyUrl if https_proxy set and in no_proxy list', () => {
process.env['https_proxy'] = 'https://myproxysvr'
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(new URL('https://myserver'))
expect(proxyUrl).toBeUndefined()
})

it('getProxyUrl returns proxyUrl if https_proxy set and not in no_proxy list', () => {
process.env['https_proxy'] = 'https://myproxysvr'
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(new URL('https://github.com'))
expect(proxyUrl).toBeDefined()
})
it('returns proxyUrl if https_proxy set and not in no_proxy list', () => {
process.env['https_proxy'] = 'https://myproxysvr'
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(new URL('https://github.com'))
expect(proxyUrl).toBeDefined()
})

it('getProxyUrl does not return proxyUrl if http_proxy set and in no_proxy list', () => {
process.env['http_proxy'] = 'http://myproxysvr'
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(new URL('http://myserver'))
expect(proxyUrl).toBeUndefined()
})
it('does not return proxyUrl if http_proxy set and in no_proxy list', () => {
process.env['http_proxy'] = 'http://myproxysvr'
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(new URL('http://myserver'))
expect(proxyUrl).toBeUndefined()
})

it('getProxyUrl returns proxyUrl if http_proxy set and not in no_proxy list', () => {
process.env['http_proxy'] = 'http://myproxysvr'
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(new URL('http://github.com'))
expect(proxyUrl).toBeDefined()
it('returns proxyUrl if http_proxy set and not in no_proxy list', () => {
process.env['http_proxy'] = 'http://myproxysvr'
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let proxyUrl = pm.getProxyUrl(new URL('http://github.com'))
expect(proxyUrl).toBeDefined()
})
})

it('checkBypass returns true if host as no_proxy list', () => {
process.env['no_proxy'] = 'myserver'
let bypass = pm.checkBypass(new URL('https://myserver'))
expect(bypass).toBeTruthy()
})
describe('checkBypass', () => {
it('returns true if host as no_proxy list', () => {
process.env['no_proxy'] = 'myserver'
let bypass = pm.checkBypass(new URL('https://myserver'))
expect(bypass).toBeTruthy()
})

it('checkBypass returns true if host in no_proxy list', () => {
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let bypass = pm.checkBypass(new URL('https://myserver'))
expect(bypass).toBeTruthy()
})
it('returns true if host in no_proxy list', () => {
process.env['no_proxy'] = 'otherserver,myserver,anotherserver:8080'
let bypass = pm.checkBypass(new URL('https://myserver'))
expect(bypass).toBeTruthy()
})

it('checkBypass returns true if host in no_proxy list with spaces', () => {
process.env['no_proxy'] = 'otherserver, myserver ,anotherserver:8080'
let bypass = pm.checkBypass(new URL('https://myserver'))
expect(bypass).toBeTruthy()
})
it('returns true if host in no_proxy list with spaces', () => {
process.env['no_proxy'] = 'otherserver, myserver ,anotherserver:8080'
let bypass = pm.checkBypass(new URL('https://myserver'))
expect(bypass).toBeTruthy()
})

it('checkBypass returns true if host in no_proxy list with port', () => {
process.env['no_proxy'] = 'otherserver, myserver:8080 ,anotherserver'
let bypass = pm.checkBypass(new URL('https://myserver:8080'))
expect(bypass).toBeTruthy()
})
it('returns true if host in no_proxy list with port', () => {
process.env['no_proxy'] = 'otherserver, myserver:8080 ,anotherserver'
let bypass = pm.checkBypass(new URL('https://myserver:8080'))
expect(bypass).toBeTruthy()
})

it('checkBypass returns true if host with port in no_proxy list without port', () => {
process.env['no_proxy'] = 'otherserver, myserver ,anotherserver'
let bypass = pm.checkBypass(new URL('https://myserver:8080'))
expect(bypass).toBeTruthy()
})
it('returns true if host with port in no_proxy list without port', () => {
process.env['no_proxy'] = 'otherserver, myserver ,anotherserver'
let bypass = pm.checkBypass(new URL('https://myserver:8080'))
expect(bypass).toBeTruthy()
})

it('checkBypass returns true if host in no_proxy list with default https port', () => {
process.env['no_proxy'] = 'otherserver, myserver:443 ,anotherserver'
let bypass = pm.checkBypass(new URL('https://myserver'))
expect(bypass).toBeTruthy()
})
it('returns true if host in no_proxy list with default https port', () => {
process.env['no_proxy'] = 'otherserver, myserver:443 ,anotherserver'
let bypass = pm.checkBypass(new URL('https://myserver'))
expect(bypass).toBeTruthy()
})

it('checkBypass returns true if host in no_proxy list with default http port', () => {
process.env['no_proxy'] = 'otherserver, myserver:80 ,anotherserver'
let bypass = pm.checkBypass(new URL('http://myserver'))
expect(bypass).toBeTruthy()
})
it('returns true if host in no_proxy list with default http port', () => {
process.env['no_proxy'] = 'otherserver, myserver:80 ,anotherserver'
let bypass = pm.checkBypass(new URL('http://myserver'))
expect(bypass).toBeTruthy()
})

it('checkBypass returns false if host not in no_proxy list', () => {
process.env['no_proxy'] = 'otherserver, myserver ,anotherserver:8080'
let bypass = pm.checkBypass(new URL('https://github.com'))
expect(bypass).toBeFalsy()
})
it('returns false if host not in no_proxy list', () => {
process.env['no_proxy'] = 'otherserver, myserver ,anotherserver:8080'
let bypass = pm.checkBypass(new URL('https://github.com'))
expect(bypass).toBeFalsy()
})

it('checkBypass returns false if empty no_proxy', () => {
process.env['no_proxy'] = ''
let bypass = pm.checkBypass(new URL('https://github.com'))
expect(bypass).toBeFalsy()
it.only('allows dot prefixes which match any subdomain', () => {
process.env['no_proxy'] = '.github.com'
let bypass = pm.checkBypass(new URL('https://api.github.com'))
expect(bypass).toBeTruthy()
bypass = pm.checkBypass(new URL('https://apigithub.com'))
expect(bypass).toBeFalsy()
})
it('returns false if empty no_proxy', () => {
process.env['no_proxy'] = ''
let bypass = pm.checkBypass(new URL('https://github.com'))
expect(bypass).toBeFalsy()
})
})

it('HttpClient does basic http get request through proxy', async () => {
Expand Down Expand Up @@ -201,7 +212,6 @@ describe('proxy', () => {
process.env['https_proxy'] = 'http://127.0.0.1:8080'
const httpClient = new httpm.HttpClient()
let agent: tunnelm.TunnelingAgent = httpClient.getAgent('https://some-url')
console.log(agent)
expect(agent.proxyOptions.host).toBe('127.0.0.1')
expect(agent.proxyOptions.port).toBe('8080')
expect(agent.proxyOptions.proxyAuth).toBe(undefined)
Expand All @@ -211,7 +221,6 @@ describe('proxy', () => {
process.env['https_proxy'] = 'http://user:password@127.0.0.1:8080'
const httpClient = new httpm.HttpClient()
let agent: tunnelm.TunnelingAgent = httpClient.getAgent('https://some-url')
console.log(agent)
expect(agent.proxyOptions.host).toBe('127.0.0.1')
expect(agent.proxyOptions.port).toBe('8080')
expect(agent.proxyOptions.proxyAuth).toBe('user:password')
Expand Down
50 changes: 26 additions & 24 deletions proxy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { CLIENT_RENEG_WINDOW } from "tls"

export function getProxyUrl(reqUrl: URL): URL | undefined {
let usingSsl = reqUrl.protocol === 'https:'

Expand All @@ -21,37 +23,37 @@ export function getProxyUrl(reqUrl: URL): URL | undefined {
}

export function checkBypass(reqUrl: URL): boolean {
if (!reqUrl.hostname) {
const noProxy = process.env['no_proxy'] || process.env['NO_PROXY']
if (!(reqUrl.hostname && noProxy)) {
return false
}

let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''
if (!noProxy) {
return false
}

// Determine the request port
let reqPort: number
if (reqUrl.port) {
reqPort = Number(reqUrl.port)
} else if (reqUrl.protocol === 'http:') {
reqPort = 80
} else if (reqUrl.protocol === 'https:') {
reqPort = 443
}

const upHost = reqUrl.hostname.toUpperCase()
// Format the request hostname and hostname with port
let upperReqHosts = [reqUrl.hostname.toUpperCase()]
if (typeof reqPort === 'number') {
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`)
const upperReqHosts = [upHost]

// Determine the request port and add that to list to check
let reqPort = Number(reqUrl.port)
if (!reqPort) {
switch (reqUrl.protocol) {
case 'http:':
reqPort = 80
break;
case 'https:':
reqPort = 443
break;
}
}
upperReqHosts.push(`${upHost}:${reqPort}`)

const upHosts = noProxy.split(',').map(x => x.trim().toUpperCase()).filter(x => x)

// Compare request host against noproxy
for (let upperNoProxyItem of noProxy
.split(',')
.map(x => x.trim().toUpperCase())
.filter(x => x)) {
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
for (const host of upHosts) {
if (host[0] === '.' && upperReqHosts.some(h => h.endsWith(host))) {
return true
}
if (upperReqHosts.some(x => x === host)) {
return true
}
}
Expand Down