🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

yakaa

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

yakaa - npm Package Compare versions

Comparing version
0.0.1
to
1.0.0
.npmignore

Sorry, the diff of this file is not supported yet

+6
language: node_js
node_js:
- "0.11"
- "0.10"
notifications:
email: false
# Guidelines for contributing code
New Relic welcomes code contributions by the Node community to this module, and
have taken effort to make this process easy for both contributors and our
development team.
When contributing, keep in mind that New Relic customers (that's you!) are
running many different versions of Node, some of them pretty old (most of you
have moved off 0.6, but there are more than a few 0.8 applications still out
there). Changes that depend on the newest version of Node will probably be
rejected, with prejudice if they replace something backwards compatible.
## And finally...
You are welcome to send pull requests to us - however, by doing so you agree
that you are granting New Relic a non-exclusive, non-revokable, no-cost license
to use the code, algorithms, patents, and ideas in that code in our products if
we so choose. You also agree the code is provided as-is and you provide no
warranties as to its fitness or correctness for any purpose.
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
## yakaa: yet another keep-alive agent
This is an extracted copy of Node 0.12's keep-alive Agent implementation with
some small changes intended to make it work with older versions of Node. It
also has one extra feature, which I needed.
The HTTP Agent is used for pooling sockets used in HTTP client requests.
The HTTP Agent also defaults client requests to using Connection:keep-alive. If
no pending HTTP requests are waiting on a socket to become free the socket is
closed. This means that Node's pool has the benefit of keep-alive when under
load but still does not require developers to manually close the HTTP clients
using KeepAlive.
If you opt into using HTTP KeepAlive, you can create an Agent object with that
flag set to `true`. (See the [constructor options](#http_new_agent_options)
below.) Then, the Agent will keep unused sockets in a pool for later use.
They will be explicitly marked so as to not keep the Node process running.
However, it is still a good idea to explicitly
[`destroy()`](#http_agent_destroy) KeepAlive agents when they are no longer in
use, so that the Sockets will be shut down.
Sockets are removed from the agent's pool when the socket emits either a
"close" event or a special "agentRemove" event. This means that if you intend
to keep one HTTP request open for a long time and don't want it to stay in the
pool you can do something along the lines of:
http.get(options, function(res) {
// Do stuff
}).on("socket", function (socket) {
socket.emit("agentRemove");
});
### var Agent = require('yakaa'); new Agent([options])
* `options` {Object} Set of configurable options to set on the agent.
Can have the following fields:
* `keepAlive` {Boolean} Keep sockets around in a pool to be used by
other requests in the future. Default = `false`
* `keepAliveMsecs` {Integer} When using HTTP KeepAlive, how often
to send TCP KeepAlive packets over sockets being kept alive.
Default = `1000`. Only relevant if `keepAlive` is set to `true`.
* **ADDED** `keepAliveTimeoutMsecs` {Integer} When using HTTP KeepAlive, how
long to keep the socket connected without activity before it gets reaped.
* `maxSockets` {Number} Maximum number of sockets to allow per
host. Default = `Infinity`.
* `maxFreeSockets` {Number} Maximum number of sockets to leave open
in a free state. Only relevant if `keepAlive` is set to `true`.
Default = `256`.
The default `http.globalAgent` that is used by `http.request` has all
of these values set to their respective defaults.
To configure any of them, you must create your own `Agent` object.
```javascript
var http = require('http');
var Agent = require('yakaa');
var keepAliveAgent = new Agent({ keepAlive: true });
keepAliveAgent.request(options, onResponseCallback);
```
### agent.maxSockets
By default set to Infinity. Determines how many concurrent sockets the agent
can have open per origin. Origin is either a 'host:port' or
'host:port:localAddress' combination.
### agent.maxFreeSockets
By default set to 256. For Agents supporting HTTP KeepAlive, this
sets the maximum number of sockets that will be left open in the free
state.
### agent.sockets
An object which contains arrays of sockets currently in use by the
Agent. Do not modify.
### agent.freeSockets
An object which contains arrays of sockets currently awaiting use by
the Agent when HTTP KeepAlive is used. Do not modify.
### agent.requests
An object which contains queues of requests that have not yet been assigned to
sockets. Do not modify.
### agent.destroy()
Destroy any sockets that are currently in use by the agent.
It is usually not necessary to do this. However, if you are using an
agent with KeepAlive enabled, then it is best to explicitly shut down
the agent when you know that it will no longer be used. Otherwise,
sockets may hang open for quite a long time before the server
terminates them.
### agent.getName(options)
Get a unique name for a set of request options, to determine whether a
connection can be reused. In the http agent, this returns
`host:port:localAddress`. In the https agent, the name includes the
CA, cert, ciphers, and other HTTPS/TLS-specific options that determine
socket reusability.
## new Agent.SSL(options)
An Agent object for HTTPS similar to Agent.
`options` is an object. All options from Agent are valid.
The following options from [tls.connect()][] can also be used.
- `pfx`: Certificate, Private key and CA certificates to use for SSL. Default `null`.
- `key`: Private key to use for SSL. Default `null`.
- `passphrase`: A string of passphrase for the private key or pfx. Default `null`.
- `cert`: Public x509 certificate to use. Default `null`.
- `ca`: An authority certificate or array of authority certificates to check
the remote host against.
- `ciphers`: A string describing the ciphers to use or exclude. Consult
<http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT> for
details on the format.
- `rejectUnauthorized`: If `true`, the server certificate is verified against
the list of supplied CAs. An `'error'` event is emitted if verification
fails. Verification happens at the connection level, *before* the HTTP
request is sent. Default `true`.
- `secureProtocol`: The SSL method to use, e.g. `SSLv3_method` to force
SSL version 3. The possible values depend on your installation of
OpenSSL and are defined in the constant [SSL_METHODS][].
Example:
```js
var SSLAgent = require('yakaa').SSL;
var options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
options.agent = new SSLAgent(options);
```
### LICENSE
See LICENSE in this distribution. As code derived from Node's source, it's
governed by the same license as Node itself.
# How to contact us
Please send any issue that you feel affects the security of this module to
**security@newrelic.com**.
# Expectations
If we do not respond promptly, we ask that you give us the benefit of the
doubt, as it is possible the email went to spam or we have been so focused on
something else we haven't seen it yet. Please send us a quick message,
*without detail* to one of the following:
* An issue here on GitHub, with an email address we can use to contact you
for a more detailed report.
* Message [@newrelic](https://twitter.com/newrelic) on Twitter.
* Give our engineering team a heads up on IRC in #newrelic on Freenode.
# History
No security issues have been reported for this project yet.
var test = require('tap').test;
var Agent = require('../index.js')
var http = require('http')
test("yakaa should destroy the socket after an error", function (t) {
t.plan(2);
// set a super short socket lifetime
// normally this would kill a TLS session,
// but our super simple test won't mind
var agent = new Agent({keepAlive : true});
var opts = {
port : 1,
agent : agent,
};
agent.on('yakaa_remove', function () {
t.ok(true, 'removed');
})
var req = new http.ClientRequest(opts);
req.on('error', function (err) {
t.ok(err);
})
req.end();
});
var test = require('tap').test;
var Agent = require('../index.js')
var http = require('http')
var web = http.createServer(function(req,res){req.pipe(process.stdout); res.end()});
test("yakaa should reuse the socket", function (t) {
t.plan(7);
web.listen();
var PORT = web.address().port;
var agent = new Agent({keepAlive : true, keepAliveTimeoutMsecs: 100});
var opts = {
port : PORT,
agent : agent,
};
var socket;
var i = 0;
agent.on('free', function (sock, opts) {
t.ok(i++ < 2, 'free socket');
});
// only destroyed once at the end
var j = 0;
agent.on('yakaa_destroy', function (s) {
t.ok(j++ < 1, 'destroy');
t.equals(j,1, 'destroy called once')
t.equals(i,2, 'free called twice')
t.end()
});
new http.ClientRequest(opts, next).end();
function next(res) {
res.pipe(process.stdout)
t.ok(res, 'first response');
// set short timeout so this test ends quickly
new http.ClientRequest(opts, done).end();
}
function done(res) {
res.pipe(process.stdout);
t.ok(res, 'second response');
web.close();
}
});
test("yakaa should destroy the socket after each request", function (t) {
t.plan(8);
web.listen();
var PORT = web.address().port;
// set a super short socket lifetime
// normally this would kill a TLS session,
// but our super simple test won't mind
var agent = new Agent({keepAlive : true, keepAliveTimeoutMsecs: 1});
var opts = {
port : PORT,
agent : agent,
};
var j=0;
agent.on('yakaa_destroy', function () {
t.ok(j++ < 2, 'destroy');
if (j==2) {
t.equals(j,2, 'destroy called twice')
t.equals(i,2, 'free called twice')
t.end();
}
})
var i=0;
agent.on('free', function (sock, opts) {
t.ok(i++ < 2, 'free socket');
});
new http.ClientRequest(opts, next).end();
function next(res) {
res.pipe(process.stdout)
t.ok(res, 'first response');
setTimeout(function () {
new http.ClientRequest(opts, done).end();
}, 10);
}
function done(res) {
res.pipe(process.stdout);
t.ok(res, 'second response');
web.close();
}
});
+15
-23

@@ -112,17 +112,10 @@ 'use strict';

// Avoid duplicate timeout events by removing timeout listeners set
// on socket by previous requests. node does not do this normally
// because it assumes sockets are too short-lived for it to matter.
// It becomes a problem when sockets are being reused. Fixed sometime
// around Node 0.10.0.
//
// See https://github.com/joyent/node/commit/451ff1540
if (self.keepAliveTimeoutMsecs &&
socket._events &&
Array.isArray(socket._events.timeout)) {
socket.removeAllListeners('timeout');
// Restore the socket's setTimeout() that was remove as collateral
// damage.
socket.setTimeout(self.keepAliveTimeoutMsecs, socket._reapTimeout);
// set timeout on idle sockets
if (options.keepAliveTimeoutMsecs !== undefined) {
socket._yakaa_timeout = setTimeout(function () {
self.emit('yakaa_destroy');
socket.destroySoon();
}, options.keepAliveTimeoutMsecs);
}
}

@@ -187,2 +180,8 @@ } else {

// mark socket as non-idle so it doesn't get destroyed mid-request
if (socket._yakaa_timeout) {
clearTimeout(socket._yakaa_timeout);
delete socket._yakaa_timeout;
}
// don't leak

@@ -240,11 +239,2 @@ if (!this.freeSockets[name].length)

if (options.keepAliveTimeoutMsecs) {
s._reapTimeout = function () {
debug('_reapTimeout, socket destroy()');
s.destroy();
self.removeSocket(s, options);
};
s.setTimeout(options.keepAliveTimeoutMsecs, s._reapTimeout);
}
function onFree() {

@@ -283,2 +273,4 @@ self.emit('free', s, options);

this.emit('yakaa_remove', s);
// If the socket was destroyed, remove it from the free buffers too.

@@ -285,0 +277,0 @@ if (s.destroyed)

{
"name": "yakaa",
"version": "0.0.1",
"version": "1.0.0",
"description": "Yet Another Keep-Alive Agent",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "tap test"
},

@@ -26,3 +26,6 @@ "repository": {

},
"homepage": "https://github.com/newrelic/yakaa"
"homepage": "https://github.com/newrelic/yakaa",
"devDependencies": {
"tap": "^0.4.8"
}
}