Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

restify

Package Overview
Dependencies
Maintainers
1
Versions
184
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

restify - npm Package Compare versions

Comparing version 2.6.0 to 2.6.1

lib/plugins/fielded_text_body_parser.js

9

CHANGES.md
# restify Changelog
## Not Yet Released
## 2.6.1
- #478 Add `req.timers` to audit logging plugin.
- #487 RequestCaptureStream: dumpDefault, haveNonRawStreams, zero ring after dump
- #407 - bunyan 0.21.3
- Add CSV/TSV parser (Dominik Lessel)
- Add `req.timers`: a list of hrtime's for each handler
- Set TCP SO_KEEPALIVE when default KeepAliveAgent is on (client)
## 2.6.0

@@ -6,0 +13,0 @@

@@ -42,2 +42,20 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

/**
* A Bunyan stream to capture records in a ring buffer and only pass through
* on a higher-level record. E.g. buffer up all records but only dump when
* getting a WARN or above.
*
* @param {Object} options contains the parameters:
* - {Object} stream The stream to which to write when dumping captured
* records. One of `stream` or `streams` must be specified.
* - {Array} streams One of `stream` or `streams` must be specified.
* - {Number|String} level The level at which to trigger dumping captured
* records. Defaults to bunyan.WARN.
* - {Number} maxRecords Number of records to capture. Default 100.
* - {Number} maxRequestIds Number of simultaneous request id capturing
* buckets to maintain. Default 1000.
* - {Boolean} dumpDefault If true, then dump captured records on the
* *default* request id when dumping. I.e. dump records logged without
* a "req_id" field. Default false.
*/
function RequestCaptureStream(opts) {

@@ -50,2 +68,3 @@ assert.object(opts, 'options');

assert.optionalNumber(opts.maxRequestIds, 'options.maxRequestIds');
assert.optionalBool(opts.dumpDefault, 'options.dumpDefault');

@@ -55,3 +74,3 @@ var self = this;

this.level = opts.level || bunyan.WARN;
this.level = opts.level ? bunyan.resolveLevel(opts.level) : bunyan.WARN;
this.limit = opts.maxRecords || 100;

@@ -62,4 +81,4 @@ this.maxRequestIds = opts.maxRequestIds || 1000;

});
this.dumpDefault = opts.dumpDefault;
this._offset = -1;

@@ -75,2 +94,10 @@ this._rings = [];

opts.streams.forEach(appendStream.bind(null, this.streams));
this.haveNonRawStreams = false;
for (var i = 0; i < this.streams.length; i++) {
if (!this.streams[i].raw) {
this.haveNonRawStreams = true;
break;
}
}
}

@@ -103,8 +130,28 @@ util.inherits(RequestCaptureStream, Stream);

if (record.level >= this.level) {
ring.records.forEach(function (r) {
var ser = JSON.stringify(r, bunyan.safeCycles()) + '\n';
var i, r, ser;
for (i = 0; i < ring.records.length; i++) {
r = ring.records[i];
if (this.haveNonRawStreams) {
ser = JSON.stringify(r,
bunyan.safeCycles()) + '\n';
}
self.streams.forEach(function (s) {
s.stream.write(s.raw ? r : ser);
});
});
}
ring.records.length = 0;
if (this.dumpDefault) {
var defaultRing = self.requestMap.get(DEFAULT_REQ_ID);
for (i = 0; i < defaultRing.records.length; i++) {
r = defaultRing.records[i];
if (this.haveNonRawStreams) {
ser = JSON.stringify(r,
bunyan.safeCycles()) + '\n';
}
self.streams.forEach(function (s) {
s.stream.write(s.raw ? r : ser);
});
}
defaultRing.records.length = 0;
}
} else {

@@ -111,0 +158,0 @@ ring.write(record);

81

lib/clients/http_client.js

@@ -19,2 +19,3 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

var once = require('once');
var tunnelAgent = require('tunnel-agent');
var uuid = require('node-uuid');

@@ -161,3 +162,3 @@

});
log.trace({client_res: res}, 'Upgrade Response received');
log.trace({client_res: res}, 'upgrade response received');

@@ -184,2 +185,5 @@ res.log = log;

clearTimeout(timer);
if (opts._keep_alive)
socket.setKeepAlive(true);
cb(null, req);

@@ -219,3 +223,3 @@ });

this.log = options.log;
if (!this.log.serializers.client_res) {
if (!this.log.serializers || !this.log.serializers.client_res) {
// Ensure logger has a reasonable serializer for `client_res`

@@ -237,2 +241,12 @@ // logged in this module.

if (process.env.https_proxy) {
this.proxy = url.parse(process.env.https_proxy);
} else if (process.env.http_proxy) {
this.proxy = url.parse(process.env.http_proxy);
} else if (options.proxy) {
this.proxy = options.proxy;
} else {
this.proxy = false;
}
this.retry = cloneRetryOptions(options.retry);

@@ -269,3 +283,18 @@ this.signRequest = options.signRequest || false;

if (this.url.protocol === 'https:') {
if (this.proxy) {
if (this.url.protocol == 'https:') {
if (this.proxy.protocol === 'https:') {
Agent = tunnelAgent.httpsOverHttps;
} else {
Agent = tunnelAgent.httpsOverHttp;
}
} else {
if (this.proxy.protocol === 'https:') {
Agent = tunnelAgent.httpOverHttps;
} else {
Agent = tunnelAgent.httpOverHttp;
}
}
maxSockets = http.globalAgent.maxSockets;
} else if (this.url.protocol === 'https:') {
Agent = KeepAliveAgent.Secure;

@@ -278,14 +307,23 @@ maxSockets = https.globalAgent.maxSockets;

this.agent = new Agent({
cert: self.cert,
ca: self.ca,
ciphers: self.ciphers,
key: self.key,
maxSockets: maxSockets,
maxKeepAliveRequests: 0,
maxKeepAliveTime: 0,
passphrase: self.passphrase,
pfx: self.pfx,
rejectUnauthorized: self.rejectUnauthorized
});
if (this.proxy) {
this.agent = new Agent({
proxy: self.proxy,
rejectUnauthorized: self.rejectUnauthorized,
ca: self.ca
});
} else {
this.agent = new Agent({
cert: self.cert,
ca: self.ca,
ciphers: self.ciphers,
key: self.key,
maxSockets: maxSockets,
maxKeepAliveRequests: 0,
maxKeepAliveTime: 0,
passphrase: self.passphrase,
pfx: self.pfx,
rejectUnauthorized: self.rejectUnauthorized
});
this._keep_alive = true;
}
}

@@ -300,5 +338,7 @@ }

Object.keys((sockets || {})).forEach(function (k) {
sockets[k].forEach(function (s) {
s.end();
});
if (Array.isArray(sockets[k])) {
sockets[k].forEach(function (s) {
s.end();
});
}
});

@@ -400,2 +440,3 @@

opts._keep_alive = this._keep_alive;
call = backoff.call(rawRequest, opts, cb);

@@ -447,3 +488,3 @@ call.setStrategy(new backoff.ExponentialStrategy({

Object.keys(self.url).forEach(function (k) {
Object.keys(this.url).forEach(function (k) {
if (!opts[k])

@@ -466,3 +507,3 @@ opts[k] = self.url[k];

delete opts.headers['content-md5'];
if (opts.headers['content-length'])
if (opts.headers['content-length'] && method !== 'DELETE')
delete opts.headers['content-length'];

@@ -469,0 +510,0 @@ if (opts.headers['transfer-encoding'])

@@ -34,2 +34,9 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

var timers = {};
(req.timers || []).forEach(function (time) {
var t = time.time;
var _t = Math.floor((1000000 * t[0]) +
(t[1] / 1000));
timers[time.name] = _t;
});
return ({

@@ -43,3 +50,4 @@ method: req.method,

body: options.body === true ?
req.body : undefined
req.body : undefined,
timers: timers
});

@@ -46,0 +54,0 @@ },

@@ -65,3 +65,5 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

try {
return (httpSignature.parseRequest(request, OPTIONS));
return (httpSignature.parseRequest(request, {
algorithms: OPTIONS.algorithms
}));
} catch (e) {

@@ -68,0 +70,0 @@ throw new InvalidHeaderError('Authorization header invalid: ' +

@@ -11,2 +11,3 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

var multipartParser = require('./multipart_parser');
var fieldedTextParser = require('./fielded_text_body_parser.js');

@@ -32,2 +33,3 @@

var parseMultipart = multipartParser(options);
var parseFieldedText = fieldedTextParser(options);

@@ -65,2 +67,12 @@ function parseBody(req, res, next) {

break;
case 'text/tsv':
parser = parseFieldedText;
break;
case 'text/tab-separated-values':
parser = parseFieldedText;
break;
case 'text/csv':
parser = parseFieldedText;
break;
default:

@@ -67,0 +79,0 @@ break;

@@ -56,3 +56,4 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

if ((req.getContentLength() === 0 && !req.isChunked()) ||
req.contentType() === 'multipart/form-data') {
req.contentType() === 'multipart/form-data' ||
req.contentType() === 'application/octet-stream') {
next();

@@ -59,0 +60,0 @@ return;

@@ -100,4 +100,4 @@ // Copyright 2013 Mark Cavage, Inc. All rights reserved.

function corsOnHeader() {
origin = req.headers['origin'];
if (opts.credentials) {
origin = req.headers['origin'];
res.setHeader(AC_ALLOW_ORIGIN, origin);

@@ -104,0 +104,0 @@ res.setHeader(AC_ALLOW_CREDS, 'true');

// Copyright 2012 Mark Cavage, Inc. All rights reserved.
var crypto = require('crypto');
var assert = require('assert-plus');

@@ -6,0 +4,0 @@

@@ -36,3 +36,3 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

next(new ResourceNotFoundError(err,
req.path()));
req.path()));
return;

@@ -45,3 +45,3 @@ } else if (!stats.isFile()) {

if (res.handledGzip && isGzip) {
res.handledGzip();
res.handledGzip();
}

@@ -76,3 +76,3 @@

// Serve an index.html page or similar
file = path.join(opts.directory, opts.default);
file = path.join(file, opts.default);
fs.stat(file, function (dirErr, dirStats) {

@@ -100,5 +100,19 @@ serveFileFromStats(file,

function serve(req, res, next) {
var file = path.join(opts.directory,
decodeURIComponent(req.path()));
var file = decodeURIComponent(req.path());
var route;
var regex;
var stats;
if (opts.directory) {
route = req.route.path.toString();
route = route.substring(1, route.length-4);
route = route.replace(/\\\//g,'/');
if (opts.directory.slice(-1) != '/')
opts.directory += '/';
regex = new RegExp(route, 'g');
file = req.path().replace(regex, opts.directory);
}
if (req.method !== 'GET' && req.method !== 'HEAD') {

@@ -110,3 +124,19 @@ next(new MethodNotAllowedError(req.method));

if (!re.test(file.replace(/\\/g, '/'))) {
next(new NotAuthorizedError(req.path()));
if (opts['default'] &&
file.indexOf(opts['default']) < 0) {
if (file.slice(-1) == '/') {
file = file.substring(0,
file.length - 1);
}
if (fs.existsSync(file)) {
stats = fs.lstatSync(file);
if (stats.isDirectory()) {
if (fs.existsSync(file)) {
file = file + '/' +
opts['default'];
}
}
}
}
serveNormal(file, req, res, next);
return;

@@ -121,18 +151,19 @@ }

if (opts.gzip && req.acceptsEncoding('gzip')) {
fs.stat(file + '.gz', function (err, stats) {
if (!err) {
res.setHeader('Content-Encoding', 'gzip');
serveFileFromStats(file,
err,
stats,
true,
req,
res,
next);
} else {
serveNormal(file, req, res, next);
}
});
fs.stat(file + '.gz', function (err, _stats) {
if (!err) {
res.setHeader('Content-Encoding',
'gzip');
serveFileFromStats(file,
err,
_stats,
true,
req,
res,
next);
} else {
serveNormal(file, req, res, next);
}
});
} else {
serveNormal(file, req, res, next);
serveNormal(file, req, res, next);
}

@@ -139,0 +170,0 @@

@@ -57,22 +57,32 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

if (type && type.indexOf(';') !== '-1')
type = type.split(';')[0];
if (!type) {
for (var i = 0; i < this.acceptable.length; i++) {
if (this.req.accepts(this.acceptable[i])) {
type = this.acceptable[i];
break;
}
}
if (!(formatter = this.formatters[type])) {
if (!type) {
for (var i = 0; i < this.acceptable.length; i++) {
if (this.req.accepts(this.acceptable[i])) {
type = this.acceptable[i];
break;
}
}
} else {
if (type.indexOf('/') === -1)
type = mime.lookup(type);
// The importance of a status code outside of the
// 2xx range probably outweighs that of unable being to
// format the response body
if (this.statusCode >= 200 && this.statusCode < 300)
this.statusCode = 406;
if (this.acceptable.indexOf(type) === -1)
type = 'application/octet-stream';
return (null);
}
} else if (type.indexOf(';') !== '-1') {
type = type.split(';')[0];
}
if (!(formatter = this.formatters[type])) {
if (type.indexOf('/') === -1)
type = mime.lookup(type);
if (this.acceptable.indexOf(type) === -1)
type = 'application/octet-stream';
formatter = this.formatters[type] || this.formatters['*/*'];
if (!formatter) {

@@ -85,3 +95,2 @@ log.warn({

}
this.setHeader('Content-Type', type);
}

@@ -91,5 +100,6 @@

type = type + '; charset=' + this._charSet;
this.setHeader('Content-Type', type);
}
this.setHeader('Content-Type', type);
if (body instanceof Error && body.statusCode !== undefined)

@@ -264,2 +274,3 @@ this.statusCode = body.statusCode;

this.removeHeader('Content-Type');
this.removeHeader('Content-Encoding');
}

@@ -266,0 +277,0 @@

@@ -371,5 +371,11 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

var v = semver.maxSatisfying(k, req.version());
if (v && (!r || semver.gt(v, r.versions))) {
r = c.r;
params = c.p;
if (v) {
if (!r ||
r.versions.some(function (v2) {
return (semver.gt(v, v2));
})) {
r = c.r;
params = c.p;
}
}

@@ -376,0 +382,0 @@ });

@@ -656,2 +656,3 @@ // Copyright 2012 Mark Cavage, Inc. All rights reserved.

var self = this;
var t;

@@ -700,7 +701,13 @@ function next(arg) {

if ((i + 1) > 0 && chain[i] && !chain[i]._skip) {
var _name = chain[i].name || ('handler-' + i);
req.timers.push({
name: _name,
time: process.hrtime(t)
});
dtrace._rstfy_probes['handler-done'].fire(function () {
return ([
self.name,
route !== null ? route : 'pre',
chain[i].name || ('handler-' + i),
route !== null ? route.name : 'pre',
_name,
id

@@ -716,2 +723,3 @@ ]);

t = process.hrtime();
if (log.trace())

@@ -723,3 +731,3 @@ log.trace('running %s', chain[i].name || '?');

self.name,
route !== null ? route : 'pre',
route !== null ? route.name : 'pre',
chain[i].name || ('handler-' + i),

@@ -738,3 +746,3 @@ id

self.name,
route !== null ? route : 'pre',
route !== null ? route.name : 'pre',
id,

@@ -760,3 +768,3 @@ res.statusCode || 200,

self.name,
route !== null ? route : 'pre',
route !== null ? route.name : 'pre',
id,

@@ -769,2 +777,3 @@ req.method,

req.timers = [];
d = domain.create();

@@ -771,0 +780,0 @@ d.add(req);

@@ -17,2 +17,3 @@ {

"Erik Kristensen",
"Domikik Lessel",
"Steve Mason",

@@ -34,3 +35,3 @@ "Trent Mick",

"description": "REST framework",
"version": "2.6.0",
"version": "2.6.1",
"repository": {

@@ -51,5 +52,6 @@ "type": "git",

"dependencies": {
"assert-plus": "0.1.2",
"backoff": "2.2.0",
"bunyan": "0.21.1",
"assert-plus": "0.1.4",
"backoff": "2.3.0",
"bunyan": "0.22.0",
"csv": "0.3.6",
"deep-equal": "0.0.0",

@@ -60,10 +62,11 @@ "escape-regexp-component": "1.0.2",

"keep-alive-agent": "0.0.1",
"lru-cache": "2.3.0",
"mime": "1.2.9",
"negotiator": "0.2.5",
"lru-cache": "2.3.1",
"mime": "1.2.11",
"negotiator": "0.3.0",
"node-uuid": "1.4.0",
"once": "1.1.1",
"qs": "0.6.4",
"semver": "1.1.4",
"spdy": "1.8.2",
"once": "1.3.0",
"qs": "0.6.5",
"semver": "2.2.1",
"spdy": "1.14.12",
"tunnel-agent": "0.3.0",
"verror": "1.3.6"

@@ -75,5 +78,5 @@ },

"devDependencies": {
"cover": "0.2.8",
"filed": "0.0.7",
"nodeunit": "0.8.0",
"cover": "0.2.9",
"filed": "0.1.0",
"nodeunit": "0.8.1",
"watershed": "0.3.0"

@@ -80,0 +83,0 @@ },

@@ -12,37 +12,39 @@ # restify

## Server
```javascript
var restify = require('restify');
var restify = require('restify');
var server = restify.createServer({
name: 'myapp',
version: '1.0.0'
});
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());
var server = restify.createServer({
name: 'myapp',
version: '1.0.0'
});
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());
server.get('/echo/:name', function (req, res, next) {
res.send(req.params);
return next();
});
server.get('/echo/:name', function (req, res, next) {
res.send(req.params);
return next();
});
server.listen(8080, function () {
console.log('%s listening at %s', server.name, server.url);
});
```
server.listen(8080, function () {
console.log('%s listening at %s', server.name, server.url);
});
## Client
```javascript
var assert = require('assert');
var restify = require('restify');
var assert = require('assert');
var restify = require('restify');
var client = restify.createJsonClient({
url: 'http://localhost:8080',
version: '~1.0'
});
var client = restify.createJsonClient({
url: 'http://localhost:8080',
version: '~1.0'
});
client.get('/echo/mark', function (err, req, res, obj) {
assert.ifError(err);
console.log('Server returned: %j', obj);
});
```
client.get('/echo/mark', function (err, req, res, obj) {
assert.ifError(err);
console.log('Server returned: %j', obj);
});
# Installation

@@ -49,0 +51,0 @@

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc