mirror of
https://github.com/nodejs/node.git
synced 2024-11-25 08:19:38 +01:00
3e1b1dd4a9
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.
157 lines
4.1 KiB
JavaScript
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);
|
|
});
|