agent-base
Advanced tools
Comparing version 1.0.2 to 2.0.0
36
agent.js
@@ -6,2 +6,4 @@ | ||
require('./patch-core'); | ||
var extend = require('extend'); | ||
var inherits = require('util').inherits; | ||
@@ -17,3 +19,6 @@ var EventEmitter = require('events').EventEmitter; | ||
/** | ||
* Base `http.Agent` implementation. | ||
* No pooling/keep-alive is implemented by default. | ||
* | ||
* @param {Function} callback | ||
* @api public | ||
@@ -41,12 +46,6 @@ */ | ||
// >= v0.11.x API | ||
opts = host; | ||
if (opts.host && opts.path) { | ||
// if both a `host` and `path` are specified then it's most likely the | ||
// result of a `url.parse()` call... we need to remove the `path` portion so | ||
// that `net.connect()` doesn't attempt to open that as a unix socket file. | ||
delete opts.path; | ||
} | ||
opts = extend({}, req._options, host); | ||
} else { | ||
// <= v0.10.x API | ||
opts = { host: host, port: port }; | ||
opts = extend({}, req._options, { host: host, port: port }); | ||
if (null != localAddress) { | ||
@@ -57,2 +56,20 @@ opts.localAddress = localAddress; | ||
if (opts.host && opts.path) { | ||
// if both a `host` and `path` are specified then it's most likely the | ||
// result of a `url.parse()` call... we need to remove the `path` portion so | ||
// that `net.connect()` doesn't attempt to open that as a unix socket file. | ||
delete opts.path; | ||
} | ||
// set default `port` if none was explicitly specified | ||
if (null == opts.port) { | ||
opts.port = opts.secureEndpoint ? 443 : 80; | ||
} | ||
delete opts.agent; | ||
delete opts.hostname; | ||
delete opts._defaultAgent; | ||
delete opts.defaultPort; | ||
delete opts.createConnection; | ||
// hint to use "Connection: close" | ||
@@ -63,2 +80,5 @@ // XXX: non-documented `http` module API :( | ||
// clean up a bit of memory since we're no longer using this | ||
req._options = null; | ||
// create the `net.Socket` instance | ||
@@ -65,0 +85,0 @@ var sync = true; |
2.0.0 / 2015-07-10 | ||
================== | ||
* refactor to patch Node.js core for more consistent `opts` values | ||
* ensure that HTTP(s) default port numbers are always given | ||
* test: use ssl-cert-snakeoil SSL certs | ||
* test: add tests for arbitrary options | ||
* README: add API section | ||
* README: make the Agent HTTP/HTTPS generic in the example | ||
* README: use SVG for Travis-CI badge | ||
1.0.2 / 2015-06-27 | ||
@@ -3,0 +14,0 @@ ================== |
{ | ||
"name": "agent-base", | ||
"version": "1.0.2", | ||
"version": "2.0.0", | ||
"description": "Turn a function into an `http.Agent` instance", | ||
@@ -27,3 +27,7 @@ "main": "agent.js", | ||
"mocha": "2" | ||
}, | ||
"dependencies": { | ||
"extend": "~3.0.0", | ||
"semver": "~4.3.6" | ||
} | ||
} |
agent-base | ||
========== | ||
### Turn a function into an `http.Agent` instance | ||
[![Build Status](https://travis-ci.org/TooTallNate/node-agent-base.png?branch=master)](https://travis-ci.org/TooTallNate/node-agent-base) | ||
[![Build Status](https://travis-ci.org/TooTallNate/node-agent-base.svg?branch=master)](https://travis-ci.org/TooTallNate/node-agent-base) | ||
@@ -12,4 +12,4 @@ This module provides an `http.Agent` generator. That is, you pass it an async | ||
Here's some more interesting uses of `agent-base`. Send a pull request to | ||
list yours! | ||
Here's some more interesting uses of `agent-base`. | ||
Send a pull request to list yours! | ||
@@ -39,4 +39,5 @@ * [`http-proxy-agent`][http-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTP endpoints | ||
``` js | ||
var net = require('net'); | ||
var tls = require('tls'); | ||
var url = require('url'); | ||
var net = require('net'); | ||
var http = require('http'); | ||
@@ -50,4 +51,9 @@ var agent = require('agent-base'); | ||
opts.agent = agent(function (req, opts, fn) { | ||
if (!opts.port) opts.port = 80; | ||
var socket = net.connect(opts); | ||
var socket; | ||
// `secureEndpoint` is true when using the https module | ||
if (opts.secureEndpoint) { | ||
socket = tls.connect(opts); | ||
} else { | ||
socket = net.connect(opts); | ||
} | ||
fn(null, socket); | ||
@@ -63,3 +69,28 @@ }); | ||
API | ||
--- | ||
## Agent(Function callback) → http.Agent | ||
Creates a base `http.Agent` that will execute the callback function `callback` | ||
for every HTTP request that it is used as the `agent` for. The callback function | ||
is responsible for creating a `stream.Duplex` instance of some kind that will be | ||
used as the underlying socket in the HTTP request. | ||
The callback function should have the following signature: | ||
### callback(http.ClientRequest req, Object options, Function cb) → undefined | ||
The ClientRequest `req` can be accessed to read request headers and | ||
and the path, etc. The `options` object contains the options passed | ||
to the `http.request()`/`https.request()` function call, and is formatted | ||
to be directly passed to `net.connect()`/`tls.connect()`, or however | ||
else you want a Socket to be created. Pass the created socket to | ||
the callback function `cb` once created, and the HTTP request will | ||
continue to proceed. | ||
If the `https` module is used to invoke the HTTP request, then the | ||
`secureEndpoint` property on `options` will be set to `true`. | ||
License | ||
@@ -66,0 +97,0 @@ ------- |
105
test/test.js
@@ -128,10 +128,10 @@ | ||
// test subject `http.Agent` instance | ||
var agent = new Agent(function (req, opts, fn) { | ||
if (!opts.port) opts.port = 80; | ||
var socket = net.connect(opts); | ||
fn(null, socket); | ||
}); | ||
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); | ||
}); | ||
it('should work for basic HTTP requests', function (done) { | ||
// add HTTP server "request" listener | ||
@@ -152,2 +152,3 @@ var gotReq = false; | ||
assert(gotReq); | ||
assert(called); | ||
done(); | ||
@@ -158,2 +159,9 @@ }); | ||
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 | ||
@@ -174,5 +182,35 @@ var gotReq = false; | ||
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 | ||
}); | ||
}); | ||
}); | ||
@@ -187,4 +225,4 @@ | ||
var options = { | ||
key: fs.readFileSync(__dirname + '/server.key'), | ||
cert: fs.readFileSync(__dirname + '/server.crt') | ||
key: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.key'), | ||
cert: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.pem') | ||
}; | ||
@@ -206,11 +244,11 @@ server = https.createServer(options); | ||
// test subject `http.Agent` instance | ||
var agent = new Agent(function (req, opts, fn) { | ||
if (!opts.port) opts.port = 443; | ||
opts.rejectUnauthorized = false; | ||
var socket = tls.connect(opts); | ||
fn(null, socket); | ||
}); | ||
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); | ||
}); | ||
it('should work for basic HTTPS requests', function (done) { | ||
// add HTTPS server "request" listener | ||
@@ -232,5 +270,38 @@ var gotReq = false; | ||
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 | ||
}); | ||
}); | ||
}); |
20287
10
404
122
2
6
+ Addedextend@~3.0.0
+ Addedsemver@~4.3.6
+ Addedextend@3.0.2(transitive)
+ Addedsemver@4.3.6(transitive)