1 | var http = require('http');
|
2 | var https = require('https');
|
3 | var net = require('net');
|
4 | var fs = require('fs');
|
5 | var path = require('path');
|
6 | var should = require('should');
|
7 | var tunnel = require('../index.js');
|
8 |
|
9 | function readPem(file) {
|
10 | return fs.readFileSync(path.join('test/keys', file + '.pem'));
|
11 | }
|
12 |
|
13 | var serverKey = readPem('server1-key');
|
14 | var serverCert = readPem('server1-cert');
|
15 | var serverCA = readPem('ca1-cert');
|
16 | var proxyKey = readPem('proxy1-key');
|
17 | var proxyCert = readPem('proxy1-cert');
|
18 | var proxyCA = readPem('ca2-cert');
|
19 | var client1Key = readPem('client1-key');
|
20 | var client1Cert = readPem('client1-cert');
|
21 | var client1CA = readPem('ca3-cert');
|
22 | var client2Key = readPem('client2-key');
|
23 | var client2Cert = readPem('client2-cert');
|
24 | var client2CA = readPem('ca4-cert');
|
25 |
|
26 | describe('HTTPS over HTTPS', function() {
|
27 | it('should finish without error', function(done) {
|
28 | var serverPort = 3006;
|
29 | var proxyPort = 3007;
|
30 | var poolSize = 3;
|
31 | var N = 5;
|
32 | var serverConnect = 0;
|
33 | var proxyConnect = 0;
|
34 | var clientConnect = 0;
|
35 | var server;
|
36 | var proxy;
|
37 | var agent;
|
38 |
|
39 | server = https.createServer({
|
40 | key: serverKey,
|
41 | cert: serverCert,
|
42 | ca: [client1CA],
|
43 | requestCert: true,
|
44 | rejectUnauthorized: true
|
45 | }, function(req, res) {
|
46 | tunnel.debug('SERVER: got request');
|
47 | ++serverConnect;
|
48 | res.writeHead(200);
|
49 | res.end('Hello' + req.url);
|
50 | tunnel.debug('SERVER: sending response');
|
51 | });
|
52 | server.listen(serverPort, setupProxy);
|
53 |
|
54 | function setupProxy() {
|
55 | proxy = https.createServer({
|
56 | key: proxyKey,
|
57 | cert: proxyCert,
|
58 | ca: [client2CA],
|
59 | requestCert: true,
|
60 | rejectUnauthorized: true
|
61 | }, function(req, res) {
|
62 | should.fail();
|
63 | });
|
64 | proxy.on('upgrade', onConnect);
|
65 | proxy.on('connect', onConnect);
|
66 |
|
67 | function onConnect(req, clientSocket, head) {
|
68 | tunnel.debug('PROXY: got CONNECT request');
|
69 | req.method.should.equal('CONNECT');
|
70 | req.url.should.equal('localhost:' + serverPort);
|
71 | req.headers.should.not.have.property('transfer-encoding');
|
72 | ++proxyConnect;
|
73 |
|
74 | var serverSocket = net.connect(serverPort, function() {
|
75 | tunnel.debug('PROXY: replying to client CONNECT request');
|
76 | clientSocket.write('HTTP/1.1 200 Connection established\r\n\r\n');
|
77 | clientSocket.pipe(serverSocket);
|
78 | serverSocket.write(head);
|
79 | serverSocket.pipe(clientSocket);
|
80 |
|
81 | serverSocket.on('end', function() {
|
82 | clientSocket.end();
|
83 | });
|
84 | });
|
85 | }
|
86 | proxy.listen(proxyPort, setupClient);
|
87 | }
|
88 |
|
89 | function setupClient() {
|
90 | agent = tunnel.httpsOverHttps({
|
91 | maxSockets: poolSize,
|
92 |
|
93 | key: client1Key,
|
94 | cert: client1Cert,
|
95 | ca: [serverCA],
|
96 | rejectUnauthroized: true,
|
97 | proxy: {
|
98 | port: proxyPort,
|
99 |
|
100 | key: client2Key,
|
101 | cert: client2Cert,
|
102 | ca: [proxyCA],
|
103 | rejectUnauthroized: true
|
104 | }
|
105 | });
|
106 |
|
107 | for (var i = 0; i < N; ++i) {
|
108 | doClientRequest(i);
|
109 | }
|
110 |
|
111 | function doClientRequest(i) {
|
112 | tunnel.debug('CLIENT: Making HTTPS request (%d)', i);
|
113 | var req = https.get({
|
114 | port: serverPort,
|
115 | path: '/' + i,
|
116 | agent: agent
|
117 | }, function(res) {
|
118 | tunnel.debug('CLIENT: got HTTPS response (%d)', i);
|
119 | res.setEncoding('utf8');
|
120 | res.on('data', function(data) {
|
121 | data.should.equal('Hello/' + i);
|
122 | });
|
123 | res.on('end', function() {
|
124 | ++clientConnect;
|
125 | if (clientConnect === N) {
|
126 | proxy.close();
|
127 | server.close();
|
128 | }
|
129 | });
|
130 | });
|
131 | }
|
132 | }
|
133 |
|
134 | server.on('close', function() {
|
135 | serverConnect.should.equal(N);
|
136 | proxyConnect.should.equal(poolSize);
|
137 | clientConnect.should.equal(N);
|
138 |
|
139 | var name = 'localhost:' + serverPort;
|
140 | agent.sockets.should.be.empty;
|
141 | agent.requests.should.be.empty;
|
142 |
|
143 | done();
|
144 | });
|
145 | });
|
146 | });
|