var httpProxy = require('../lib/http-proxy'), semver = require('semver'), expect = require('expect.js'), http = require('http') https = require('https'), path = require('path'), fs = require('fs'); // // Expose a port number generator. // thanks to @3rd-Eden // var initialPort = 1024, gen = {}; Object.defineProperty(gen, 'port', { get: function get() { return initialPort++; } }); describe('lib/http-proxy.js', function() { describe('HTTPS #createProxyServer', function() { describe('HTTPS to HTTP', function () { it('should proxy the request en send back the response', function (done) { var ports = { source: gen.port, proxy: gen.port }; var source = http.createServer(function(req, res) { expect(req.method).to.eql('GET'); expect(req.headers.host.split(':')[1]).to.eql(ports.proxy); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello from ' + ports.source); }); source.listen(ports.source); var proxy = httpProxy.createProxyServer({ target: 'http://127.0.0.1:' + ports.source, ssl: { key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')), cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')), ciphers: 'AES128-GCM-SHA256', } }).listen(ports.proxy); https.request({ host: 'localhost', port: ports.proxy, path: '/', method: 'GET', rejectUnauthorized: false }, function(res) { expect(res.statusCode).to.eql(200); res.on('data', function (data) { expect(data.toString()).to.eql('Hello from ' + ports.source); }); res.on('end', function () { source.close(); proxy.close(); done(); }) }).end(); }) }); describe('HTTP to HTTPS', function () { it('should proxy the request en send back the response', function (done) { var ports = { source: gen.port, proxy: gen.port }; var source = https.createServer({ key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')), cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')), ciphers: 'AES128-GCM-SHA256', }, function (req, res) { expect(req.method).to.eql('GET'); expect(req.headers.host.split(':')[1]).to.eql(ports.proxy); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello from ' + ports.source); }); source.listen(ports.source); var proxy = httpProxy.createProxyServer({ target: 'https://127.0.0.1:' + ports.source, // Allow to use SSL self signed secure: false }).listen(ports.proxy); http.request({ hostname: '127.0.0.1', port: ports.proxy, method: 'GET' }, function(res) { expect(res.statusCode).to.eql(200); res.on('data', function (data) { expect(data.toString()).to.eql('Hello from ' + ports.source); }); res.on('end', function () { source.close(); proxy.close(); done(); }); }).end(); }) }) describe('HTTPS to HTTPS', function () { it('should proxy the request en send back the response', function (done) { var ports = { source: gen.port, proxy: gen.port }; var source = https.createServer({ key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')), cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')), ciphers: 'AES128-GCM-SHA256', }, function(req, res) { expect(req.method).to.eql('GET'); expect(req.headers.host.split(':')[1]).to.eql(ports.proxy); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello from ' + ports.source); }); source.listen(ports.source); var proxy = httpProxy.createProxyServer({ target: 'https://127.0.0.1:' + ports.source, ssl: { key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')), cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')), ciphers: 'AES128-GCM-SHA256', }, secure: false }).listen(ports.proxy); https.request({ host: 'localhost', port: ports.proxy, path: '/', method: 'GET', rejectUnauthorized: false }, function(res) { expect(res.statusCode).to.eql(200); res.on('data', function (data) { expect(data.toString()).to.eql('Hello from ' + ports.source); }); res.on('end', function () { source.close(); proxy.close(); done(); }) }).end(); }) }); describe('HTTPS not allow SSL self signed', function () { it('should fail with error', function (done) { var ports = { source: gen.port, proxy: gen.port }; var source = https.createServer({ key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')), cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')), ciphers: 'AES128-GCM-SHA256', }).listen(ports.source); var proxy = httpProxy.createProxyServer({ target: 'https://127.0.0.1:' + ports.source, secure: true }); proxy.listen(ports.proxy); proxy.on('error', function (err, req, res) { expect(err).to.be.an(Error); if (semver.gt(process.versions.node, '0.12.0')) { expect(err.toString()).to.be('Error: unable to verify the first certificate') } else { expect(err.toString()).to.be('Error: DEPTH_ZERO_SELF_SIGNED_CERT') } done(); }) http.request({ hostname: '127.0.0.1', port: ports.proxy, method: 'GET' }).end(); }) }) describe('HTTPS to HTTP using own server', function () { it('should proxy the request en send back the response', function (done) { var ports = { source: gen.port, proxy: gen.port }; var source = http.createServer(function(req, res) { expect(req.method).to.eql('GET'); expect(req.headers.host.split(':')[1]).to.eql(ports.proxy); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello from ' + ports.source); }); source.listen(ports.source); var proxy = httpProxy.createServer({ agent: new http.Agent({ maxSockets: 2 }) }); var ownServer = https.createServer({ key: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-key.pem')), cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'agent2-cert.pem')), ciphers: 'AES128-GCM-SHA256', }, function (req, res) { proxy.web(req, res, { target: 'http://127.0.0.1:' + ports.source }) }).listen(ports.proxy); https.request({ host: 'localhost', port: ports.proxy, path: '/', method: 'GET', rejectUnauthorized: false }, function(res) { expect(res.statusCode).to.eql(200); res.on('data', function (data) { expect(data.toString()).to.eql('Hello from ' + ports.source); }); res.on('end', function () { source.close(); ownServer.close(); done(); }) }).end(); }) }) }); });