123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- /**
- * Module dependencies.
- */
- var fs = require('fs');
- var url = require('url');
- var net = require('net');
- var tls = require('tls');
- var http = require('http');
- var https = require('https');
- var WebSocket = require('ws');
- var assert = require('assert');
- var events = require('events');
- var inherits = require('util').inherits;
- var semver = require('semver');
- var Agent = require('../');
- describe('Agent', function () {
- describe('subclass', function () {
- it('should be subclassable', function (done) {
- function MyAgent () {
- Agent.call(this);
- }
- inherits(MyAgent, Agent);
- MyAgent.prototype.callback = function (req, opts, fn) {
- assert.equal(req.path, '/foo');
- assert.equal(req.getHeader('host'), '127.0.0.1:1234');
- assert.equal(opts.secureEndpoint, true);
- done();
- };
- var info = url.parse('https://127.0.0.1:1234/foo');
- info.agent = new MyAgent;
- https.get(info);
- });
- });
- describe('"error" event', function () {
- it('should be invoked on `http.ClientRequest` instance if `callback()` has not been defined', function (done) {
- var agent = new Agent();
- var info = url.parse('http://127.0.0.1/foo');
- info.agent = agent;
- var req = http.get(info);
- req.on('error', function (err) {
- assert.equal('"agent-base" has no default implementation, you must subclass and override `callback()`', err.message);
- done();
- });
- });
- it('should be invoked on `http.ClientRequest` instance if Error passed to callback function on the first tick', function (done) {
- var agent = new Agent(function (req, opts, fn) {
- fn(new Error('is this caught?'));
- });
- var info = url.parse('http://127.0.0.1/foo');
- info.agent = agent;
- var req = http.get(info);
- req.on('error', function (err) {
- assert.equal('is this caught?', err.message);
- done();
- });
- });
- it('should be invoked on `http.ClientRequest` instance if Error passed to callback function after the first tick', function (done) {
- var agent = new Agent(function (req, opts, fn) {
- setTimeout(function () {
- fn(new Error('is this caught?'));
- }, 10);
- });
- var info = url.parse('http://127.0.0.1/foo');
- info.agent = agent;
- var req = http.get(info);
- req.on('error', function (err) {
- assert.equal('is this caught?', err.message);
- done();
- });
- });
- });
- describe('artificial "streams"', function () {
- it('should send a GET request', function (done) {
- var stream = new events.EventEmitter();
- // needed for the `http` module to call .write() on the stream
- stream.writable = true;
- stream.write = function (str) {
- assert(0 == str.indexOf('GET / HTTP/1.1'));
- done();
- };
- // needed for `http` module in Node.js 4
- stream.cork = function () {
- };
- var opts = {
- method: 'GET',
- host: '127.0.0.1',
- path: '/',
- port: 80,
- agent: new Agent(function (req, opts, fn) {
- fn(null, stream);
- })
- };
- var req = http.request(opts);
- req.end();
- });
- it('should receive a GET response', function (done) {
- var stream = new events.EventEmitter();
- var opts = {
- method: 'GET',
- host: '127.0.0.1',
- path: '/',
- port: 80,
- agent: new Agent(function (req, opts, fn) {
- fn(null, stream);
- })
- };
- var req = http.request(opts, function (res) {
- assert.equal('0.9', res.httpVersion);
- assert.equal(111, res.statusCode);
- assert.equal('bar', res.headers.foo);
- done();
- });
- req.end();
- // have to nextTick() since `http.ClientRequest` doesn't *actually*
- // attach the listeners to the "stream" until the next tick :\
- process.nextTick(function () {
- var buf = new Buffer('HTTP/0.9 111\r\n' +
- 'Foo: bar\r\n' +
- 'Set-Cookie: 1\r\n' +
- 'Set-Cookie: 2\r\n\r\n');
- if ('function' == typeof stream.ondata) {
- // node <= v0.11.3
- stream.ondata(buf, 0, buf.length);
- } else {
- // node > v0.11.3
- stream.emit('data', buf);
- }
- });
- });
- });
- });
- describe('"http" module', function () {
- var server;
- var port;
- // setup test HTTP server
- before(function (done) {
- server = http.createServer();
- server.listen(0, function () {
- port = server.address().port;
- done();
- });
- });
- // shut down test HTTP server
- after(function (done) {
- server.once('close', function () {
- done();
- });
- server.close();
- });
- it('should work for basic HTTP requests', function (done) {
- var called = false;
- var agent = new Agent(function (req, opts, fn) {
- called = true;
- var socket = net.connect(opts);
- fn(null, socket);
- });
- // add HTTP server "request" listener
- var gotReq = false;
- server.once('request', function (req, res) {
- gotReq = true;
- res.setHeader('X-Foo', 'bar');
- res.setHeader('X-Url', req.url);
- res.end();
- });
- var info = url.parse('http://127.0.0.1:' + port + '/foo');
- info.agent = agent;
- http.get(info, function (res) {
- assert.equal('bar', res.headers['x-foo']);
- assert.equal('/foo', res.headers['x-url']);
- assert(gotReq);
- assert(called);
- done();
- });
- });
- it('should set the `Connection: close` response header', function (done) {
- var called = false;
- var agent = new Agent(function (req, opts, fn) {
- called = true;
- var socket = net.connect(opts);
- fn(null, socket);
- });
- // add HTTP server "request" listener
- var gotReq = false;
- server.once('request', function (req, res) {
- gotReq = true;
- res.setHeader('X-Url', req.url);
- assert.equal('close', req.headers.connection);
- res.end();
- });
- var info = url.parse('http://127.0.0.1:' + port + '/bar');
- info.agent = agent;
- http.get(info, function (res) {
- assert.equal('/bar', res.headers['x-url']);
- assert.equal('close', res.headers.connection);
- assert(gotReq);
- assert(called);
- done();
- });
- });
- it('should pass through options from `http.request()`', function (done) {
- var agent = new Agent(function (req, opts, fn) {
- assert.equal('google.com', opts.host);
- assert.equal('bar', opts.foo);
- done();
- });
- http.get({
- host: 'google.com',
- foo: 'bar',
- agent: agent
- });
- });
- it('should default to port 80', function (done) {
- var agent = new Agent(function (req, opts, fn) {
- assert.equal(80, opts.port);
- done();
- });
- // (probably) not hitting a real HTTP server here,
- // so no need to add a httpServer request listener
- http.get({
- host: '127.0.0.1',
- path: '/foo',
- agent: agent
- });
- });
- });
- describe('"https" module', function () {
- var server;
- var port;
- // setup test HTTPS server
- before(function (done) {
- var options = {
- key: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.key'),
- cert: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.pem')
- };
- server = https.createServer(options);
- server.listen(0, function () {
- port = server.address().port;
- done();
- });
- });
- // shut down test HTTP server
- after(function (done) {
- server.once('close', function () {
- done();
- });
- server.close();
- });
- it('should work for basic HTTPS requests', function (done) {
- var called = false;
- var agent = new Agent(function (req, opts, fn) {
- called = true;
- assert(opts.secureEndpoint);
- var socket = tls.connect(opts);
- fn(null, socket);
- });
- // add HTTPS server "request" listener
- var gotReq = false;
- server.once('request', function (req, res) {
- gotReq = true;
- res.setHeader('X-Foo', 'bar');
- res.setHeader('X-Url', req.url);
- res.end();
- });
- var info = url.parse('https://127.0.0.1:' + port + '/foo');
- info.agent = agent;
- info.rejectUnauthorized = false;
- https.get(info, function (res) {
- assert.equal('bar', res.headers['x-foo']);
- assert.equal('/foo', res.headers['x-url']);
- assert(gotReq);
- assert(called);
- done();
- });
- });
- it('should pass through options from `https.request()`', function (done) {
- var agent = new Agent(function (req, opts, fn) {
- assert.equal('google.com', opts.host);
- assert.equal('bar', opts.foo);
- done();
- });
- https.get({
- host: 'google.com',
- foo: 'bar',
- agent: agent
- });
- });
- it('should default to port 443', function (done) {
- var agent = new Agent(function (req, opts, fn) {
- assert.equal(true, opts.secureEndpoint);
- assert.equal(false, opts.rejectUnauthorized);
- assert.equal(443, opts.port);
- done();
- });
- // (probably) not hitting a real HTTPS server here,
- // so no need to add a httpsServer request listener
- https.get({
- host: '127.0.0.1',
- path: '/foo',
- agent: agent,
- rejectUnauthorized: false
- });
- });
- });
- describe('"ws" server', function () {
- var wss;
- var server;
- var port;
- // setup test HTTP server
- before(function (done) {
- server = http.createServer()
- wss = new WebSocket.Server({ server: server });
- server.listen(0, function () {
- port = server.address().port;
- done();
- });
- });
- // shut down test HTTP server
- after(function (done) {
- server.once('close', function () {
- done();
- });
- server.close();
- });
- it('should work for basic WebSocket connections', function (done) {
- function onconnection(ws) {
- ws.on('message', function (data) {
- assert.equal('ping', data);
- ws.send('pong');
- });
- }
- wss.on('connection', onconnection);
- var agent = new Agent(function (req, opts, fn) {
- var socket = net.connect(opts);
- fn(null, socket);
- });
- var client = new WebSocket('ws://127.0.0.1:' + port + '/', {
- agent: agent
- });
- client.on('open', function () {
- client.send('ping');
- });
- client.on('message', function (data) {
- assert.equal('pong', data);
- client.close();
- wss.removeListener('connection', onconnection);
- done();
- });
- });
- });
- describe('"wss" server', function () {
- var wss;
- var server;
- var port;
- // setup test HTTP server
- before(function (done) {
- var options = {
- key: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.key'),
- cert: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.pem')
- };
- server = https.createServer(options);
- wss = new WebSocket.Server({ server: server });
- server.listen(0, function () {
- port = server.address().port;
- done();
- });
- });
- // shut down test HTTP server
- after(function (done) {
- server.once('close', function () {
- done();
- });
- server.close();
- });
- it('should work for secure WebSocket connections', function (done) {
- function onconnection(ws) {
- ws.on('message', function (data) {
- assert.equal('ping', data);
- ws.send('pong');
- });
- }
- wss.on('connection', onconnection);
- var agent = new Agent(function (req, opts, fn) {
- var socket = tls.connect(opts);
- fn(null, socket);
- });
- var client = new WebSocket('wss://127.0.0.1:' + port + '/', {
- agent: agent,
- rejectUnauthorized: false
- });
- client.on('open', function () {
- client.send('ping');
- });
- client.on('message', function (data) {
- assert.equal('pong', data);
- client.close();
- wss.removeListener('connection', onconnection);
- done();
- });
- });
- });
|