mirror of
https://github.com/cypress-io/cypress.git
synced 2026-03-11 20:09:47 -05:00
Do not send requests for SNI server through upstream proxy (#4275)
* add test to ensure that SNI server will never go through proxy * prevent test from false positive * ensure that SNI server requests never go through proxy * e2e test that https-proxy does not pass sni reqs thru upstream * improve debug logging in https-proxy * fix using cwd, not workspaceFolder for terminals manager * remove dead code * stop the debug proxy after each test Co-authored-by: Brian Mann <brian.mann86@gmail.com>
This commit is contained in:
committed by
Brian Mann
parent
ef5c38d178
commit
b568e82545
@@ -31,7 +31,7 @@ class Server
|
||||
## https://github.com/cypress-io/cypress/issues/3192
|
||||
browserSocket.setNoDelay(true)
|
||||
|
||||
debug("Writing browserSocket connection headers %o", { url: req.url })
|
||||
debug("Writing browserSocket connection headers %o", { url: req.url, headLength: _.get(head, 'length'), headers: req.headers })
|
||||
|
||||
browserSocket.on "error", (err) =>
|
||||
## TODO: shouldn't we destroy the upstream socket here?
|
||||
@@ -62,6 +62,8 @@ class Server
|
||||
@_onFirstHeadBytes(req, browserSocket, data, options)
|
||||
|
||||
_onFirstHeadBytes: (req, browserSocket, head, options) ->
|
||||
debug("Got first head bytes %o", { url: req.url, head: _.chain(head).invoke('toString').slice(0, 64).join('').value() })
|
||||
|
||||
browserSocket.pause()
|
||||
|
||||
if odc = options.onDirectConnection
|
||||
@@ -96,8 +98,16 @@ class Server
|
||||
res.end()
|
||||
.pipe(res)
|
||||
|
||||
_getProxyForUrl: (url) ->
|
||||
if url == "https://localhost:#{@_sniPort}"
|
||||
## https://github.com/cypress-io/cypress/issues/4257
|
||||
## this is a tunnel to the SNI server, it should never go through a proxy
|
||||
return undefined
|
||||
|
||||
getProxyForUrl(url)
|
||||
|
||||
_makeDirectConnection: (req, browserSocket, head) ->
|
||||
{ port, hostname } = url.parse("http://#{req.url}")
|
||||
{ port, hostname } = url.parse("https://#{req.url}")
|
||||
|
||||
debug("Making connection to #{hostname}:#{port}")
|
||||
@_makeConnection(browserSocket, head, port, hostname)
|
||||
@@ -124,7 +134,7 @@ class Server
|
||||
|
||||
browserSocket.resume()
|
||||
|
||||
if upstreamProxy = getProxyForUrl("https://#{hostname}:#{port}")
|
||||
if upstreamProxy = @_getProxyForUrl("https://#{hostname}:#{port}")
|
||||
# todo: as soon as all requests are intercepted, this can go away since this is just for pass-through
|
||||
debug("making proxied connection %o", {
|
||||
host: "#{hostname}:#{port}",
|
||||
@@ -149,7 +159,7 @@ class Server
|
||||
makeConnection = (port) =>
|
||||
debug("Making intercepted connection to %s", port)
|
||||
|
||||
@_makeConnection(browserSocket, head, port)
|
||||
@_makeConnection(browserSocket, head, port, "localhost")
|
||||
|
||||
if firstBytes not in SSL_RECORD_TYPES
|
||||
## if this isn't an SSL request then go
|
||||
|
||||
@@ -5,6 +5,7 @@ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
|
||||
_ = require("lodash")
|
||||
DebugProxy = require("@cypress/debugging-proxy")
|
||||
net = require("net")
|
||||
network = require("@packages/network")
|
||||
path = require("path")
|
||||
Promise = require("bluebird")
|
||||
proxy = require("../helpers/proxy")
|
||||
@@ -241,6 +242,27 @@ describe "Proxy", ->
|
||||
expect(socket.destroyed).to.be.true
|
||||
resolve()
|
||||
|
||||
## https://github.com/cypress-io/cypress/issues/4257
|
||||
it "passes through to SNI when it is intercepted and not through proxy", ->
|
||||
createSocket = @sandbox.stub(network.connect, 'createRetryingSocket').callsArgWith(1, new Error('stub'))
|
||||
createProxyConn = @sandbox.spy(network.agent.httpsAgent, 'createUpstreamProxyConnection')
|
||||
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8443"
|
||||
proxy: "http://localhost:3333"
|
||||
resolveWithFullResponse: true
|
||||
forever: false
|
||||
})
|
||||
.then =>
|
||||
throw new Error('should not succeed')
|
||||
.catch { message: 'Error: socket hang up' }, =>
|
||||
expect(createProxyConn).to.not.be.called
|
||||
expect(createSocket).to.be.calledWith({
|
||||
port: @proxy._sniPort
|
||||
host: 'localhost'
|
||||
})
|
||||
|
||||
afterEach ->
|
||||
@upstream.stop()
|
||||
delete process.env.HTTP_PROXY
|
||||
|
||||
@@ -5,6 +5,7 @@ sinonChai = require("sinon-chai")
|
||||
sinonPromise = require("sinon-as-promised")(Promise)
|
||||
|
||||
global.request = require("request-promise")
|
||||
global.sinon = sinon
|
||||
global.supertest = require("supertest")
|
||||
|
||||
chai.use(sinonChai)
|
||||
@@ -15,4 +16,4 @@ beforeEach ->
|
||||
@sandbox = sinon.sandbox.create()
|
||||
|
||||
afterEach ->
|
||||
@sandbox.restore()
|
||||
@sandbox.restore()
|
||||
|
||||
Reference in New Issue
Block a user