| exports.contentHandler = function() { | ||
| return function(string) { | ||
| return JSON.parse(string); | ||
| }; | ||
| }; | ||
| exports.contentWriter = function() { | ||
| return function(body) { | ||
| return JSON.stringify(body); | ||
| }; | ||
| }; |
| /* | ||
| * This file provides a content handler that will send a response from restify | ||
| * as a jsonp callback | ||
| */ | ||
| var url; | ||
| url = require('url'); | ||
| /* | ||
| * Callback name variable defaults to 'callback' (which is normal) | ||
| * and this writer will look in that variable | ||
| * for the name of the function to call | ||
| */ | ||
| exports.contentWriter = function(key) { | ||
| if (key === null) { | ||
| key = 'callback'; | ||
| } | ||
| return function(obj, req, res) { | ||
| var callbackName, query, response; | ||
| query = url.parse(req.url, true).query; | ||
| callbackName = query[key] ? query[key] : 'callback'; | ||
| response = { | ||
| code: res.code, | ||
| data: obj | ||
| }; | ||
| res.code = 200; | ||
| return callbackName + '(' + JSON.stringify(response) + ');'; | ||
| }; | ||
| }; |
| var querystring = require('querystring'); | ||
| exports.contentHandler = function() { | ||
| return function(string) { | ||
| return querystring.parse(string) || {}; | ||
| }; | ||
| }; | ||
| exports.contentWriter = function() { | ||
| return function(body) { | ||
| data = querystring.stringify(body); | ||
| data = data + '\n'; | ||
| return data; | ||
| }; | ||
| }; |
+18
-21
@@ -66,21 +66,15 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
| this._code = _opts.code; | ||
| this.code = _opts.code; | ||
| this._time = now.getTime() - this.startTime; | ||
| var headers; | ||
| if (!_opts.headers) { | ||
| headers = {}; | ||
| this.headers = {}; | ||
| } else { | ||
| headers = _opts.headers; | ||
| this.headers = _opts.headers; | ||
| } | ||
| if (_opts.body && _opts.code !== HttpCodes.NoContent) { | ||
| 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]) { | ||
| data = this._config.contentWriters[this._accept](_opts.body); | ||
| if (this._config.contentWriters[this._accept]) { | ||
| data = this._config | ||
| .contentWriters[this._accept](_opts.body, this.request, this); | ||
| } else { | ||
@@ -96,6 +90,8 @@ // Just pass it through "broken", since we should never | ||
| if (!_opts.noClose) | ||
| headers.Connection = 'close'; | ||
| this.headers.Connection = 'close'; | ||
| headers.Date = utils.newHttpDate(now); | ||
| headers.Server = this._config.serverName; | ||
| this.headers.Date = | ||
| this.headers.Date ? this.headers.Date : utils.newHttpDate(now); | ||
| this.headers.Server = | ||
| this.headers.Server ? this.headers.Server : this._config.serverName; | ||
| for (var k in this._config.headers) { | ||
@@ -105,13 +101,14 @@ if (this._config.headers.hasOwnProperty(k)) { | ||
| if (val !== undefined && val !== null) | ||
| headers[k] = val; | ||
| // allow all of these to be overridden by the writer | ||
| this.headers[k] = this.headers[k] ? this.headers[k] : val; | ||
| } | ||
| } | ||
| this.__headers = headers; | ||
| this.__headers = this.headers; | ||
| log.trace('response.send: code=%d, headers=%o, body=%s', | ||
| _opts.code, headers, data); | ||
| this.code, this.headers, data); | ||
| if (!this._sent) { | ||
| this.writeHead(_opts.code, headers); | ||
| if (_opts.code !== HttpCodes.NoContent && this._method !== 'HEAD' && data) | ||
| this.writeHead(this.code, this.headers); | ||
| if (this.code !== HttpCodes.NoContent && this._method !== 'HEAD' && data) | ||
| this.write(data); | ||
@@ -122,3 +119,3 @@ | ||
| if (!_opts.noEnd) | ||
| if (!this.options.noEnd) | ||
| this.end(); | ||
@@ -125,0 +122,0 @@ } |
+1
-1
@@ -63,3 +63,3 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
| d.getUTCFullYear(), | ||
| _pad(d.getUTCMonth()), | ||
| _pad(d.getUTCMonth() + 1), | ||
| _pad(d.getUTCDate()), | ||
@@ -66,0 +66,0 @@ _pad(d.getUTCHours()), |
+69
-34
@@ -117,3 +117,2 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
| var _accept = new RegExp(mediaRanges[i].split(';')[0].replace(/\*/g, '.*')); | ||
| for (var j = 0; j < request._config.acceptable.length; j++) { | ||
@@ -341,9 +340,5 @@ if (_accept.test(request._config.acceptable[j])) { | ||
| try { | ||
| if (contentType === 'application/x-www-form-urlencoded') { | ||
| bParams = querystring.parse(request.body) || {}; | ||
| } else if (contentType === 'application/json') { | ||
| bParams = JSON.parse(request.body); | ||
| } else if (request._config.contentHandlers[contentType]) { | ||
| var fn = request._config.contentHandlers[contentType]; | ||
| bParams = fn(request.body); | ||
| if (request._config.contentHandlers[contentType]) { | ||
| bParams = request._config | ||
| .contentHandlers[contentType](request.body, request, response); | ||
| } else if (contentType) { | ||
@@ -463,11 +458,21 @@ return response.sendError(newError({ | ||
| * Default: process.stderr. | ||
| * - contentHandlers: An object of 'type' -> function(body). | ||
| * The function should return an Object of the | ||
| * parsed params. Note that JSON, form-urlencoded, | ||
| * and multipart are all "built in", and cannot be | ||
| * overridden. | ||
| * - contentWriters: An object of 'type' -> function(obj). | ||
| * The function should a string from the passed in | ||
| * Object. JSON and form-urlencoded are built-in | ||
| * and cannot be overridden. | ||
| * - contentHandlers: An object of | ||
| * 'type'-> function(body, req, res). | ||
| * or 'type'-> string where string is a built in | ||
| * content type, such as 'application/json'. | ||
| * Content types are overideable if you parse in | ||
| * a function instead of a string. | ||
| * Built in content types are: | ||
| * - application/json | ||
| * - application/x-www-form-urlencoded | ||
| * - application/jsonp | ||
| * Defaults to 'application/json' | ||
| * - contentWriters: An object of | ||
| * 'type' -> function(obj, req, res). | ||
| * or 'type' -> string where string is a built in | ||
| * content type, such as 'application/json'. | ||
| * The function should a return string from the | ||
| * passed in Object (obj). The same built in types | ||
| * as contentHandlers exist. | ||
| * Defaults to application/json. | ||
| * - headers: An object of global headers that are sent back | ||
@@ -511,2 +516,3 @@ * on all requests. Restify automatically sets: | ||
| response.request = request; | ||
| response._method = request.method; | ||
@@ -584,5 +590,8 @@ response._allowedMethods = ['OPTIONS']; | ||
| function runChain() { | ||
| return _parseRequest(request, response, function() { | ||
| return _parseRequest(request, response, function(had_err) { | ||
| var next = arguments.callee; | ||
| if (had_err) | ||
| response.sendError(had_err); | ||
| if (chain.length > 1) { | ||
@@ -677,27 +686,53 @@ // Check if we need to skip to the post chain | ||
| if (options.contentHandlers) { | ||
| if (typeof(options.contentHandlers) !== 'object') | ||
| throw new TypeError('contentHandlers must be an object'); | ||
| if (!options.contentHandlers) | ||
| options.contentHandlers = {'application/json' : 'application/json', | ||
| 'application/x-www-form-urlencoded' : | ||
| 'application/x-www-form-urlencoded'}; | ||
| for (k in options.contentHandlers) { | ||
| if (options.contentHandlers.hasOwnProperty(k)) { | ||
| if (typeof(options.contentHandlers[k]) !== 'function') | ||
| throw new TypeError('contentHandlers values must be functions'); | ||
| if (typeof(options.contentHandlers) !== 'object') | ||
| throw new TypeError('contentHandlers must be an object'); | ||
| for (k in options.contentHandlers) { | ||
| if (options.contentHandlers.hasOwnProperty(k)) { | ||
| if (typeof(options.contentHandlers[k]) === 'function') | ||
| server._config.contentHandlers[k] = options.contentHandlers[k]; | ||
| } | ||
| else if (typeof(options.contentHandlers[k]) === 'string') { | ||
| try { | ||
| typeH = /^(.*)\/(.*)$/i.exec(options.contentHandlers[k]); | ||
| server._config.contentHandlers[k] = | ||
| require('./contentTypes/' + typeH[2]).contentHandler(); | ||
| } catch (errH) { | ||
| throw new Error('could not import contentHandler ' + | ||
| options.contentHandlers[k]); | ||
| } | ||
| } else | ||
| throw new TypeError('contentWriters values must' + | ||
| ' be functions or type strings'); | ||
| } | ||
| } | ||
| if (options.contentWriters) { | ||
| if (typeof(options.contentWriters) !== 'object') | ||
| throw new TypeError('contentWriters must be an object'); | ||
| if (!options.contentWriters) //set up defaults | ||
| options.contentWriters = {'application/json' : 'application/json', | ||
| 'application/x-www-form-urlencoded' : | ||
| 'application/x-www-form-urlencoded'}; | ||
| for (k in options.contentWriters) { | ||
| if (options.contentWriters.hasOwnProperty(k)) { | ||
| if (typeof(options.contentWriters[k]) !== 'function') | ||
| throw new TypeError('contentWriters values must be functions'); | ||
| if (typeof(options.contentWriters) !== 'object') | ||
| throw new TypeError('contentWriters must be an object'); | ||
| for (k in options.contentWriters) { | ||
| if (options.contentWriters.hasOwnProperty(k)) { | ||
| if (typeof(options.contentWriters[k]) === 'function') | ||
| server._config.contentWriters[k] = options.contentWriters[k]; | ||
| } | ||
| else if (typeof(options.contentWriters[k]) === 'string') { | ||
| try { | ||
| typeW = /^(.*)\/(.*)$/i.exec(options.contentWriters[k]); | ||
| server._config.contentWriters[k] = | ||
| require('./contentTypes/' + typeW[2]).contentWriter(); | ||
| } catch (errW) { | ||
| throw new Error('could not import contentWriter ' + | ||
| options.contentWriters[k]); | ||
| } | ||
| } else | ||
| throw new TypeError('contentWriters values must be' + | ||
| ' functions or type strings'); | ||
| } | ||
@@ -704,0 +739,0 @@ } |
+3
-3
| { | ||
| "name": "restify", | ||
| "description": "REST framework specifically meant for web service APIs", | ||
| "version": "0.3.15", | ||
| "version": "0.4.0", | ||
| "repository": { | ||
@@ -34,7 +34,7 @@ "type": "git", | ||
| "jshint": "0.2.3", | ||
| "whiskey": "0.4.0" | ||
| "whiskey": "0.4.1" | ||
| }, | ||
| "engines": { | ||
| "node": "~0.4" | ||
| "node": ">=0.4" | ||
| } | ||
| } |
+25
-0
@@ -492,1 +492,26 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
| }; | ||
| exports.test_send_error = function(test, assert) { | ||
| var server = restify.createServer(); | ||
| var socket = '/tmp/.' + uuid(); | ||
| server.get('/foo', function(req, res, next) { | ||
| return next(newError()); | ||
| }); | ||
| server.listen(socket, function() { | ||
| var opts = common.newOptions(socket, '/users/1..15'); | ||
| http.get({ | ||
| path: '/foo', | ||
| socketPath: socket | ||
| }, function(res) { | ||
| common.checkResponse(assert, res); | ||
| assert.equal(res.statusCode, 500); | ||
| server.on('close', function() { | ||
| test.finish(); | ||
| }); | ||
| server.close(); | ||
| }).end(); | ||
| }); | ||
| }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
225532
1.68%53
6%4282
2.46%