Socket
Socket
Sign inDemoInstall

agent-base

Package Overview
Dependencies
0
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.1 to 1.0.0

.travis.yml

57

agent.js

@@ -6,3 +6,2 @@

var net = require('net');
var inherits = require('util').inherits;

@@ -18,17 +17,11 @@ var EventEmitter = require('events').EventEmitter;

/**
* Barebones HTTP "Agent" implementation. Emulates the node-core `http.Agent`
* class, but implemented in a way that can be easily extended for additional
* functionality.
*
* This base implementation does no socket pooling, and opens
* a new connection for every HTTP request.
*
* It behaves more-or-less like `agent: false`.
*
* @api public
*/
function Agent () {
if (!(this instanceof Agent)) return new Agent();
function Agent (callback) {
if (!(this instanceof Agent)) return new Agent(callback);
if ('function' != typeof callback) throw new Error('Must pass a "callback function"');
EventEmitter.call(this);
this.callback = callback;
}

@@ -38,8 +31,2 @@ inherits(Agent, EventEmitter);

/**
* Default port to connect to.
*/
Agent.prototype.defaultPort = 80;
/**
* Called by node-core's "_http_client.js" module when creating

@@ -56,21 +43,23 @@ * a new HTTP request with this Agent instance.

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;
}
} else {
// <= v0.10.x API
opts = {
host: host,
port: port,
localAddress: localAddress
};
opts = { host: host, port: port };
if (null != localAddress) {
opts.localAddress = localAddress;
}
}
// hint to use "Connection: close"
// XXX: non-documented `http` module API :(
req._last = true;
req.shouldKeepAlive = false;
// create the `net.Socket` instance
var info = {
host: opts.hostname || opts.host,
port: +opts.port || this.defaultPort,
localAddress: opts.localAddress
};
this.createConnection(info, function (err, socket) {
this.callback(req, opts, function (err, socket) {
if (err) {

@@ -83,13 +72,1 @@ req.emit('error', err);

};
/**
* Creates and returns a `net.Socket` instance to use for an HTTP request.
*
* @api protected
*/
Agent.prototype.createConnection = function (opts, fn) {
var socket = net.connect(opts);
fn(null, socket);
return socket;
};

@@ -0,1 +1,6 @@

1.0.0 / 2013-09-09
==================
- New API: now you pass a callback function directly
0.0.1 / 2013-07-09

@@ -2,0 +7,0 @@ ==================

{
"name": "agent-base",
"version": "0.0.1",
"description": "Barebone `http.Agent` implementation",
"version": "1.0.0",
"description": "Turn a function into an `http.Agent` instance",
"main": "agent.js",

@@ -6,0 +6,0 @@ "scripts": {

@@ -1,26 +0,18 @@

node-agent-base
===============
### Barebone `http.Agent` implementation
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)
This module provides a very basic, barebones implementation of a Node.js
`http.Agent`. This can be used with the built-in `http` module.
This module provides an `http.Agent` generator. That is, you pass it an async
callback function, and it returns a new `http.Agent` instance that will invoke the
given callback function when sending outbound HTTP requests.
It provides _no_ Keep-Alive support and _no_ socket pooling. It's _very_ minimal.
#### Why?
It's minimal in order to be easily extended, and to feel like I have a sense of
"control" over the underlying sockets being used by the `http` module.
This also allows for cooler things to be done in subclasses, like preprocessing
the socket somehow, or perhaps connecting the socket to a different server
entirely (think proxy servers).
#### Some subclasses:
Here's some more interesting subclasses of `agent-base`. Send a pull request to
add yours!
Here's some more interesting uses of `agent-base`. Send a pull request to
list yours!
* [`http-proxy-agent`][http-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTP endpoints
* [`https-proxy-agent`][https-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTPS endpoints
* [`socks-proxy-agent`][socks-proxy-agent]: A SOCKS (v4a) proxy `http.Agent` implementation for HTTP and HTTPS

@@ -41,6 +33,10 @@

Here's a minimal example that creates a new `net.Socket` connection to the server
for every HTTP request (i.e. the equivalent of `agent: false` option):
``` js
var url = require('url');
var net = require('net');
var http = require('http');
var Agent = require('agent-base');
var agent = require('agent-base');

@@ -51,3 +47,7 @@ var endpoint = 'http://nodejs.org/api/';

// This is the important part!
opts.agent = new Agent();
opts.agent = agent(function (req, opts, fn) {
if (!opts.port) opts.port = 80;
var socket = net.connect(opts);
fn(null, socket);
});

@@ -90,1 +90,2 @@ // Everything else works just like normal...

[https-proxy-agent]: https://github.com/TooTallNate/node-https-proxy-agent
[socks-proxy-agent]: https://github.com/TooTallNate/node-socks-proxy-agent

@@ -6,27 +6,134 @@

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 assert = require('assert');
var Agent = require('../');
describe('Agent', function () {
describe('"http" module', function () {
var server;
var port;
it('should work in simple http requests', function (done) {
// set up a local HTTP server
var server = http.createServer(function (req, res) {
res.setHeader('X-It-Works', 'yesss');
// 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();
});
// 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) {
// 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);
done();
});
});
it('should set the `Connection: close` response header', function (done) {
// 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);
done();
});
});
});
describe('"https" module', function () {
var server;
var port;
// setup test HTTPS server
before(function (done) {
var options = {
key: fs.readFileSync(__dirname + '/server.key'),
cert: fs.readFileSync(__dirname + '/server.crt')
};
server = https.createServer(options);
server.listen(0, function () {
var port = server.address().port;
var info = url.parse('http://127.0.0.1:' + port + '/foo');
info.agent = new Agent();
http.get(info, function (res) {
assert.equal('yesss', res.headers['x-it-works']);
server.on('close', done);
server.close();
});
port = server.address().port;
done();
});
});
// shut down test HTTP server
after(function (done) {
server.once('close', function () {
done();
});
server.close();
});
// 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) {
// 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);
done();
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc