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

restify

Package Overview
Dependencies
Maintainers
0
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 0.3.8 to 0.3.9

30

docs/restify.md

@@ -46,14 +46,19 @@ restify(3) -- Getting Started with restify

'application/json', // Allow these Accept types
'application/foo'
'application/foo'
],
contentHandlers: { // A hash of custom content-type handlers
'application/foo': function(body) {
return JSON.parse(body);
}
return JSON.parse(body);
}
},
contentWriters: { // A hash of custom serializers
'application/foo': function(obj) {
return JSON.stringify(obj);
}
return JSON.stringify(obj);
}
},
headers: { // A hash of customer headers
'X-Foo': function(res) {
return 'bar';
}
},
key: <PEM>, // Together with `cert`, create an SSL server

@@ -98,3 +103,18 @@ cert: <PEM> // Together with `key`, create an SSL server

`res.send` naturally with content-types not built-in to restify.
* headers:
An object of global headers that are sent back on all requests. Restify
automatically sets the list below. If you don't set those particular keys,
restify fills in default functions; if you do set them, you can fully override
restify's defaults. Note that like contentWriters, this is an object with a
string key as the header name, and the value is a function of the form
f(response) which must return a string. Defaults:
- X-Api-Version (if versioned)
- X-Request-Id
- X-Response-Time
- Content-(Length|Type|MD5)
- Access-Control-Allow-(Origin|Methods|Headers)
- Access-Control-Expose-Headers
## ROUTING

@@ -101,0 +121,0 @@

3

lib/client.js

@@ -407,3 +407,4 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.

if (res.body.length > 0) {
switch (res.headers['content-type']) {
var ct = res.headers['content-type'].split(';')[0];
switch (ct) {

@@ -410,0 +411,0 @@ case 'application/json':

@@ -64,2 +64,3 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.

}
this.options = _opts;

@@ -76,26 +77,9 @@ this._code = _opts.code;

// These headers allow strict clients (i.e. Google Chrome) to know that
// this server does allow itself to be invoked from pages that aren't
// part of the same origin policy.
headers['Access-Control-Allow-Origin'] = '*';
if (this._allowedMethods && this._allowedMethods.length)
headers['Access-Control-Allow-Methods'] = this._allowedMethods.join(', ');
if (!_opts.noClose)
headers.Connection = 'close';
if (this._version)
headers['X-Api-Version'] = this._version;
headers.Date = utils.newHttpDate(now);
headers.Server = this._config.serverName;
headers['X-Request-Id'] = this.requestId;
headers['X-Response-Time'] = this._time;
if (_opts.body && _opts.code !== HttpCodes.NoContent) {
headers['Content-Type'] = this._accept;
if (this._accept === 'application/x-www-form-urlencoded') {
data = querystring.stringify(_opts.body);
data = data + '\n';
} else if (this._accept === 'application/json') {
data = JSON.stringify(_opts.body);
data = data + '\n';
} else if (this._config.contentWriters[this._accept]) {

@@ -106,21 +90,21 @@ data = this._config.contentWriters[this._accept](_opts.body);

// actually be in this case.
data = _opts.body;
data = _opts.body + '';
}
}
this._data = data;
this._bytes = 0;
if (data && _opts.code !== HttpCodes.NoContent) {
data = data + '\n';
this._bytes = Buffer.byteLength(data, 'utf8');
if (!_opts.noContentMD5) {
var hash = crypto.createHash('md5');
hash.update(data);
headers['Content-MD5'] = hash.digest('base64');
if (!_opts.noClose)
headers.Connection = 'close';
headers.Date = utils.newHttpDate(now);
headers.Server = this._config.serverName;
for (var k in this._config.headers) {
if (this._config.headers.hasOwnProperty(k)) {
var val = this._config.headers[k](this);
if (val !== undefined && val !== null)
headers[k] = val;
}
}
if (!_opts.noEnd && this._method !== 'HEAD')
headers['Content-Length'] = this._bytes;
log.trace('response.send: code=%d, headers=%o, body=%s',

@@ -127,0 +111,0 @@ _opts.code, headers, data);

@@ -470,2 +470,17 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.

* and cannot be overridden.
* - headers: An object of global headers that are sent back
* on all requests. Restify automatically sets:
* - X-Api-Version (if versioned)
* - X-Request-Id
* - X-Response-Time
* - Content-(Length|Type|MD5)
* - Access-Control-Allow-(Origin|Methods|Headers)
* - Access-Control-Expose-Headers
* If you don't set those particular keys, restify
* fills in default functions; if you do set them,
* you can fully override restify's defaults.
* Note that like contentWriters, this is an object
* with a string key as the header name, and the
* value is a function of the form f(response)
* which must return a string.
*

@@ -475,3 +490,3 @@ * @return {Object} node HTTP server, with restify "magic".

createServer: function(options) {
var k;
var server;

@@ -496,3 +511,3 @@

response._method = request.method;
response._allowedMethods = [];
response._allowedMethods = ['OPTIONS'];
response._config = server._config;

@@ -612,2 +627,3 @@

server._config.contentWriters = {};
server._config.headers = {};

@@ -646,3 +662,2 @@ if (options) {

var k;
if (options.contentHandlers) {

@@ -675,2 +690,16 @@ if (typeof(options.contentHandlers) !== 'object')

}
if (options.headers) {
if (typeof(options.headers) !== 'object')
throw new TypeError('headers must be an object');
for (k in options.headers) {
if (options.headers.hasOwnProperty(k)) {
if (typeof(options.headers[k]) !== 'function')
throw new TypeError('headers values must be functions');
server._config.headers[k] = options.headers[k];
}
}
}
}

@@ -717,5 +746,124 @@

}
log.trace('server will accept types: %o', server._config.acceptable);
var foundXApiVersion = false;
var foundXRequestId = false;
var foundXResponseTime = false;
var foundContentLength = false;
var foundContentType = false;
var foundContentMD5 = false;
var foundACAO = false;
var foundACAM = false;
var foundACAH = false;
var foundACEH = false;
for (k in server._config.headers) {
if (server._config.headers.hasOwnProperty(k)) {
var h = k.toLowerCase();
switch (h) {
case 'x-api-version':
foundXApiVersion = true;
break;
case 'x-request-id':
foundXRequestId = true;
break;
case 'x-response-time':
foundXResponseTime = true;
break;
case 'content-length':
foundContentLength = true;
break;
case 'content-type':
foundContentType = true;
break;
case 'content-md5':
foundContentMD5 = true;
break;
case 'access-control-allow-origin':
foundACAO = true;
break;
case 'access-control-allow-method':
foundACAM = true;
break;
case 'access-control-allow-headers':
foundACAH = true;
break;
case 'access-control-expose-headers':
foundACEH = true;
break;
}
}
}
if (!foundXApiVersion) {
server._config.headers['X-Api-Version'] = function(res) {
return res._version;
};
}
if (!foundXRequestId) {
server._config.headers['X-Request-Id'] = function(res) {
return res.requestId;
};
}
if (!foundXResponseTime) {
server._config.headers['X-Response-Time'] = function(res) {
return res._time;
};
}
if (!foundContentLength) {
server._config.headers['Content-Length'] = function(res) {
if (!res.options.noEnd && res._method !== 'HEAD' && res._data) {
res._bytes = Buffer.byteLength(res._data, 'utf8');
}
return res._bytes;
};
}
if (!foundContentMD5) {
server._config.headers['Content-MD5'] = function(res) {
if (res._data && res.options.code !== 204) {
if (!res.options.noContentMD5) {
var hash = crypto.createHash('md5');
hash.update(res._data);
return hash.digest('base64');
}
}
};
}
if (!foundContentType) {
server._config.headers['Content-Type'] = function(res) {
if (res._data && res.options.code !== 204)
return res._accept;
};
}
if (!foundACAO) {
server._config.headers['Access-Control-Allow-Origin'] = function(res) {
return '*';
};
}
if (!foundACAM) {
server._config.headers['Access-Control-Allow-Methods'] = function(res) {
if (res._allowedMethods && res._allowedMethods.length)
return res._allowedMethods.join(', ');
};
}
if (!foundACAH) {
server._config.headers['Access-Control-Allow-Headers'] = function(res) {
return [
'Accept',
'Content-Type',
'Content-Length',
'Date',
'X-Api-Version'
].join(', ');
};
}
if (!foundACEH) {
server._config.headers['Access-Control-Expose-Headers'] = function(res) {
return [
'X-Api-Version',
'X-Request-Id',
'X-Response-Time'
].join(', ');
};
}
return server;

@@ -722,0 +870,0 @@ }

{
"name": "restify",
"description": "REST framework specifically meant for web service APIs",
"version": "0.3.8",
"version": "0.3.9",
"repository": {

@@ -6,0 +6,0 @@ "type": "git",

@@ -451,1 +451,42 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.

};
exports.test_custom_headers = function(test, assert) {
var server = restify.createServer({
headers: {
'access-control-allow-headers': function(res) {
return [
'x-unit-test'
].join(', ');
},
'X-Unit-Test': function(res) {
return 'foo';
}
}
});
server.get('/custom_headers', function(req, res, next) {
res.send(200);
return next();
});
var socket = '/tmp/.' + uuid();
server.listen(socket, function() {
var content = JSON.stringify({json: 'foo'});
var opts = common.newOptions(socket, '/custom_headers');
var req = http.request(opts, function(res) {
common.checkResponse(assert, res);
assert.equal(res.statusCode, 200);
console.log(res.headers);
assert.equal(res.headers['access-control-allow-headers'], 'x-unit-test');
assert.equal(res.headers['x-unit-test'], 'foo');
server.on('close', function() {
test.finish();
});
server.close();
});
req.write(content);
req.end();
});
};

Sorry, the diff of this file is not supported yet

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