mirror of
https://github.com/cypress-io/cypress.git
synced 2026-03-14 13:20:29 -05:00
remove core- prefixes from packages
This commit is contained in:
37
packages/https-proxy/.gitignore
vendored
Normal file
37
packages/https-proxy/.gitignore
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directory
|
||||
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
|
||||
node_modules
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
ca
|
||||
.http-mitm-proxy
|
||||
1
packages/https-proxy/.node-version
Normal file
1
packages/https-proxy/.node-version
Normal file
@@ -0,0 +1 @@
|
||||
6.5.0
|
||||
8
packages/https-proxy/.release.json
Normal file
8
packages/https-proxy/.release.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"commitMessage": "release %s",
|
||||
"tagAnnotation": "release %s",
|
||||
"github": {
|
||||
"release": false,
|
||||
"releaseName": "release %s"
|
||||
}
|
||||
}
|
||||
29
packages/https-proxy/README.md
Normal file
29
packages/https-proxy/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Cypress Core Extension
|
||||
|
||||
## Developing
|
||||
|
||||
**Testing**
|
||||
|
||||
```bash
|
||||
npm run test-once
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
#### 0.1.5 - *(04/20/17)*
|
||||
- bump cypress coffee script and releaser dep
|
||||
|
||||
#### 0.1.4 - *(10/21/16)*
|
||||
- add server destroy to https helper
|
||||
|
||||
#### 0.1.3 - *(08/24/16)*
|
||||
- ref fork
|
||||
|
||||
#### 0.1.2 - *(08/24/16)*
|
||||
- fix segfault errors
|
||||
|
||||
#### 0.1.1 - *(08/24/16)*
|
||||
- fix devDep to dep
|
||||
|
||||
#### 0.1.0 - *(06/28/16)*
|
||||
- initial release
|
||||
7
packages/https-proxy/circle.yml
Normal file
7
packages/https-proxy/circle.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
machine:
|
||||
node:
|
||||
version: 6.5.0
|
||||
|
||||
test:
|
||||
override:
|
||||
- npm run test-ci
|
||||
2
packages/https-proxy/https.js
Normal file
2
packages/https-proxy/https.js
Normal file
@@ -0,0 +1,2 @@
|
||||
require("coffee-script/register")
|
||||
require("./test/helpers/https_server").start(8443)
|
||||
3
packages/https-proxy/index.js
Normal file
3
packages/https-proxy/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
require("@cypress/coffee-script")
|
||||
|
||||
module.exports = require("./lib/proxy")
|
||||
236
packages/https-proxy/lib/ca.coffee
Normal file
236
packages/https-proxy/lib/ca.coffee
Normal file
@@ -0,0 +1,236 @@
|
||||
_ = require("lodash")
|
||||
fs = require("fs-extra")
|
||||
path = require("path")
|
||||
Forge = require("node-forge")
|
||||
Promise = require("bluebird")
|
||||
|
||||
fs = Promise.promisifyAll(fs)
|
||||
|
||||
pki = Forge.pki
|
||||
|
||||
generateKeyPairAsync = Promise.promisify(pki.rsa.generateKeyPair)
|
||||
|
||||
ipAddressRe = /^[\d\.]+$/
|
||||
asterisksRe = /\*/g
|
||||
|
||||
CAattrs = [{
|
||||
name: "commonName",
|
||||
value: "CypressProxyCA"
|
||||
}, {
|
||||
name: "countryName",
|
||||
value: "Internet"
|
||||
}, {
|
||||
shortName: "ST",
|
||||
value: "Internet"
|
||||
}, {
|
||||
name: "localityName",
|
||||
value: "Internet"
|
||||
}, {
|
||||
name: "organizationName",
|
||||
value: "Cypress.io"
|
||||
}, {
|
||||
shortName: "OU",
|
||||
value: "CA"
|
||||
}]
|
||||
|
||||
CAextensions = [{
|
||||
name: "basicConstraints",
|
||||
cA: true
|
||||
}, {
|
||||
name: "keyUsage",
|
||||
keyCertSign: true,
|
||||
digitalSignature: true,
|
||||
nonRepudiation: true,
|
||||
keyEncipherment: true,
|
||||
dataEncipherment: true
|
||||
}, {
|
||||
name: "extKeyUsage",
|
||||
serverAuth: true,
|
||||
clientAuth: true,
|
||||
codeSigning: true,
|
||||
emailProtection: true,
|
||||
timeStamping: true
|
||||
}, {
|
||||
name: "nsCertType",
|
||||
client: true,
|
||||
server: true,
|
||||
email: true,
|
||||
objsign: true,
|
||||
sslCA: true,
|
||||
emailCA: true,
|
||||
objCA: true
|
||||
}, {
|
||||
name: "subjectKeyIdentifier"
|
||||
}]
|
||||
|
||||
ServerAttrs = [{
|
||||
name: "countryName",
|
||||
value: "Internet"
|
||||
}, {
|
||||
shortName: "ST",
|
||||
value: "Internet"
|
||||
}, {
|
||||
name: "localityName",
|
||||
value: "Internet"
|
||||
}, {
|
||||
name: "organizationName",
|
||||
value: "Cypress Proxy CA"
|
||||
}, {
|
||||
shortName: "OU",
|
||||
value: "Cypress Proxy Server Certificate"
|
||||
}]
|
||||
|
||||
ServerExtensions = [{
|
||||
name: "basicConstraints",
|
||||
cA: false
|
||||
}, {
|
||||
name: "keyUsage",
|
||||
keyCertSign: false,
|
||||
digitalSignature: true,
|
||||
nonRepudiation: false,
|
||||
keyEncipherment: true,
|
||||
dataEncipherment: true
|
||||
}, {
|
||||
name: "extKeyUsage",
|
||||
serverAuth: true,
|
||||
clientAuth: true,
|
||||
codeSigning: false,
|
||||
emailProtection: false,
|
||||
timeStamping: false
|
||||
}, {
|
||||
name: "nsCertType",
|
||||
client: true,
|
||||
server: true,
|
||||
email: false,
|
||||
objsign: false,
|
||||
sslCA: false,
|
||||
emailCA: false,
|
||||
objCA: false
|
||||
}, {
|
||||
name: "subjectKeyIdentifier"
|
||||
}]
|
||||
|
||||
class CA
|
||||
|
||||
randomSerialNumber: ->
|
||||
## generate random 16 bytes hex string
|
||||
sn = ""
|
||||
|
||||
for i in [1..4]
|
||||
sn += ("00000000" + Math.floor(Math.random()*Math.pow(256, 4)).toString(16)).slice(-8)
|
||||
|
||||
sn
|
||||
|
||||
generateCA: ->
|
||||
generateKeyPairAsync({bits: 512})
|
||||
.then (keys) =>
|
||||
cert = pki.createCertificate()
|
||||
cert.publicKey = keys.publicKey
|
||||
cert.serialNumber = @randomSerialNumber()
|
||||
cert.validity.notBefore = new Date()
|
||||
cert.validity.notAfter = new Date()
|
||||
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 10)
|
||||
cert.setSubject(CAattrs)
|
||||
cert.setIssuer(CAattrs)
|
||||
cert.setExtensions(CAextensions)
|
||||
cert.sign(keys.privateKey, Forge.md.sha256.create())
|
||||
|
||||
@CAcert = cert
|
||||
@CAkeys = keys
|
||||
|
||||
Promise.all([
|
||||
fs.writeFileAsync(path.join(@certsFolder, "ca.pem"), pki.certificateToPem(cert))
|
||||
fs.writeFileAsync(path.join(@keysFolder, "ca.private.key"), pki.privateKeyToPem(keys.privateKey))
|
||||
fs.writeFileAsync(path.join(@keysFolder, "ca.public.key"), pki.publicKeyToPem(keys.publicKey))
|
||||
])
|
||||
|
||||
loadCA: ->
|
||||
Promise.props({
|
||||
certPEM: fs.readFileAsync(path.join(@certsFolder, "ca.pem"), "utf-8")
|
||||
keyPrivatePEM: fs.readFileAsync(path.join(@keysFolder, "ca.private.key"), "utf-8")
|
||||
keyPublicPEM: fs.readFileAsync(path.join(@keysFolder, "ca.public.key"), "utf-8")
|
||||
})
|
||||
.then (results) =>
|
||||
@CAcert = pki.certificateFromPem(results.certPEM)
|
||||
@CAkeys = {
|
||||
privateKey: pki.privateKeyFromPem(results.keyPrivatePEM)
|
||||
publicKey: pki.publicKeyFromPem(results.keyPublicPEM)
|
||||
}
|
||||
.return(undefined)
|
||||
|
||||
generateServerCertificateKeys: (hosts) ->
|
||||
hosts = [].concat(hosts)
|
||||
|
||||
mainHost = hosts[0]
|
||||
keysServer = pki.rsa.generateKeyPair(1024)
|
||||
certServer = pki.createCertificate()
|
||||
|
||||
certServer.publicKey = keysServer.publicKey
|
||||
certServer.serialNumber = @randomSerialNumber()
|
||||
certServer.validity.notBefore = new Date
|
||||
certServer.validity.notAfter = new Date
|
||||
certServer.validity.notAfter.setFullYear(certServer.validity.notBefore.getFullYear() + 2)
|
||||
|
||||
attrsServer = _.clone(ServerAttrs)
|
||||
attrsServer.unshift({
|
||||
name: "commonName",
|
||||
value: mainHost
|
||||
})
|
||||
|
||||
certServer.setSubject(attrsServer)
|
||||
certServer.setIssuer(@CAcert.issuer.attributes)
|
||||
certServer.setExtensions(ServerExtensions.concat([{
|
||||
name: "subjectAltName",
|
||||
altNames: hosts.map (host) ->
|
||||
if host.match(ipAddressRe)
|
||||
{type: 7, ip: host}
|
||||
else
|
||||
{type: 2, value: host}
|
||||
}]))
|
||||
|
||||
certServer.sign(@CAkeys.privateKey, Forge.md.sha256.create())
|
||||
|
||||
certPem = pki.certificateToPem(certServer)
|
||||
keyPrivatePem = pki.privateKeyToPem(keysServer.privateKey)
|
||||
keyPublicPem = pki.publicKeyToPem(keysServer.publicKey)
|
||||
|
||||
dest = mainHost.replace(asterisksRe, "_")
|
||||
|
||||
Promise.all([
|
||||
fs.writeFileAsync(path.join(@certsFolder, dest + ".pem"), certPem)
|
||||
fs.writeFileAsync(path.join(@keysFolder, dest + ".key"), keyPrivatePem)
|
||||
fs.writeFileAsync(path.join(@keysFolder, dest + ".public.key"), keyPublicPem)
|
||||
])
|
||||
.return([certPem, keyPrivatePem])
|
||||
|
||||
getCertificateKeysForHostname: (hostname) ->
|
||||
dest = hostname.replace(asterisksRe, "_")
|
||||
|
||||
Promise.all([
|
||||
fs.readFileAsync(path.join(@certsFolder, dest + ".pem"))
|
||||
fs.readFileAsync(path.join(@keysFolder, dest + ".key"))
|
||||
])
|
||||
|
||||
getCACertPath: ->
|
||||
path.join(@certsFolder, "ca.pem")
|
||||
|
||||
@create = (caFolder) ->
|
||||
ca = new CA
|
||||
|
||||
ca.baseCAFolder = caFolder
|
||||
ca.certsFolder = path.join(ca.baseCAFolder, "certs")
|
||||
ca.keysFolder = path.join(ca.baseCAFolder, "keys")
|
||||
|
||||
Promise.all([
|
||||
fs.ensureDirAsync(ca.baseCAFolder)
|
||||
fs.ensureDirAsync(ca.certsFolder)
|
||||
fs.ensureDirAsync(ca.keysFolder)
|
||||
])
|
||||
.then ->
|
||||
fs.statAsync(path.join(ca.certsFolder, "ca.pem"))
|
||||
.bind(ca)
|
||||
.then(ca.loadCA)
|
||||
.catch(ca.generateCA)
|
||||
.return(ca)
|
||||
|
||||
module.exports = CA
|
||||
13
packages/https-proxy/lib/proxy.coffee
Normal file
13
packages/https-proxy/lib/proxy.coffee
Normal file
@@ -0,0 +1,13 @@
|
||||
CA = require("./ca")
|
||||
Server = require("./server")
|
||||
|
||||
module.exports = {
|
||||
create: (dir, port, options) ->
|
||||
CA.create(dir)
|
||||
.then (ca) ->
|
||||
Server.create(ca, port, options)
|
||||
|
||||
reset: ->
|
||||
Server.reset()
|
||||
|
||||
}
|
||||
184
packages/https-proxy/lib/server.coffee
Normal file
184
packages/https-proxy/lib/server.coffee
Normal file
@@ -0,0 +1,184 @@
|
||||
_ = require("lodash")
|
||||
fs = require("fs-extra")
|
||||
net = require("net")
|
||||
url = require("url")
|
||||
https = require("https")
|
||||
Promise = require("bluebird")
|
||||
semaphore = require("semaphore")
|
||||
allowDestroy = require("server-destroy-vvo")
|
||||
parse = require("./util/parse")
|
||||
|
||||
fs = Promise.promisifyAll(fs)
|
||||
|
||||
sslServers = {}
|
||||
sslSemaphores = {}
|
||||
|
||||
class Server
|
||||
constructor: (@_ca, @_port) ->
|
||||
@_onError = null
|
||||
|
||||
connect: (req, socket, head, options = {}) ->
|
||||
if not head or head.length is 0
|
||||
socket.once "data", (data) =>
|
||||
@connect(req, socket, data, options)
|
||||
|
||||
socket.write "HTTP/1.1 200 OK\r\n"
|
||||
|
||||
if req.headers["proxy-connection"] is "keep-alive"
|
||||
socket.write("Proxy-Connection: keep-alive\r\n")
|
||||
socket.write("Connection: keep-alive\r\n")
|
||||
|
||||
return socket.write("\r\n")
|
||||
|
||||
else
|
||||
if odc = options.onDirectConnection
|
||||
## if onDirectConnection return true
|
||||
## then dont proxy, just pass this through
|
||||
if odc.call(@, req, socket, head) is true
|
||||
return @_makeDirectConnection(req, socket, head)
|
||||
|
||||
socket.pause()
|
||||
|
||||
@_onServerConnectData(req, socket, head)
|
||||
|
||||
_onUpgrade: (fn, req, socket, head) ->
|
||||
if fn
|
||||
fn.call(@, req, socket, head)
|
||||
|
||||
_onRequest: (fn, req, res) ->
|
||||
hostPort = parse.hostAndPort(req.url, req.headers, 443)
|
||||
|
||||
req.url = url.format({
|
||||
protocol: "https:"
|
||||
hostname: hostPort.host
|
||||
port: hostPort.port
|
||||
}) + req.url
|
||||
|
||||
if fn
|
||||
return fn.call(@, req, res)
|
||||
|
||||
req.pipe(request(req.url))
|
||||
.on "error", ->
|
||||
res.statusCode = 500
|
||||
res.end()
|
||||
.pipe(res)
|
||||
|
||||
_makeDirectConnection: (req, socket, head) ->
|
||||
directUrl = url.parse("http://#{req.url}")
|
||||
|
||||
@_makeConnection(socket, head, directUrl.port, directUrl.hostname)
|
||||
|
||||
_makeConnection: (socket, head, port, hostname) ->
|
||||
cb = ->
|
||||
socket.pipe(conn)
|
||||
conn.pipe(socket)
|
||||
socket.emit("data", head)
|
||||
|
||||
socket.resume()
|
||||
|
||||
## compact out hostname when undefined
|
||||
args = _.compact([port, hostname, cb])
|
||||
|
||||
conn = net.connect.apply(net, args)
|
||||
|
||||
conn.on "error", (err) =>
|
||||
if @_onError
|
||||
@_onError(err, socket, head, port)
|
||||
|
||||
_onServerConnectData: (req, socket, head) ->
|
||||
firstBytes = head[0]
|
||||
|
||||
makeConnection = (port) =>
|
||||
@_makeConnection(socket, head, port)
|
||||
|
||||
if firstBytes is 0x16 or firstBytes is 0x80 or firstBytes is 0x00
|
||||
{hostname} = url.parse("http://#{req.url}")
|
||||
|
||||
if sslServer = sslServers[hostname]
|
||||
return makeConnection(sslServer.port)
|
||||
|
||||
if not sem = sslSemaphores[hostname]
|
||||
sem = sslSemaphores[hostname] = semaphore(1)
|
||||
|
||||
sem.take =>
|
||||
leave = ->
|
||||
process.nextTick ->
|
||||
sem.leave()
|
||||
|
||||
if sslServer = sslServers[hostname]
|
||||
leave()
|
||||
|
||||
return makeConnection(sslServer.port)
|
||||
|
||||
@_getPortFor(hostname)
|
||||
.then (port) ->
|
||||
sslServers[hostname] = { port: port }
|
||||
|
||||
leave()
|
||||
|
||||
makeConnection(port)
|
||||
|
||||
else
|
||||
makeConnection(@_port)
|
||||
|
||||
_normalizeKeyAndCert: (certPem, privateKeyPem) ->
|
||||
return {
|
||||
key: privateKeyPem
|
||||
cert: certPem
|
||||
}
|
||||
|
||||
_getCertificatePathsFor: (hostname) ->
|
||||
@_ca.getCertificateKeysForHostname(hostname)
|
||||
.spread(@_normalizeKeyAndCert)
|
||||
|
||||
_generateMissingCertificates: (hostname) ->
|
||||
@_ca.generateServerCertificateKeys(hostname)
|
||||
.spread(@_normalizeKeyAndCert)
|
||||
|
||||
_getPortFor: (hostname) ->
|
||||
@_getCertificatePathsFor(hostname)
|
||||
|
||||
.catch (err) =>
|
||||
@_generateMissingCertificates(hostname)
|
||||
|
||||
.then (data = {}) =>
|
||||
@_sniServer.addContext(hostname, data)
|
||||
|
||||
return @_sniPort
|
||||
|
||||
listen: (options = {}) ->
|
||||
new Promise (resolve) =>
|
||||
@_onError = options.onError
|
||||
|
||||
@_sniServer = https.createServer({})
|
||||
|
||||
allowDestroy(@_sniServer)
|
||||
|
||||
@_sniServer.on "upgrade", @_onUpgrade.bind(@, options.onUpgrade)
|
||||
@_sniServer.on "request", @_onRequest.bind(@, options.onRequest)
|
||||
@_sniServer.listen =>
|
||||
## store the port of our current sniServer
|
||||
@_sniPort = @_sniServer.address().port
|
||||
|
||||
resolve()
|
||||
|
||||
close: ->
|
||||
close = =>
|
||||
new Promise (resolve) =>
|
||||
@_sniServer.destroy(resolve)
|
||||
|
||||
close()
|
||||
.finally ->
|
||||
sslServers = {}
|
||||
|
||||
module.exports = {
|
||||
reset: ->
|
||||
sslServers = {}
|
||||
|
||||
create: (ca, port, options = {}) ->
|
||||
srv = new Server(ca, port)
|
||||
|
||||
srv
|
||||
.listen(options)
|
||||
.return(srv)
|
||||
}
|
||||
35
packages/https-proxy/lib/util/parse.coffee
Normal file
35
packages/https-proxy/lib/util/parse.coffee
Normal file
@@ -0,0 +1,35 @@
|
||||
url = require("url")
|
||||
|
||||
module.exports = {
|
||||
parseHost: (hostString, defaultPort) ->
|
||||
if m = hostString.match(/^http:\/\/(.*)/)
|
||||
parsedUrl = url.parse(hostString)
|
||||
|
||||
return {
|
||||
host: parsedUrl.hostname
|
||||
port: parsedUrl.port
|
||||
}
|
||||
|
||||
hostPort = hostString.split(':')
|
||||
host = hostPort[0]
|
||||
port = if hostPort.length is 2 then +hostPort[1] else defaultPort
|
||||
|
||||
return {
|
||||
host: host
|
||||
port: port
|
||||
}
|
||||
|
||||
hostAndPort: (reqUrl, headers, defaultPort) ->
|
||||
host = headers.host
|
||||
|
||||
hostPort = @parseHost(host, defaultPort)
|
||||
|
||||
## this handles paths which include the full url. This could happen if it's a proxy
|
||||
if m = reqUrl.match(/^http:\/\/([^\/]*)\/?(.*)$/)
|
||||
parsedUrl = url.parse(reqUrl)
|
||||
hostPort.host = parsedUrl.hostname
|
||||
hostPort.port = parsedUrl.port
|
||||
reqUrl = parsedUrl.path
|
||||
|
||||
hostPort
|
||||
}
|
||||
45
packages/https-proxy/package.json
Normal file
45
packages/https-proxy/package.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@cypress/core-https-proxy",
|
||||
"version": "0.1.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"test": "NODE_ENV=test mocha --watch",
|
||||
"test-ci": "NODE_ENV=test mocha",
|
||||
"https": "node https.js",
|
||||
"release": "releaser"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/cypress-io/cypress-core-https-proxy.git"
|
||||
},
|
||||
"author": "Brian Mann",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/cypress-io/cypress-core-https-proxy/issues"
|
||||
},
|
||||
"homepage": "https://github.com/cypress-io/cypress-core-https-proxy#readme",
|
||||
"devDependencies": {
|
||||
"@cypress/releaser": "0.1.12",
|
||||
"chai": "^3.5.0",
|
||||
"http-mitm-proxy": "^0.5.1",
|
||||
"mocha": "^2.5.3",
|
||||
"request": "^2.72.0",
|
||||
"request-promise": "^3.0.0",
|
||||
"sinon": "^1.17.4",
|
||||
"sinon-as-promised": "^4.0.0",
|
||||
"sinon-chai": "^2.8.0",
|
||||
"supertest": "^1.2.0",
|
||||
"supertest-as-promised": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cypress/coffee-script": "0.1.2",
|
||||
"bluebird": "^3.4.0",
|
||||
"fs-extra": "^0.30.0",
|
||||
"node-forge": "^0.6.39",
|
||||
"semaphore": "^1.0.5",
|
||||
"server-destroy-vvo": "1.0.1",
|
||||
"ssl-root-cas": "^1.1.10"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEHjCCAwagAwIBAgIJALopHKFY/15aMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNV
|
||||
BAYTAlVTMQ0wCwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMa
|
||||
QUNNRSBTaWduaW5nIEF1dGhvcml0eSBJbmMxFDASBgNVBAMTC2V4YW1wbGUuY29t
|
||||
MB4XDTE2MDYwODE3MTExOVoXDTE5MDMyOTE3MTExOVowZzELMAkGA1UEBhMCVVMx
|
||||
DTALBgNVBAgTBFV0YWgxDjAMBgNVBAcTBVByb3ZvMSMwIQYDVQQKExpBQ01FIFNp
|
||||
Z25pbmcgQXV0aG9yaXR5IEluYzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDG/vgku+Ugjy+BtPMGyhoOk89Ef6Cp
|
||||
KintiwE4JI1LkaGJj2cJLBW7qll5fjSXOYbYVsEA5naa7hSfcIjUVidrsGSeDiLd
|
||||
vOc2Vz/Dl163R384TgPBnfQ/OVI5r43/Kjkr2jWXOhvCGIbF1BBSz3aNNBFTgEy8
|
||||
HkFwrxISzInt/GMpXn4eVDPIQpT1SoWNF301vANDPdni51W8ftsMtyKpCWFEsLHA
|
||||
2bznrz2Mzb0BL+FvnrCmyPNTNHlYDZZ4mzUDXs77eO1sWhfM9J8B2tY1TrUwUEjy
|
||||
Ggf1PX9tZr2VLCoEvFRZu6lxbQlVhdkE3ioXQLV83hDn9pUtYbkDD60lAgMBAAGj
|
||||
gcwwgckwHQYDVR0OBBYEFK7xCs6E4Vt/O4KwbJgOHN/pCQT/MIGZBgNVHSMEgZEw
|
||||
gY6AFK7xCs6E4Vt/O4KwbJgOHN/pCQT/oWukaTBnMQswCQYDVQQGEwJVUzENMAsG
|
||||
A1UECBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xIzAhBgNVBAoTGkFDTUUgU2lnbmlu
|
||||
ZyBBdXRob3JpdHkgSW5jMRQwEgYDVQQDEwtleGFtcGxlLmNvbYIJALopHKFY/15a
|
||||
MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAH7EVGG1sxYH0QHbArxu
|
||||
WIqzz79K5egLdnfrvvah/dDcqsJEH7BZSNeIWlBIs47ofVY4xUM/r4hL1TKgIrwq
|
||||
IsKeRql02gNxQPZV7iudGuOBp41cmIxvM+cQsxWmK3Ja/Tf1tE0nsm2L7J+a7ktJ
|
||||
cHJ5yzJA4gY5pVby/TvHzJ5R2BZwd5B+EVRStgxG2Yt4YvvlcDXCxIMzrFYUCmDf
|
||||
AHo7KXsyA/R2mtihSvZEudivbxBt01wKvcAEMeUOsLuEZgSdqFmk3npIhOyHpPSM
|
||||
pHM22Lf0jvz4WeCmgzB0ZinQh1k+E4kxMqP9g+R2dhlZITwL/z5TUdy90fh/iOzD
|
||||
4ek=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAxv74JLvlII8vgbTzBsoaDpPPRH+gqSop7YsBOCSNS5GhiY9n
|
||||
CSwVu6pZeX40lzmG2FbBAOZ2mu4Un3CI1FYna7Bkng4i3bznNlc/w5det0d/OE4D
|
||||
wZ30PzlSOa+N/yo5K9o1lzobwhiGxdQQUs92jTQRU4BMvB5BcK8SEsyJ7fxjKV5+
|
||||
HlQzyEKU9UqFjRd9NbwDQz3Z4udVvH7bDLciqQlhRLCxwNm85689jM29AS/hb56w
|
||||
psjzUzR5WA2WeJs1A17O+3jtbFoXzPSfAdrWNU61MFBI8hoH9T1/bWa9lSwqBLxU
|
||||
WbupcW0JVYXZBN4qF0C1fN4Q5/aVLWG5Aw+tJQIDAQABAoIBAH9KpezJjH3RWfA8
|
||||
kaDsMtLUVidZBKpxYDSlUHhbWU7Xr19RLfW+D4DmLSn8QyPhFpLYm8k5ovDkDqkW
|
||||
0VASdFD8msBIBqGUrsoh8ZXqBBp1T7nynZCCu7SdtC1WURzCI6Qbh2BfOVZlXgC5
|
||||
8F8oeotEnTiuv2cua2nrc0I3OJvUT2AFblIPaCiKeUA6GEQNbe1SbD1VWhfyIMgL
|
||||
59rUNtsq/NI2lS8Be52r5cE/KeEEi5+8p3hXPo0VcmHCU1Oyffidwr9bPcseCTjy
|
||||
aKnzn/8FMmGlVGJ/rJNsuX68a1SQVbECc5ulb9+P9kMOztGAu/gaZJcrJdD8YFTa
|
||||
8gKfDNkCgYEA7ns4+pqguqbZjpPu9ncKI+0exm9gU78AIdHY5hUifkfr2ynaQfu8
|
||||
WlJOtta9K8jUI2N9jN/4ysSxoFUpsGoY7QKpgMF58JH4+HAGUJhUR4xsXu+P2tt+
|
||||
vunWL5LngzreIzxPObqs/83shE+WxkzhHybu1A5Z55yS/VqmHF2gGFcCgYEA1Z0z
|
||||
tA16t6Akb+XQN0wMYlEZp9195gFvri5zlydCqDfS1yf+rsF4oDQ8j90zyHvL/VWQ
|
||||
wrmLlpuBhQz5VpztemlzLNp2/LdtJoBv0SbgbAgN0cWMD1C0R3M7XQXH65WHR7yK
|
||||
urX2eKhmh/XXtclxm7ubC55edyouJwby0oJHqOMCgYEAlD6O/eFPFpgPVz0IZ7c5
|
||||
23lUDyA+7fAmQd+zh9sNdRh6OeO7ZBb7T94oRioYr/YIQPNgoUi83DcG/9bQsnRR
|
||||
iEuGWJ5skan77Vud4U2/3jYhS6Z5cx/Mmxq65RnZxk66tYaQ7R7o2Z8Fbn4XCK/T
|
||||
pUzLW5CMPJitGsbVyX49vcMCgYEAl1bTjanLGpNDnV9lH/gqAfHRSmOa0byMwgu4
|
||||
6wrup709DCASyP7bFi1MBuTBzjUe9bGMaNkJsz8jCP+DG0D84rAY4Fs615qgoxl1
|
||||
nul7MC6Yk9jwfN1BjClwklwJIrgCaumCI/vMzfkJAyRCmlFIwvusQhQGe0iQAChl
|
||||
Go0gdd8CgYAtMQlL6jJn9JpI3o6vZoFoTfGcMId7T8/VSPZ5qMyptP9lh/xDU8QN
|
||||
y92AqG6nYxMY9CRRW1aP0HJRxu/BwKLF6QBid9efntYcT53GUoAqIyiwyjpIzlv2
|
||||
F9RZj0L64mcmJTFvI+kvKrAeZVdUK/Q5OJyTHtOyA9o30LOBWibJ9A==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
AA71608ABEAE0A1B
|
||||
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEHjCCAwagAwIBAgIJALopHKFY/15aMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNV
|
||||
BAYTAlVTMQ0wCwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMa
|
||||
QUNNRSBTaWduaW5nIEF1dGhvcml0eSBJbmMxFDASBgNVBAMTC2V4YW1wbGUuY29t
|
||||
MB4XDTE2MDYwODE3MTExOVoXDTE5MDMyOTE3MTExOVowZzELMAkGA1UEBhMCVVMx
|
||||
DTALBgNVBAgTBFV0YWgxDjAMBgNVBAcTBVByb3ZvMSMwIQYDVQQKExpBQ01FIFNp
|
||||
Z25pbmcgQXV0aG9yaXR5IEluYzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDG/vgku+Ugjy+BtPMGyhoOk89Ef6Cp
|
||||
KintiwE4JI1LkaGJj2cJLBW7qll5fjSXOYbYVsEA5naa7hSfcIjUVidrsGSeDiLd
|
||||
vOc2Vz/Dl163R384TgPBnfQ/OVI5r43/Kjkr2jWXOhvCGIbF1BBSz3aNNBFTgEy8
|
||||
HkFwrxISzInt/GMpXn4eVDPIQpT1SoWNF301vANDPdni51W8ftsMtyKpCWFEsLHA
|
||||
2bznrz2Mzb0BL+FvnrCmyPNTNHlYDZZ4mzUDXs77eO1sWhfM9J8B2tY1TrUwUEjy
|
||||
Ggf1PX9tZr2VLCoEvFRZu6lxbQlVhdkE3ioXQLV83hDn9pUtYbkDD60lAgMBAAGj
|
||||
gcwwgckwHQYDVR0OBBYEFK7xCs6E4Vt/O4KwbJgOHN/pCQT/MIGZBgNVHSMEgZEw
|
||||
gY6AFK7xCs6E4Vt/O4KwbJgOHN/pCQT/oWukaTBnMQswCQYDVQQGEwJVUzENMAsG
|
||||
A1UECBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xIzAhBgNVBAoTGkFDTUUgU2lnbmlu
|
||||
ZyBBdXRob3JpdHkgSW5jMRQwEgYDVQQDEwtleGFtcGxlLmNvbYIJALopHKFY/15a
|
||||
MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAH7EVGG1sxYH0QHbArxu
|
||||
WIqzz79K5egLdnfrvvah/dDcqsJEH7BZSNeIWlBIs47ofVY4xUM/r4hL1TKgIrwq
|
||||
IsKeRql02gNxQPZV7iudGuOBp41cmIxvM+cQsxWmK3Ja/Tf1tE0nsm2L7J+a7ktJ
|
||||
cHJ5yzJA4gY5pVby/TvHzJ5R2BZwd5B+EVRStgxG2Yt4YvvlcDXCxIMzrFYUCmDf
|
||||
AHo7KXsyA/R2mtihSvZEudivbxBt01wKvcAEMeUOsLuEZgSdqFmk3npIhOyHpPSM
|
||||
pHM22Lf0jvz4WeCmgzB0ZinQh1k+E4kxMqP9g+R2dhlZITwL/z5TUdy90fh/iOzD
|
||||
4ek=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwQE+xnWNY3G84R8Pl64K
|
||||
VlbvP4qF8z0jsgCjaZmQWSPEgbPEwYY4NUb/ROZrIiwwo9HSpkfExrfEL2nflv65
|
||||
mMRqyWVB5OgTFdmQTpc0r+YeSS/rSHEg0n+hz3Bugw6JZOFeaBvJQ3xyPQA621tx
|
||||
ahIq0kAfum77aAaX3aFOOn5/IVjY3n4uy2qQGFv3Jh0ix5wnVgrKPldKwBOlLYnu
|
||||
KQJFJmgUhwi4cFugAD6rnvy/vpDav13Ua7KahU6usByLSvw2jTjwYec9wrNxNH7u
|
||||
CjEWAdLnwkVWu803EtLtFn9A29k2LTb96Z/3XsNw4UMAn1PtbVnljgMQrWMFPqMR
|
||||
ywIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEHjCCAwagAwIBAgIJALopHKFY/15aMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNV
|
||||
BAYTAlVTMQ0wCwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMa
|
||||
QUNNRSBTaWduaW5nIEF1dGhvcml0eSBJbmMxFDASBgNVBAMTC2V4YW1wbGUuY29t
|
||||
MB4XDTE2MDYwODE3MTExOVoXDTE5MDMyOTE3MTExOVowZzELMAkGA1UEBhMCVVMx
|
||||
DTALBgNVBAgTBFV0YWgxDjAMBgNVBAcTBVByb3ZvMSMwIQYDVQQKExpBQ01FIFNp
|
||||
Z25pbmcgQXV0aG9yaXR5IEluYzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDG/vgku+Ugjy+BtPMGyhoOk89Ef6Cp
|
||||
KintiwE4JI1LkaGJj2cJLBW7qll5fjSXOYbYVsEA5naa7hSfcIjUVidrsGSeDiLd
|
||||
vOc2Vz/Dl163R384TgPBnfQ/OVI5r43/Kjkr2jWXOhvCGIbF1BBSz3aNNBFTgEy8
|
||||
HkFwrxISzInt/GMpXn4eVDPIQpT1SoWNF301vANDPdni51W8ftsMtyKpCWFEsLHA
|
||||
2bznrz2Mzb0BL+FvnrCmyPNTNHlYDZZ4mzUDXs77eO1sWhfM9J8B2tY1TrUwUEjy
|
||||
Ggf1PX9tZr2VLCoEvFRZu6lxbQlVhdkE3ioXQLV83hDn9pUtYbkDD60lAgMBAAGj
|
||||
gcwwgckwHQYDVR0OBBYEFK7xCs6E4Vt/O4KwbJgOHN/pCQT/MIGZBgNVHSMEgZEw
|
||||
gY6AFK7xCs6E4Vt/O4KwbJgOHN/pCQT/oWukaTBnMQswCQYDVQQGEwJVUzENMAsG
|
||||
A1UECBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xIzAhBgNVBAoTGkFDTUUgU2lnbmlu
|
||||
ZyBBdXRob3JpdHkgSW5jMRQwEgYDVQQDEwtleGFtcGxlLmNvbYIJALopHKFY/15a
|
||||
MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAH7EVGG1sxYH0QHbArxu
|
||||
WIqzz79K5egLdnfrvvah/dDcqsJEH7BZSNeIWlBIs47ofVY4xUM/r4hL1TKgIrwq
|
||||
IsKeRql02gNxQPZV7iudGuOBp41cmIxvM+cQsxWmK3Ja/Tf1tE0nsm2L7J+a7ktJ
|
||||
cHJ5yzJA4gY5pVby/TvHzJ5R2BZwd5B+EVRStgxG2Yt4YvvlcDXCxIMzrFYUCmDf
|
||||
AHo7KXsyA/R2mtihSvZEudivbxBt01wKvcAEMeUOsLuEZgSdqFmk3npIhOyHpPSM
|
||||
pHM22Lf0jvz4WeCmgzB0ZinQh1k+E4kxMqP9g+R2dhlZITwL/z5TUdy90fh/iOzD
|
||||
4ek=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,20 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDRjCCAi4CCQCqcWCKvq4KGzANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJV
|
||||
UzENMAsGA1UECBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xIzAhBgNVBAoTGkFDTUUg
|
||||
U2lnbmluZyBBdXRob3JpdHkgSW5jMRQwEgYDVQQDEwtleGFtcGxlLmNvbTAeFw0x
|
||||
NjA2MDgxNzExMTlaFw0xNzEwMjExNzExMTlaMGMxCzAJBgNVBAYTAlVTMQ0wCwYD
|
||||
VQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEWMBQGA1UEChMNQUNNRSBUZWNoIElu
|
||||
YzEdMBsGA1UEAxMUbG9jYWwubGRzY29ubmVjdC5vcmcwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDBAT7GdY1jcbzhHw+XrgpWVu8/ioXzPSOyAKNpmZBZ
|
||||
I8SBs8TBhjg1Rv9E5msiLDCj0dKmR8TGt8Qvad+W/rmYxGrJZUHk6BMV2ZBOlzSv
|
||||
5h5JL+tIcSDSf6HPcG6DDolk4V5oG8lDfHI9ADrbW3FqEirSQB+6bvtoBpfdoU46
|
||||
fn8hWNjefi7LapAYW/cmHSLHnCdWCso+V0rAE6Utie4pAkUmaBSHCLhwW6AAPque
|
||||
/L++kNq/XdRrspqFTq6wHItK/DaNOPBh5z3Cs3E0fu4KMRYB0ufCRVa7zTcS0u0W
|
||||
f0Db2TYtNv3pn/dew3DhQwCfU+1tWeWOAxCtYwU+oxHLAgMBAAEwDQYJKoZIhvcN
|
||||
AQEFBQADggEBAFmj6aJg1/euvIjfnr4oWoeLKEThPdZDCBwOMesDH3RiZyAQ+UOK
|
||||
kGIIQydgEKWazv8k4FzoPRDf1x1l7/iQofT7pxQgT8Mcv5LBAOPomG2tupaWy0b8
|
||||
B2t4EKFH6AoO6Id48mkWWVMgonVen4rzcPslBi9E92306lnPZEevi9lKT/+hllqX
|
||||
coCNhAuZ4eDS95e7gydPwdMY6P8Azx94buG6DFddSbtDppBy8sb+YOUCGLwwY8zy
|
||||
8JPlk0V2LJLBeFuMAwRb7nULh25x3p+EXbYF3vNvmMdVgLiwvOheCNCTfwkjyotk
|
||||
5+PqZrsL0ci+j0IfLHOBJBcBwjDCk1j7RR4=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAwQE+xnWNY3G84R8Pl64KVlbvP4qF8z0jsgCjaZmQWSPEgbPE
|
||||
wYY4NUb/ROZrIiwwo9HSpkfExrfEL2nflv65mMRqyWVB5OgTFdmQTpc0r+YeSS/r
|
||||
SHEg0n+hz3Bugw6JZOFeaBvJQ3xyPQA621txahIq0kAfum77aAaX3aFOOn5/IVjY
|
||||
3n4uy2qQGFv3Jh0ix5wnVgrKPldKwBOlLYnuKQJFJmgUhwi4cFugAD6rnvy/vpDa
|
||||
v13Ua7KahU6usByLSvw2jTjwYec9wrNxNH7uCjEWAdLnwkVWu803EtLtFn9A29k2
|
||||
LTb96Z/3XsNw4UMAn1PtbVnljgMQrWMFPqMRywIDAQABAoIBAQCmoHCV3f8HD7bF
|
||||
lI9doEAEcmFzNiCW8v3SO4LZNF7O1nZck9sWSM5WEMlprpRnmEcV55w5OlTESvrx
|
||||
BDKopZmOLmUTInxVJ5bykjZn41r1UXJsNRaoICL6GH6WHLcMJoyvr3JV50dHIDVw
|
||||
PLaTksrDjJOzmPDLf+1Ezgxmp1BmZjZQx3rViUs6w+DB8y7zep1R6Brt2KtRuiRo
|
||||
C2QC4y8l8Wl0e2PbZWsNIX/FGZ0HEVSf0KSeztMh4jnMix6SqZWc5GxtpBaOE+7q
|
||||
amgNXZ6NCe5pHX/5TL6xLzTTmcObp7AmGDlUqyNccYZ9OJMcdSte8UbGY9Q3D9Xv
|
||||
wi4VTZ9BAoGBAPCRplUp6GqdDg2/EOUSGI+Uq6MNu5bajGtgcKSVH6rk9bb1qKqT
|
||||
em9EgqZVOcqu1RxoSltxxCXWJBx1VNq2C/Gjv5NtSZG9tYpzgkVhxvu1vF+gCQIm
|
||||
YDSdfbAjsSnw66PZ8K9QN/fsn46O7p2szGdMNER+ZdFaBG7d5/1nxxepAoGBAM1i
|
||||
jVemTg66Q9fovYm//6YOFcJZxqmBoUFGeyZR6Gqkff+DYW2Tl9ACi3lyuijNoXoa
|
||||
niUtHc8DWkfF7oVHCTujwLZfOOuQE2GfCSBsGAM4vsqHmKopXa+Vdgf2SX3Xk4YR
|
||||
ok7hm+9r8KHvhpENFIZynJpB2Y2cfmtfamPVyvZTAoGBAMLMbe/QO475FgQzjy6u
|
||||
dIzvSfyChkAlQEdClHPw/O+Y7w7z5Vwah63JwDGIGX/yCkcye+OIP9iTijIxIEDp
|
||||
4MoOWna6rDQDdhliZz5fao0wIBUetayz/nscfEZA4JihqW3IcIjFYEy1oo4BV17+
|
||||
KZYLstczsqbPSX+s2MntWt3hAoGAUlbqV3Ni4+ClBlBWfH0u3sHS02HulVJU9bht
|
||||
8sTvqqFbqi5fxvBe8pOymvP10hnuXOeC82CNDMtJTHD72Q7Lks9pmTO/vCC8xGxf
|
||||
2lG7pr7/Lm8CM2X2G0iOU07X082zZRJ4wasNOwVJKYK/rjNSQTx9sBIqR+2veRh9
|
||||
rJyvi+UCgYEAlnGa/NxBH9urVxSCk2m3azgxW5sYlxXa9rfuQQBMaRrtmjUzArhZ
|
||||
B5L0vKrV185qZGUflEyAeDxj4aDP9Yp4ksZ46Jcvqosv5FKVwRZU3DpZ/tEaJ0XV
|
||||
K3zgH/422QidN0Ik1gjSjph4jIWfQXENvDvVj0tGDbksrJErvS+jPzc=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
24
packages/https-proxy/test/helpers/http_server.coffee
Normal file
24
packages/https-proxy/test/helpers/http_server.coffee
Normal file
@@ -0,0 +1,24 @@
|
||||
http = require("http")
|
||||
Promise = require("bluebird")
|
||||
|
||||
srv = http.createServer (req, res) ->
|
||||
console.log "HTTP SERVER REQUEST URL:", req.url
|
||||
console.log "HTTP SERVER REQUEST HEADERS:", req.headers
|
||||
|
||||
res.setHeader("Content-Type", "text/html")
|
||||
res.writeHead(200)
|
||||
res.end("<html><body>http server</body></html>")
|
||||
|
||||
module.exports = {
|
||||
srv: srv
|
||||
|
||||
start: ->
|
||||
new Promise (resolve) ->
|
||||
srv.listen 8080, ->
|
||||
console.log "server listening on port: 8080"
|
||||
resolve(srv)
|
||||
|
||||
stop: ->
|
||||
new Promise (resolve) ->
|
||||
srv.close(resolve)
|
||||
}
|
||||
48
packages/https-proxy/test/helpers/https_server.coffee
Normal file
48
packages/https-proxy/test/helpers/https_server.coffee
Normal file
@@ -0,0 +1,48 @@
|
||||
fs = require("fs")
|
||||
path = require("path")
|
||||
https = require("https")
|
||||
Promise = require("bluebird")
|
||||
sslRootCas = require('ssl-root-cas')
|
||||
allowDestroy = require("server-destroy-vvo")
|
||||
|
||||
sslRootCas
|
||||
.inject()
|
||||
.addFile(path.join(__dirname, "certs", "server", "my-root-ca.crt.pem"))
|
||||
|
||||
options = {
|
||||
key: fs.readFileSync(path.join(__dirname, "certs", "server", "my-server.key.pem"))
|
||||
cert: fs.readFileSync(path.join(__dirname, "certs", "server", "my-server.crt.pem"))
|
||||
}
|
||||
|
||||
onRequest = (req, res) ->
|
||||
console.log "HTTPS SERVER REQUEST URL:", req.url
|
||||
console.log "HTTPS SERVER REQUEST HEADERS:", req.headers
|
||||
|
||||
res.setHeader("Content-Type", "text/html")
|
||||
res.writeHead(200)
|
||||
res.end("<html><head></head><body>https server</body></html>")
|
||||
|
||||
servers = []
|
||||
|
||||
module.exports = {
|
||||
start: (port) ->
|
||||
new Promise (resolve) ->
|
||||
srv = https.createServer(options, onRequest)
|
||||
|
||||
allowDestroy(srv)
|
||||
|
||||
servers.push(srv)
|
||||
|
||||
srv.listen port, ->
|
||||
console.log "server listening on port: #{port}"
|
||||
resolve(srv)
|
||||
|
||||
stop: ->
|
||||
stop = (srv) ->
|
||||
new Promise (resolve) ->
|
||||
srv.destroy(resolve)
|
||||
|
||||
Promise.map(servers, stop)
|
||||
.then ->
|
||||
servers = []
|
||||
}
|
||||
17
packages/https-proxy/test/helpers/mitm.coffee
Normal file
17
packages/https-proxy/test/helpers/mitm.coffee
Normal file
@@ -0,0 +1,17 @@
|
||||
Promise = require("bluebird")
|
||||
|
||||
Proxy = require("http-mitm-proxy")
|
||||
proxy = Proxy()
|
||||
|
||||
proxy.onRequest (ctx, cb) ->
|
||||
cb()
|
||||
|
||||
module.exports = {
|
||||
start: ->
|
||||
new Promise (resolve) ->
|
||||
proxy.listen({port: 8081, forceSNI: true}, resolve)
|
||||
|
||||
stop: ->
|
||||
proxy.close()
|
||||
|
||||
}
|
||||
67
packages/https-proxy/test/helpers/proxy.coffee
Normal file
67
packages/https-proxy/test/helpers/proxy.coffee
Normal file
@@ -0,0 +1,67 @@
|
||||
http = require("http")
|
||||
path = require("path")
|
||||
httpsProxy = require("../../lib/proxy")
|
||||
|
||||
prx = null
|
||||
|
||||
pipe = (req, res) ->
|
||||
req.pipe(request(req.url))
|
||||
.on "error", ->
|
||||
console.log "**ERROR**", req.url
|
||||
req.statusCode = 500
|
||||
res.end()
|
||||
.pipe(res)
|
||||
|
||||
onConnect = (req, socket, head, proxy) ->
|
||||
proxy.connect(req, socket, head, {
|
||||
onDirectConnection: (req, socket, head) ->
|
||||
req.url is "localhost:8444"
|
||||
})
|
||||
|
||||
onRequest = (req, res) ->
|
||||
pipe(req, res)
|
||||
|
||||
module.exports = {
|
||||
reset: ->
|
||||
httpsProxy.reset()
|
||||
|
||||
start: (port) ->
|
||||
prx = http.createServer()
|
||||
|
||||
dir = path.join(process.cwd(), "ca")
|
||||
|
||||
httpsProxy.create(dir, port, {
|
||||
onUpgrade: (req, socket, head) ->
|
||||
|
||||
onRequest: (req, res) ->
|
||||
console.log "ON REQUEST FROM OUTER PROXY", req.url, req.headers, req.method
|
||||
|
||||
if req.url.includes("replace")
|
||||
write = res.write
|
||||
res.write = (chunk) ->
|
||||
chunk = new Buffer(chunk.toString().replace("https server", "replaced content"))
|
||||
|
||||
write.call(@, chunk)
|
||||
|
||||
pipe(req, res)
|
||||
else
|
||||
pipe(req, res)
|
||||
})
|
||||
.then (proxy) =>
|
||||
prx.on "request", onRequest
|
||||
|
||||
prx.on "connect", (req, socket, head) ->
|
||||
onConnect(req, socket, head, proxy)
|
||||
|
||||
new Promise (resolve) ->
|
||||
prx.listen port, ->
|
||||
prx.proxy = proxy
|
||||
console.log "server listening on port: #{port}"
|
||||
resolve(proxy)
|
||||
|
||||
stop: ->
|
||||
new Promise (resolve) ->
|
||||
prx.close(resolve)
|
||||
.then ->
|
||||
prx.proxy.close()
|
||||
}
|
||||
284
packages/https-proxy/test/helpers/proxy_bak.coffee
Normal file
284
packages/https-proxy/test/helpers/proxy_bak.coffee
Normal file
@@ -0,0 +1,284 @@
|
||||
fs = require("fs-extra")
|
||||
net = require("net")
|
||||
url = require("url")
|
||||
path = require("path")
|
||||
http = require("http")
|
||||
https = require("https")
|
||||
request = require("request")
|
||||
Promise = require("bluebird")
|
||||
sempahore = require("semaphore")
|
||||
CA = require("../../lib/ca")
|
||||
|
||||
Promise.promisifyAll(fs)
|
||||
|
||||
ca = null
|
||||
httpsSrv = null
|
||||
httpsPort = null
|
||||
|
||||
sslServers = {}
|
||||
sslSemaphores = {}
|
||||
|
||||
onClientError = (err) ->
|
||||
console.log "CLIENT ERROR", err
|
||||
|
||||
onError = (err) ->
|
||||
console.log "ERROR", err
|
||||
|
||||
onRequest = (req, res) ->
|
||||
console.log "onRequest!!!!!!!!!", req.url, req.headers, req.method
|
||||
|
||||
hostPort = parseHostAndPort(req)
|
||||
|
||||
# req.pause()
|
||||
|
||||
opts = {
|
||||
url: req.url
|
||||
baseUrl: "https://" + hostPort.host + ":" + hostPort.port
|
||||
method: req.method
|
||||
headers: req.headers
|
||||
}
|
||||
|
||||
req.pipe(request(opts))
|
||||
.on "error", ->
|
||||
console.log "**ERROR", req.url
|
||||
res.statusCode = 500
|
||||
res.end()
|
||||
.pipe(res)
|
||||
|
||||
parseHostAndPort = (req, defaultPort) ->
|
||||
host = req.headers.host
|
||||
|
||||
return null if not host
|
||||
|
||||
hostPort = parseHost(host, defaultPort)
|
||||
|
||||
## this handles paths which include the full url. This could happen if it's a proxy
|
||||
if m = req.url.match(/^http:\/\/([^\/]*)\/?(.*)$/)
|
||||
parsedUrl = url.parse(req.url)
|
||||
hostPort.host = parsedUrl.hostname
|
||||
hostPort.port = parsedUrl.port
|
||||
req.url = parsedUrl.path
|
||||
|
||||
hostPort
|
||||
|
||||
parseHost = (hostString, defaultPort) ->
|
||||
if m = hostString.match(/^http:\/\/(.*)/)
|
||||
parsedUrl = url.parse(hostString)
|
||||
|
||||
return {
|
||||
host: parsedUrl.hostname
|
||||
port: parsedUrl.port
|
||||
}
|
||||
|
||||
hostPort = hostString.split(':')
|
||||
host = hostPort[0]
|
||||
port = if hostPort.length is 2 then +hostPort[1] else defaultPort
|
||||
|
||||
return {
|
||||
host: host
|
||||
port: port
|
||||
}
|
||||
|
||||
onConnect = (req, socket, head) ->
|
||||
console.log "ON CONNECT!!!!!!!!!!!!!!!"
|
||||
## tell the client that the connection is established
|
||||
# socket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', function() {
|
||||
# // creating pipes in both ends
|
||||
# conn.pipe(socket);
|
||||
# socket.pipe(conn);
|
||||
# });
|
||||
|
||||
console.log "URL", req.url
|
||||
console.log "HEADERS", req.headers
|
||||
console.log "HEAD IS", head
|
||||
console.log "HEAD LENGTH", head.length
|
||||
|
||||
# srvUrl = url.parse("http://#{req.url}")
|
||||
|
||||
# conn = null
|
||||
|
||||
# cb = ->
|
||||
# socket.write('HTTP/1.1 200 Connection Established\r\n' +
|
||||
# 'Proxy-agent: Cypress\r\n' +
|
||||
# '\r\n')
|
||||
# conn.write(head)
|
||||
# conn.pipe(socket)
|
||||
# socket.pipe(conn)
|
||||
|
||||
# conn = net.connect(srvUrl.port, srvUrl.hostname, cb)
|
||||
|
||||
# conn.on "error", (err) ->
|
||||
# ## TODO: attach error handling here
|
||||
# console.log "*******ERROR CONNECTING", err, err.stack
|
||||
|
||||
# # conn.on "close", ->
|
||||
# # console.log "CONNECTION CLOSED", arguments
|
||||
|
||||
# return
|
||||
|
||||
# URL www.cypress.io:443
|
||||
# HEADERS { host: 'www.cypress.io:443',
|
||||
# 'proxy-connection': 'keep-alive',
|
||||
# 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2609.0 Safari/537.36' }
|
||||
# HEAD IS <Buffer >
|
||||
# HEAD LENGTH 0
|
||||
|
||||
getHttpsServer = (hostname) ->
|
||||
onCertificateRequired(hostname)
|
||||
.then (certPaths) ->
|
||||
Promise.props({
|
||||
keyFileExists: fs.statAsync(certPaths.keyFile)
|
||||
certFileExists: fs.statAsync(certPaths.certFile)
|
||||
})
|
||||
.catch (err) ->
|
||||
onCertificateMissing(certPaths)
|
||||
.then (data = {}) ->
|
||||
return {
|
||||
key: data.keyFileData
|
||||
cert: data.certFileData
|
||||
hosts: data.hosts
|
||||
}
|
||||
.then (data = {}) ->
|
||||
hosts = [hostname]
|
||||
delete data.hosts
|
||||
|
||||
hosts.forEach (host) ->
|
||||
console.log "ADD CONTEXT", host, data
|
||||
httpsSrv.addContext(host, data)
|
||||
# sslServers[host] = { port: httpsPort }
|
||||
|
||||
# return cb(null, self.httpsPort)
|
||||
|
||||
return httpsPort
|
||||
|
||||
onCertificateMissing = (certPaths) ->
|
||||
hosts = certPaths.hosts #or [ctx.hostname]
|
||||
|
||||
ca.generateServerCertificateKeys(hosts)
|
||||
.spread (certPEM, privateKeyPEM) ->
|
||||
return {
|
||||
hosts: hosts
|
||||
keyFileData: privateKeyPEM
|
||||
certFileData: certPEM
|
||||
}
|
||||
|
||||
onCertificateRequired = (hostname) ->
|
||||
Promise.resolve({
|
||||
keyFile: ""
|
||||
certFile: ""
|
||||
hosts: [hostname]
|
||||
})
|
||||
|
||||
makeConnection = (port) ->
|
||||
console.log "makeConnection", port
|
||||
conn = net.connect port, ->
|
||||
console.log "connected to", port#, socket, conn, head
|
||||
socket.pipe(conn)
|
||||
conn.pipe(socket)
|
||||
socket.emit("data", head)
|
||||
|
||||
return socket.resume()
|
||||
|
||||
conn.on "error", onError
|
||||
|
||||
onServerConnectData = (head) ->
|
||||
firstBytes = head[0]
|
||||
|
||||
if firstBytes is 0x16 or firstBytes is 0x80 or firstBytes is 0x00
|
||||
{hostname} = url.parse("http://#{req.url}")
|
||||
|
||||
if sslServer = sslServers[hostname]
|
||||
return makeConnection(sslServer.port)
|
||||
|
||||
wildcardhost = hostname.replace(/[^\.]+\./, "*.")
|
||||
|
||||
sem = sslSemaphores[wildcardhost]
|
||||
|
||||
if not sem
|
||||
sem = sslSemaphores[wildcardhost] = sempahore(1)
|
||||
|
||||
sem.take ->
|
||||
leave = ->
|
||||
process.nextTick ->
|
||||
console.log "leaving sem"
|
||||
sem.leave()
|
||||
|
||||
if sslServer = sslServers[hostname]
|
||||
leave()
|
||||
return makeConnection(sslServer.port)
|
||||
|
||||
if sslServer = sslServers[wildcardhost]
|
||||
leave()
|
||||
sslServers[hostname] = {
|
||||
port: sslServer
|
||||
}
|
||||
|
||||
return makeConnection(sslServers[hostname].port)
|
||||
|
||||
getHttpsServer(hostname)
|
||||
.then (port) ->
|
||||
leave()
|
||||
|
||||
makeConnection(port)
|
||||
|
||||
else
|
||||
throw new Error("@httpPort")
|
||||
makeConnection(@httpPort)
|
||||
|
||||
if not head or head.length is 0
|
||||
socket.once "data", onConnect.bind(@, req, socket)
|
||||
|
||||
socket.write "HTTP/1.1 200 OK\r\n"
|
||||
|
||||
if req.headers["proxy-connection"] is "keep-alive"
|
||||
socket.write("Proxy-Connection: keep-alive\r\n")
|
||||
socket.write("Connection: keep-alive\r\n")
|
||||
|
||||
return socket.write("\r\n")
|
||||
|
||||
else
|
||||
socket.pause()
|
||||
|
||||
onServerConnectData(head)
|
||||
|
||||
prx = http.createServer()
|
||||
|
||||
prx.on("connect", onConnect)
|
||||
prx.on("request", onRequest)
|
||||
prx.on("clientError", onClientError)
|
||||
prx.on("error", onError)
|
||||
|
||||
module.exports = {
|
||||
prx: prx
|
||||
|
||||
startHttpsSrv: ->
|
||||
new Promise (resolve) ->
|
||||
httpsSrv = https.createServer({})
|
||||
# httpsSrv.timeout = 0
|
||||
httpsSrv.on("connect", onConnect)
|
||||
httpsSrv.on("request", onRequest)
|
||||
httpsSrv.on("clientError", onClientError)
|
||||
httpsSrv.on("error", onError)
|
||||
httpsSrv.listen ->
|
||||
resolve([httpsSrv.address().port, httpsSrv])
|
||||
|
||||
start: ->
|
||||
dir = path.join(process.cwd(), "ca")
|
||||
|
||||
CA.create(dir)
|
||||
.then (c) =>
|
||||
ca = c
|
||||
|
||||
@startHttpsSrv()
|
||||
.spread (port, httpsSrv) ->
|
||||
httpsPort = port
|
||||
|
||||
new Promise (resolve) ->
|
||||
prx.listen 3333, ->
|
||||
console.log "server listening on port: 3333"
|
||||
resolve(prx)
|
||||
|
||||
stop: ->
|
||||
new Promise (resolve) ->
|
||||
prx.close(resolve)
|
||||
}
|
||||
138
packages/https-proxy/test/integration/proxy_spec.coffee
Normal file
138
packages/https-proxy/test/integration/proxy_spec.coffee
Normal file
@@ -0,0 +1,138 @@
|
||||
require("../spec_helper")
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
|
||||
|
||||
path = require("path")
|
||||
Promise = require("bluebird")
|
||||
proxy = require("../helpers/proxy")
|
||||
mitmProxy = require("../helpers/mitm")
|
||||
httpServer = require("../helpers/http_server")
|
||||
httpsServer = require("../helpers/https_server")
|
||||
|
||||
describe "Proxy", ->
|
||||
beforeEach ->
|
||||
Promise.join(
|
||||
httpServer.start()
|
||||
|
||||
# mitmProxy.start()
|
||||
|
||||
httpsServer.start(8443)
|
||||
|
||||
httpsServer.start(8444)
|
||||
|
||||
proxy.start(3333)
|
||||
.then (@proxy) =>
|
||||
)
|
||||
|
||||
afterEach ->
|
||||
Promise.join(
|
||||
httpServer.stop()
|
||||
httpsServer.stop()
|
||||
proxy.stop()
|
||||
)
|
||||
|
||||
it "can request the googles", ->
|
||||
Promise.all([
|
||||
request({
|
||||
strictSSL: false
|
||||
proxy: "http://localhost:3333"
|
||||
url: "https://www.google.com"
|
||||
})
|
||||
|
||||
request({
|
||||
strictSSL: false
|
||||
proxy: "http://localhost:3333"
|
||||
url: "https://mail.google.com"
|
||||
})
|
||||
|
||||
request({
|
||||
strictSSL: false
|
||||
proxy: "http://localhost:3333"
|
||||
url: "https://google.com"
|
||||
})
|
||||
])
|
||||
|
||||
it "can call the httpsDirectly without a proxy", ->
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8443"
|
||||
})
|
||||
|
||||
it "can boot the httpsServer", ->
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8443/"
|
||||
proxy: "http://localhost:3333"
|
||||
})
|
||||
.then (html) ->
|
||||
expect(html).to.include("https server")
|
||||
|
||||
it "yields the onRequest callback", ->
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8443/replace"
|
||||
proxy: "http://localhost:3333"
|
||||
})
|
||||
.then (html) ->
|
||||
expect(html).to.include("replaced content")
|
||||
|
||||
it "can pass directly through", ->
|
||||
## this will fail due to dynamic cert
|
||||
## generation when strict ssl is true
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8444/replace"
|
||||
proxy: "http://localhost:3333"
|
||||
})
|
||||
.then (html) ->
|
||||
expect(html).to.include("https server")
|
||||
|
||||
it "can boot the httpServer", ->
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "http://localhost:8080/"
|
||||
proxy: "http://localhost:3333"
|
||||
})
|
||||
.then (html) ->
|
||||
expect(html).to.include("http server")
|
||||
|
||||
context "generating certificates", ->
|
||||
it "reuses existing certificates", ->
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8443/"
|
||||
proxy: "http://localhost:3333"
|
||||
})
|
||||
.then =>
|
||||
proxy.reset()
|
||||
|
||||
## force this to reject if its called
|
||||
@sandbox.stub(@proxy, "_generateMissingCertificates").rejects(new Error("should not call"))
|
||||
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8443/"
|
||||
proxy: "http://localhost:3333"
|
||||
})
|
||||
|
||||
context "closing", ->
|
||||
it "resets sslServers and can reopen", ->
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8443/"
|
||||
proxy: "http://localhost:3333"
|
||||
})
|
||||
.then =>
|
||||
proxy.stop()
|
||||
.then =>
|
||||
proxy.start(3333)
|
||||
.then =>
|
||||
## force this to reject if its called
|
||||
@sandbox.stub(@proxy, "_generateMissingCertificates").rejects(new Error("should not call"))
|
||||
|
||||
request({
|
||||
strictSSL: false
|
||||
url: "https://localhost:8443/"
|
||||
proxy: "http://localhost:3333"
|
||||
})
|
||||
|
||||
5
packages/https-proxy/test/mocha.opts
Normal file
5
packages/https-proxy/test/mocha.opts
Normal file
@@ -0,0 +1,5 @@
|
||||
test/unit
|
||||
test/integration
|
||||
--reporter spec
|
||||
--compilers coffee:@cypress/coffee-script
|
||||
--recursive
|
||||
18
packages/https-proxy/test/spec_helper.coffee
Normal file
18
packages/https-proxy/test/spec_helper.coffee
Normal file
@@ -0,0 +1,18 @@
|
||||
chai = require("chai")
|
||||
sinon = require("sinon")
|
||||
Promise = require("bluebird")
|
||||
sinonChai = require("sinon-chai")
|
||||
sinonPromise = require("sinon-as-promised")(Promise)
|
||||
|
||||
global.request = require("request-promise")
|
||||
global.supertest = require("supertest-as-promised")(Promise)
|
||||
|
||||
chai.use(sinonChai)
|
||||
|
||||
global.expect = chai.expect
|
||||
|
||||
beforeEach ->
|
||||
@sandbox = sinon.sandbox.create()
|
||||
|
||||
afterEach ->
|
||||
@sandbox.restore()
|
||||
76
packages/https-proxy/test/unit/ca_spec.coffee
Normal file
76
packages/https-proxy/test/unit/ca_spec.coffee
Normal file
@@ -0,0 +1,76 @@
|
||||
require("../spec_helper")
|
||||
|
||||
fs = require("fs-extra")
|
||||
path = require("path")
|
||||
Promise = require("bluebird")
|
||||
CA = require("../../lib/ca")
|
||||
|
||||
fs = Promise.promisifyAll(fs)
|
||||
|
||||
describe "lib/ca", ->
|
||||
beforeEach ->
|
||||
@timeout(5000)
|
||||
|
||||
@dir = path.join(process.cwd(), "tmp")
|
||||
|
||||
fs.ensureDirAsync(@dir)
|
||||
.then =>
|
||||
CA.create(@dir)
|
||||
.then (@ca) =>
|
||||
|
||||
afterEach ->
|
||||
fs.removeAsync(@dir)
|
||||
|
||||
context "#generateServerCertificateKeys", ->
|
||||
it "generates certs for each host", ->
|
||||
@ca.generateServerCertificateKeys("www.cypress.io")
|
||||
.spread (certPem, keyPrivatePem) ->
|
||||
expect(certPem).to.include("-----BEGIN CERTIFICATE-----")
|
||||
expect(keyPrivatePem).to.include("-----BEGIN RSA PRIVATE KEY-----")
|
||||
|
||||
context ".create", ->
|
||||
it "returns a new CA instance", ->
|
||||
expect(@ca).to.be.an.instanceof(CA)
|
||||
|
||||
it "creates certs + keys dir", ->
|
||||
Promise.join(
|
||||
fs.statAsync(path.join(@dir, "certs"))
|
||||
fs.statAsync(path.join(@dir, "keys"))
|
||||
)
|
||||
|
||||
it "writes certs/ca.pem", ->
|
||||
fs.statAsync(path.join(@dir, "certs", "ca.pem"))
|
||||
|
||||
it "writes keys/ca.private.key", ->
|
||||
fs.statAsync(path.join(@dir, "keys", "ca.private.key"))
|
||||
|
||||
it "writes keys/ca.public.key", ->
|
||||
fs.statAsync(path.join(@dir, "keys", "ca.public.key"))
|
||||
|
||||
it "sets ca.CAcert", ->
|
||||
expect(@ca.CAcert).to.be.an("object")
|
||||
|
||||
it "sets ca.CAkeys", ->
|
||||
expect(@ca.CAkeys).to.be.an("object")
|
||||
expect(@ca.CAkeys).to.have.a.property("privateKey")
|
||||
expect(@ca.CAkeys).to.have.a.property("publicKey")
|
||||
|
||||
describe "existing CA folder", ->
|
||||
beforeEach ->
|
||||
@sandbox.spy(CA.prototype, "loadCA")
|
||||
@sandbox.spy(CA.prototype, "generateCA")
|
||||
|
||||
CA.create(@dir)
|
||||
.then (@ca2) =>
|
||||
|
||||
it "calls loadCA and not generateCA", ->
|
||||
expect(CA.prototype.loadCA).to.be.calledOnce
|
||||
expect(CA.prototype.generateCA).not.to.be.called
|
||||
|
||||
it "sets ca.CAcert", ->
|
||||
expect(@ca2.CAcert).to.be.an("object")
|
||||
|
||||
it "sets ca.CAkeys", ->
|
||||
expect(@ca2.CAkeys).to.be.an("object")
|
||||
expect(@ca2.CAkeys).to.have.a.property("privateKey")
|
||||
expect(@ca2.CAkeys).to.have.a.property("publicKey")
|
||||
51
packages/https-proxy/test/unit/server_spec.coffee
Normal file
51
packages/https-proxy/test/unit/server_spec.coffee
Normal file
@@ -0,0 +1,51 @@
|
||||
require("../spec_helper")
|
||||
|
||||
Promise = require("bluebird")
|
||||
proxy = require("../helpers/proxy")
|
||||
Server = require("../../lib/server")
|
||||
|
||||
describe "lib/server", ->
|
||||
beforeEach ->
|
||||
@setup = (options = {}) =>
|
||||
@ca = {}
|
||||
@port = 12345
|
||||
|
||||
Server.create(@ca, @port, options)
|
||||
|
||||
context "#listen", ->
|
||||
it "calls options.onUpgrade with req, socket head", ->
|
||||
onUpgrade = @sandbox.stub()
|
||||
|
||||
@setup({onUpgrade: onUpgrade})
|
||||
.then (srv) ->
|
||||
srv._sniServer.emit("upgrade", 1, 2, 3)
|
||||
|
||||
expect(onUpgrade).to.be.calledWith(1,2,3)
|
||||
|
||||
it "calls options.onRequest with req, res", ->
|
||||
onRequest = @sandbox.stub()
|
||||
req = {url: "https://www.foobar.com", headers: {host: "www.foobar.com"}}
|
||||
res = {}
|
||||
|
||||
@setup({onRequest: onRequest})
|
||||
.then (srv) ->
|
||||
srv._sniServer.emit("request", req, res)
|
||||
|
||||
expect(onRequest).to.be.calledWith(req, res)
|
||||
|
||||
it "calls options.onError with err and port", (done) ->
|
||||
onError = @sandbox.stub()
|
||||
socket = {}
|
||||
head = {}
|
||||
|
||||
@setup({onError: onError})
|
||||
.then (srv) ->
|
||||
conn = srv._makeDirectConnection({url: "localhost:8444"}, socket, head)
|
||||
|
||||
conn.once "error", ->
|
||||
err = onError.getCall(0).args[0]
|
||||
expect(err.message).to.eq("connect ECONNREFUSED 127.0.0.1:8444")
|
||||
|
||||
expect(onError).to.be.calledWithMatch(err, socket, head, 8444)
|
||||
|
||||
done()
|
||||
Reference in New Issue
Block a user