0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-25 08:19:38 +01:00
nodejs/test/parallel/test-tls-over-http-tunnel.js
isaacs 3e1b1dd4a9 Remove excessive copyright/license boilerplate
The copyright and license notice is already in the LICENSE file.  There
is no justifiable reason to also require that it be included in every
file, since the individual files are not individually distributed except
as part of the entire package.
2015-01-12 15:30:28 -08:00

157 lines
4.1 KiB
JavaScript

if (!process.versions.openssl) {
console.error('Skipping because node compiled without OpenSSL.');
process.exit(0);
}
var common = require('../common');
var assert = require('assert');
var fs = require('fs');
var net = require('net');
var http = require('http');
var https = require('https');
var proxyPort = common.PORT + 1;
var gotRequest = false;
var key = fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem');
var cert = fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem');
var options = {
key: key,
cert: cert
};
var server = https.createServer(options, function(req, res) {
console.log('SERVER: got request');
res.writeHead(200, {
'content-type': 'text/plain'
});
console.log('SERVER: sending response');
res.end('hello world\n');
});
var proxy = net.createServer(function(clientSocket) {
console.log('PROXY: got a client connection');
var serverSocket = null;
clientSocket.on('data', function(chunk) {
if (!serverSocket) {
// Verify the CONNECT request
assert.equal('CONNECT localhost:' + common.PORT + ' HTTP/1.1\r\n' +
'Proxy-Connections: keep-alive\r\n' +
'Host: localhost:' + proxyPort + '\r\n\r\n',
chunk);
console.log('PROXY: got CONNECT request');
console.log('PROXY: creating a tunnel');
// create the tunnel
serverSocket = net.connect(common.PORT, function() {
console.log('PROXY: replying to client CONNECT request');
// Send the response
clientSocket.write('HTTP/1.1 200 OK\r\nProxy-Connections: keep' +
'-alive\r\nConnections: keep-alive\r\nVia: ' +
'localhost:' + proxyPort + '\r\n\r\n');
});
serverSocket.on('data', function(chunk) {
clientSocket.write(chunk);
});
serverSocket.on('end', function() {
clientSocket.destroy();
});
} else {
serverSocket.write(chunk);
}
});
clientSocket.on('end', function() {
serverSocket.destroy();
});
});
server.listen(common.PORT);
proxy.listen(proxyPort, function() {
console.log('CLIENT: Making CONNECT request');
var req = http.request({
port: proxyPort,
method: 'CONNECT',
path: 'localhost:' + common.PORT,
headers: {
'Proxy-Connections': 'keep-alive'
}
});
req.useChunkedEncodingByDefault = false; // for v0.6
req.on('response', onResponse); // for v0.6
req.on('upgrade', onUpgrade); // for v0.6
req.on('connect', onConnect); // for v0.7 or later
req.end();
function onResponse(res) {
// Very hacky. This is necessary to avoid http-parser leaks.
res.upgrade = true;
}
function onUpgrade(res, socket, head) {
// Hacky.
process.nextTick(function() {
onConnect(res, socket, head);
});
}
function onConnect(res, socket, header) {
assert.equal(200, res.statusCode);
console.log('CLIENT: got CONNECT response');
// detach the socket
socket.removeAllListeners('data');
socket.removeAllListeners('close');
socket.removeAllListeners('error');
socket.removeAllListeners('drain');
socket.removeAllListeners('end');
socket.ondata = null;
socket.onend = null;
socket.ondrain = null;
console.log('CLIENT: Making HTTPS request');
https.get({
path: '/foo',
key: key,
cert: cert,
socket: socket, // reuse the socket
agent: false,
rejectUnauthorized: false
}, function(res) {
assert.equal(200, res.statusCode);
res.on('data', function(chunk) {
assert.equal('hello world\n', chunk);
console.log('CLIENT: got HTTPS response');
gotRequest = true;
});
res.on('end', function() {
proxy.close();
server.close();
});
}).on('error', function(er) {
// We're ok with getting ECONNRESET in this test, but it's
// timing-dependent, and thus unreliable. Any other errors
// are just failures, though.
if (er.code !== 'ECONNRESET')
throw er;
}).end();
}
});
process.on('exit', function() {
assert.ok(gotRequest);
});