Skip to content

Commit 19fdf43

Browse files
authored
fix: route all https traffic through proxy (#8827)
1 parent 07ed546 commit 19fdf43

File tree

14 files changed

+44
-391
lines changed

14 files changed

+44
-391
lines changed

packages/https-proxy/lib/server.js

+3-63
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
const _ = require('lodash')
2-
const { agent, allowDestroy, connect } = require('@packages/network')
2+
const { allowDestroy, connect } = require('@packages/network')
33
const debug = require('debug')('cypress:https-proxy')
4-
const {
5-
getProxyForUrl,
6-
} = require('proxy-from-env')
74
const https = require('https')
85
const net = require('net')
96
const parse = require('./util/parse')
@@ -76,29 +73,16 @@ class Server {
7673
})
7774
}
7875

79-
_onFirstHeadBytes (req, browserSocket, head, options) {
80-
let odc
81-
76+
_onFirstHeadBytes (req, browserSocket, head) {
8277
debug('Got first head bytes %o', { url: req.url, head: _.chain(head).invoke('toString').slice(0, 64).join('').value() })
8378

8479
browserSocket.pause()
8580

86-
odc = options.onDirectConnection
87-
88-
if (odc) {
89-
// if onDirectConnection return true
90-
// then dont proxy, just pass this through
91-
if (odc.call(this, req, browserSocket, head) === true) {
92-
return this._makeDirectConnection(req, browserSocket, head)
93-
}
94-
95-
debug('Not making direct connection %o', { url: req.url })
96-
}
97-
9881
return this._onServerConnectData(req, browserSocket, head)
9982
}
10083

10184
_onUpgrade (fn, req, browserSocket, head) {
85+
debug('upgrade', req.url)
10286
if (fn) {
10387
return fn.call(this, req, browserSocket, head)
10488
}
@@ -118,31 +102,7 @@ class Server {
118102
}
119103
}
120104

121-
_getProxyForUrl (urlStr) {
122-
const port = Number(_.get(url.parse(urlStr), 'port'))
123-
124-
debug('getting proxy URL %o', { port, serverPort: this._port, sniPort: this._sniPort, url: urlStr })
125-
126-
if ([this._sniPort, this._port].includes(port)) {
127-
// https://github.com/cypress-io/cypress/issues/4257
128-
// this is a tunnel to the SNI server or to the main server,
129-
// it should never go through a proxy
130-
return undefined
131-
}
132-
133-
return getProxyForUrl(urlStr)
134-
}
135-
136-
_makeDirectConnection (req, browserSocket, head) {
137-
const { port, hostname } = url.parse(`https://${req.url}`)
138-
139-
debug(`Making connection to ${hostname}:${port}`)
140-
141-
return this._makeConnection(browserSocket, head, port, hostname)
142-
}
143-
144105
_makeConnection (browserSocket, head, port, hostname) {
145-
let upstreamProxy
146106
const onSocket = (err, upstreamSocket) => {
147107
debug('received upstreamSocket callback for request %o', { port, hostname, err })
148108

@@ -174,26 +134,6 @@ class Server {
174134
port = '443'
175135
}
176136

177-
upstreamProxy = this._getProxyForUrl(`https://${hostname}:${port}`)
178-
179-
if (upstreamProxy) {
180-
// todo: as soon as all requests are intercepted, this can go away since this is just for pass-through
181-
debug('making proxied connection %o', {
182-
host: `${hostname}:${port}`,
183-
proxy: upstreamProxy,
184-
})
185-
186-
return agent.httpsAgent.createUpstreamProxyConnection({
187-
proxy: upstreamProxy,
188-
href: `https://${hostname}:${port}`,
189-
uri: {
190-
port,
191-
hostname,
192-
},
193-
shouldRetry: true,
194-
}, onSocket)
195-
}
196-
197137
return connect.createRetryingSocket({ port, host: hostname }, onSocket)
198138
}
199139

packages/https-proxy/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
"fs-extra": "8.1.0",
2020
"lodash": "4.17.19",
2121
"node-forge": "0.10.0",
22-
"proxy-from-env": "1.0.0",
2322
"semaphore": "1.1.0"
2423
},
2524
"devDependencies": {

packages/https-proxy/test/integration/proxy_spec.js

+5-38
Original file line numberDiff line numberDiff line change
@@ -89,34 +89,6 @@ describe('Proxy', () => {
8989
})
9090
})
9191

92-
// this will fail due to dynamic cert
93-
// generation when strict ssl is true
94-
it('can pass directly through', () => {
95-
return request({
96-
strictSSL: false,
97-
url: 'https://localhost:8444/replace',
98-
proxy: 'http://localhost:3333',
99-
})
100-
.then((html) => {
101-
expect(html).to.include('https server')
102-
})
103-
})
104-
105-
it('retries 5 times', function () {
106-
this.sandbox.spy(net, 'connect')
107-
108-
return request({
109-
strictSSL: false,
110-
url: 'https://localhost:12344',
111-
proxy: 'http://localhost:3333',
112-
})
113-
.then(() => {
114-
throw new Error('should not reach')
115-
}).catch(() => {
116-
expect(net.connect).to.have.callCount(5)
117-
})
118-
})
119-
12092
it('closes outgoing connections when client disconnects', function () {
12193
this.sandbox.spy(net, 'connect')
12294

@@ -130,12 +102,8 @@ describe('Proxy', () => {
130102
// ensure client has disconnected
131103
expect(res.socket.destroyed).to.be.true
132104
// ensure the outgoing socket created for this connection was destroyed
133-
const socket = net.connect.getCalls()
134-
.find((call) => {
135-
return (call.args[0].port === '8444') && (call.args[0].host === 'localhost')
136-
}).returnValue
137-
138-
expect(socket.destroyed).to.be.true
105+
expect(net.connect).calledOnce
106+
expect(net.connect.getCalls()[0].returnValue.destroyed).to.be.true
139107
})
140108
})
141109

@@ -227,6 +195,7 @@ describe('Proxy', () => {
227195
})
228196
})
229197

198+
// TODO
230199
context('with an upstream proxy', () => {
231200
beforeEach(function () {
232201
// PROXY vars should override npm_config vars, so set them to cause failures if they are used
@@ -300,10 +269,8 @@ describe('Proxy', () => {
300269
expect(res.socket.destroyed).to.be.true
301270

302271
// ensure the outgoing socket created for this connection was destroyed
303-
const socket = net.connect.getCalls()
304-
.find((call) => {
305-
return (call.args[0].port === 9001) && (call.args[0].host === 'localhost')
306-
}).returnValue
272+
expect(net.connect).calledOnce
273+
const socket = net.connect.getCalls()[0].returnValue
307274

308275
return new Promise((resolve) => {
309276
return socket.on('close', () => {

packages/https-proxy/test/unit/server_spec.js

+3-30
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ describe('lib/server', () => {
6464

6565
this.setup({ onError })
6666
.then((srv) => {
67-
srv._makeDirectConnection({ url: 'localhost:8444' }, socket, head)
67+
srv._makeConnection(socket, head, '8444', 'localhost')
6868
})
6969
})
7070

@@ -76,7 +76,7 @@ describe('lib/server', () => {
7676
const head = {}
7777

7878
const onError = function (err, socket2, head2, port) {
79-
expect(err.message).to.eq('connect ECONNREFUSED 127.0.0.1:443')
79+
expect(err.message).to.eq('getaddrinfo ENOTFOUND %7Balgolia_application_id%7D-dsn.algolia.net')
8080

8181
expect(socket).to.eq(socket2)
8282
expect(head).to.eq(head2)
@@ -89,34 +89,7 @@ describe('lib/server', () => {
8989

9090
this.setup({ onError })
9191
.then((srv) => {
92-
srv._makeDirectConnection({ url: '%7Balgolia_application_id%7D-dsn.algolia.net:443' }, socket, head)
93-
})
94-
})
95-
96-
it('with proxied connection calls options.onError with err and port and destroys the client socket', function (done) {
97-
const socket = new EE()
98-
99-
socket.destroy = this.sandbox.stub()
100-
const head = {}
101-
102-
const onError = function (err, socket2, head2, port) {
103-
expect(err.message).to.eq('A connection to the upstream proxy could not be established: connect ECONNREFUSED 127.0.0.1:8444')
104-
105-
expect(socket).to.eq(socket2)
106-
expect(head).to.eq(head2)
107-
expect(port).to.eq('11111')
108-
109-
expect(socket.destroy).to.be.calledOnce
110-
111-
done()
112-
}
113-
114-
process.env.HTTPS_PROXY = 'http://localhost:8444'
115-
process.env.NO_PROXY = ''
116-
117-
this.setup({ onError })
118-
.then((srv) => {
119-
srv._makeDirectConnection({ url: 'should-not-reach.invalid:11111' }, socket, head)
92+
srv._makeConnection(socket, head, '443', '%7Balgolia_application_id%7D-dsn.algolia.net')
12093
})
12194
})
12295
})

packages/net-stubbing/lib/server/index.ts

-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ export { InterceptResponse } from './intercept-response'
88

99
export { NetStubbingState } from './types'
1010

11-
export { isHostInterceptable } from './is-host-interceptable'
12-
1311
import { state } from './state'
1412

1513
export const netStubbingState = state

packages/net-stubbing/lib/server/is-host-interceptable.ts

-60
This file was deleted.

0 commit comments

Comments
 (0)