Comparing version 0.1.13 to 0.1.14
@@ -25,2 +25,3 @@ restify-log(7) -- The restify Logger | ||
* Off | ||
* Fatal | ||
@@ -35,3 +36,3 @@ * Error | ||
output messages that are of level Fatal/Error/Warn. Everything else will be | ||
surpressed. The default level is Info. | ||
surpressed. The default level is Info. Off disables logging altogether. | ||
@@ -38,0 +39,0 @@ Each level is accessed by a lower-case method of the same name: |
@@ -78,3 +78,4 @@ restify-response(7) -- The Response Object | ||
noClose: boolean, | ||
noEnd: boolean | ||
noEnd: boolean, | ||
noContentMD5: boolean | ||
}); | ||
@@ -81,0 +82,0 @@ |
@@ -42,6 +42,6 @@ restify(3) -- Getting Started with restify | ||
serverName: 'MySite', // returned in the HTTP 'Server:` header | ||
exceptionHandler: function(e) {}, // calls function(2) on uncaught errors | ||
maxRequestSize: 8192, // Any request body larger than this gets a 400 | ||
clockSkew: 300, // Allow up to N seconds of skew in the Date header | ||
accept: ['application/json'] // Allow these Accept types | ||
accept: ['application/json'], // Allow these Accept types | ||
logTo: process.stderr // Where to direct log output | ||
} | ||
@@ -60,6 +60,2 @@ | ||
header. Defaults to `node.js`. | ||
* exceptionHandler: | ||
Installs your function to handle all uncaught JS exceptions. If you **don't** | ||
provide one, restify installs a default handler that simply returns 500 | ||
Internal Server Error, and logs a warning. | ||
* maxRequestSize: | ||
@@ -74,2 +70,5 @@ Caps the amount of data a client can send to your HTTP server, in bytes. | ||
`application/json`. Not really useful as of yet. | ||
* logTo: | ||
An instance of `Writable Stream`. All restify.log messages will go to that. | ||
Defaults to process.stderr. | ||
@@ -124,5 +123,5 @@ ## ROUTING | ||
param1: 'dog', | ||
param2: 'cat', | ||
param3: 'bird', | ||
param4: 'turtle' | ||
param2: 'cat', | ||
param3: 'bird', | ||
param4: 'turtle' | ||
} | ||
@@ -129,0 +128,0 @@ } |
@@ -5,5 +5,5 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
// Headers | ||
XRequestId: 'X-Request-Id', | ||
XApiVersion: 'X-Api-Version', | ||
XResponseTime: 'X-Response-Time', | ||
XRequestId: 'x-request-id', | ||
XApiVersion: 'x-api-version', | ||
XResponseTime: 'x-response-time', | ||
@@ -15,3 +15,4 @@ // Misc | ||
ContentTypeFormEncoded: 'application/x-www-form-urlencoded', | ||
DefaultServerName: 'node.js' | ||
DefaultServerName: 'node.js', | ||
NoApiVersion: '__no_version' | ||
}; |
@@ -15,2 +15,4 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
function _pad(val) { | ||
@@ -23,2 +25,3 @@ if (parseInt(val, 10) < 10) { | ||
function _rfc822(date) { | ||
@@ -48,26 +51,33 @@ var months = ['Jan', | ||
function _mergeFnArgs() { | ||
function _mergeFnArgs(argv, offset) { | ||
var _handlers = []; | ||
var _args = arguments[0]; | ||
var i = 1; | ||
do { | ||
if (_args[i] instanceof Array) { | ||
var _arr = _args[i]; | ||
for (var j = 0; j < _arr.length; j++) { | ||
if (!(_arr[j] instanceof Function)) { | ||
throw new Error('Invalid argument type: ' + typeof(_arr[j])); | ||
if (log.trace()) | ||
log.trace('_mergeFnArgs: argv=%o, offset=%d', argv, offset); | ||
for (var i = offset; i < argv.length; i++) { | ||
if (argv[i] instanceof Array) { | ||
var arr = argv[i]; | ||
for (var j = 0; j < arr.length; j++) { | ||
if (!(arr[j] instanceof Function)) { | ||
throw new TypeError('Invalid argument type: ' + typeof(arr[j])); | ||
} | ||
_handlers.push(_arr[j]); | ||
_handlers.push(arr[j]); | ||
} | ||
} else if (_args[i] instanceof Function) { | ||
_handlers.push(_args[i]); | ||
} else if (argv[i] instanceof Function) { | ||
_handlers.push(argv[i]); | ||
} else { | ||
throw new Error('Invalid argument type: ' + typeof(_args[i])); | ||
throw new TypeError('Invalid argument type: ' + typeof(argv[i])); | ||
} | ||
} while (++i < _args.length); | ||
} | ||
if (log.trace()) | ||
log.trace('_mergeFnArgs: %o', _handlers); | ||
return _handlers; | ||
} | ||
//////////////////////// | ||
@@ -133,4 +143,6 @@ // Prototype extensions | ||
if (this._config.apiVersion) | ||
headers[Constants.XApiVersion] = this._config.apiVersion; | ||
if (this._apiVersion && | ||
this._serverVersioned && | ||
this._apiVersion !== Constants.NoApiVersion) | ||
headers[Constants.XApiVersion] = this._apiVersion; | ||
@@ -160,7 +172,9 @@ headers.Date = _rfc822(now); | ||
this._bytes = data.length; | ||
var hash = crypto.createHash('md5'); | ||
hash.update(data); | ||
headers['Content-MD5'] = hash.digest(encoding = 'base64'); | ||
if (_opts.code !== HttpCodes.NoContent) { | ||
headers['Content-Length'] = data.length; | ||
if (!_opts.noContentMD5) { | ||
var hash = crypto.createHash('md5'); | ||
hash.update(data); | ||
headers['Content-MD5'] = hash.digest(encoding = 'base64'); | ||
} | ||
} else { | ||
@@ -190,2 +204,3 @@ headers['Content-Length'] = 0; | ||
http.ServerResponse.prototype.sendError = function sendError(error) { | ||
@@ -210,8 +225,37 @@ if (!error || !error.restCode || !error.message || !error.httpCode) { | ||
http.Server.prototype._mount = function _mount(method, url, handlers) { | ||
/** | ||
* Adds a route for handling. | ||
* | ||
* This method supports the notion of versioned routes. Basically, the routing | ||
* table looks like this: | ||
* | ||
* { | ||
* '1.2.3': | ||
* { | ||
* 'GET': | ||
* { | ||
* '/foo/bar': [f(req, res, next), ...], | ||
* } | ||
* } | ||
* } | ||
* | ||
* An identical "reverse" index is kept for mapping URLs to methods (so just | ||
* mentally swap foo/bar and GET above). | ||
* | ||
* @param {String} method HTTP method. | ||
* @param {String} url the HTTP resource. | ||
* @param {Array} handlers an array of function(req, res, next). | ||
* @param {String} version version for this route. | ||
* | ||
*/ | ||
http.Server.prototype._mount = function _mount(method, url, handlers, version) { | ||
if (version !== Constants.NoApiVersion) | ||
this._versioned = true; | ||
if (!this.routes) this.routes = {}; | ||
if (!this.routes[method]) this.routes[method] = []; | ||
// reverse index | ||
if (!this.routes[version]) this.routes[version] = {}; | ||
if (!this.routes[version][method]) this.routes[version][method] = []; | ||
if (!this.routes.urls) this.routes.urls = {}; | ||
if (!this.routes.urls[url]) this.routes.urls[url] = []; | ||
if (!this.routes.urls[version]) this.routes.urls[version] = {}; | ||
if (!this.routes.urls[version][url]) this.routes.urls[version][url] = []; | ||
@@ -231,3 +275,2 @@ var _handlers = []; | ||
var r = { | ||
@@ -237,36 +280,131 @@ method: method, | ||
handlers: _handlers, | ||
urlComponents: url.split('/').slice(1) | ||
urlComponents: url.split('/').slice(1), | ||
version: version | ||
}; | ||
this.routes[method].push(r); | ||
this.routes.urls[url].push(r); | ||
this.routes[version][method].push(r); | ||
this.routes.urls[version][url].push(r); | ||
if (log.trace()) | ||
log.trace('restify._mount: routes now %o', this.routes); | ||
}; | ||
http.Server.prototype.del = function(url) { | ||
if (!url) throw new Error('url is required'); | ||
return this._mount('DELETE', url, _mergeFnArgs(arguments)); | ||
http.Server.prototype.del = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var offset = 1; | ||
var url = args[0]; | ||
var version = this._config.defaultVersion; | ||
if (!args[0] || typeof(args[0]) !== 'string') | ||
throw new TypeError('argument 0 must be a string (version or url)'); | ||
if (!args[1]) | ||
throw new TypeError('argument 1 is required (handler chain or url)'); | ||
if (typeof(args[1]) === 'string') { | ||
version = args[0]; | ||
url = args[1]; | ||
offset = 2; | ||
} | ||
var handlers = _mergeFnArgs(args, offset); | ||
return this._mount('DELETE', url, handlers, version); | ||
}; | ||
http.Server.prototype.get = function(url) { | ||
if (!url) throw new Error('url is required'); | ||
return this._mount('GET', url, _mergeFnArgs(arguments)); | ||
http.Server.prototype.get = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var offset = 1; | ||
var url = args[0]; | ||
var version = this._config.defaultVersion; | ||
if (!args[0] || typeof(args[0]) !== 'string') | ||
throw new TypeError('argument 0 must be a string (version or url)'); | ||
if (!args[1]) | ||
throw new TypeError('argument 1 is required (handler chain or url)'); | ||
if (typeof(args[1]) === 'string') { | ||
version = args[0]; | ||
url = args[1]; | ||
offset = 2; | ||
} | ||
var handlers = _mergeFnArgs(args, offset); | ||
return this._mount('GET', url, handlers, version); | ||
}; | ||
http.Server.prototype.head = function(url, handlers) { | ||
if (!url) throw new Error('url is required'); | ||
return this._mount('HEAD', url, _mergeFnArgs(arguments)); | ||
http.Server.prototype.head = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var offset = 1; | ||
var url = args[0]; | ||
var version = this._config.defaultVersion; | ||
if (!args[0] || typeof(args[0]) !== 'string') | ||
throw new TypeError('argument 0 must be a string (version or url)'); | ||
if (!args[1]) | ||
throw new TypeError('argument 1 is required (handler chain or url)'); | ||
if (typeof(args[1]) === 'string') { | ||
version = args[0]; | ||
url = args[1]; | ||
offset = 2; | ||
} | ||
var handlers = _mergeFnArgs(args, offset); | ||
return this._mount('HEAD', url, handlers, version); | ||
}; | ||
http.Server.prototype.post = function(url, handlers) { | ||
if (!url) throw new Error('url is required'); | ||
return this._mount('POST', url, _mergeFnArgs(arguments)); | ||
http.Server.prototype.post = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var offset = 1; | ||
var url = args[0]; | ||
var version = this._config.defaultVersion; | ||
if (!args[0] || typeof(args[0]) !== 'string') | ||
throw new TypeError('argument 0 must be a string (version or url)'); | ||
if (!args[1]) | ||
throw new TypeError('argument 1 is required (handler chain or url)'); | ||
if (typeof(args[1]) === 'string') { | ||
version = args[0]; | ||
url = args[1]; | ||
offset = 2; | ||
} | ||
var handlers = _mergeFnArgs(args, offset); | ||
return this._mount('POST', url, handlers, version); | ||
}; | ||
http.Server.prototype.put = function(url, handlers) { | ||
if (!url) throw new Error('url is required'); | ||
return this._mount('PUT', url, _mergeFnArgs(arguments)); | ||
http.Server.prototype.put = function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var offset = 1; | ||
var url = args[0]; | ||
var version = this._config.defaultVersion; | ||
if (!args[0] || typeof(args[0]) !== 'string') | ||
throw new TypeError('argument 0 must be a string (version or url)'); | ||
if (!args[1]) | ||
throw new TypeError('argument 1 is required (handler chain or url)'); | ||
if (typeof(args[1]) === 'string') { | ||
version = args[0]; | ||
url = args[1]; | ||
offset = 2; | ||
} | ||
var handlers = _mergeFnArgs(args, offset); | ||
return this._mount('PUT', url, handlers, version); | ||
}; |
@@ -198,33 +198,5 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
/** | ||
* Fairly ugly and long method that does the brunt of the | ||
* work for setting up the processing chain. | ||
* | ||
* @param {Object} request node.js request. | ||
* @param {Object} response node.js response. | ||
* @param {Function} next the first call in the chain. | ||
* | ||
*/ | ||
function _parseRequest(request, response, next) { | ||
assert.ok(request); | ||
assert.ok(response); | ||
assert.ok(next); | ||
if (log.trace()) { | ||
log.trace('_parseRequest:\n%s %s HTTP/%s\nHeaders: %o', | ||
request.method, | ||
request.url, | ||
request.httpVersion, | ||
request.headers); | ||
} | ||
if (!_parseAccept(request, response)) return; | ||
if (!_parseDate(request, response)) return; | ||
// This is so common it's worth checking up front before we read data | ||
// TODO (mcavage) fix this | ||
var contentType = request.contentType(); | ||
if (contentType === 'multipart/form-data') { | ||
return response.sendError(newError({ | ||
function _parseContentType(request, response) { | ||
if (request.contentType() === 'multipart/form-data') { | ||
response.sendError(newError({ | ||
httpCode: HttpCodes.UnsupportedMediaType, | ||
@@ -234,17 +206,19 @@ restCode: RestCodes.InvalidArgument, | ||
})); | ||
return false; | ||
} | ||
return request.contentType(); | ||
} | ||
if (request._config.apiVersion) { | ||
if (request.headers[Constants.XApiVersion] || | ||
(request.headers[Constants.XApiVersion.toLowerCase()] !== | ||
request._config.apiVersion)) { | ||
return response.sendError(newError({ | ||
httpCode: HttpCodes.Conflict, | ||
restCode: RestCodes.InvalidArgument, | ||
message: Constants.XApiVersion + ' must be ' + | ||
request._config.apiVersion | ||
})); | ||
} | ||
function _parseApiVersion(request, response) { | ||
if (request.headers[Constants.XApiVersion] && request._serverVersioned) { | ||
request._apiVersion = request.headers[Constants.XApiVersion]; | ||
response._apiVersion = request.headers[Constants.XApiVersion]; | ||
} | ||
return true; | ||
} | ||
function _parseQueryString(request, response) { | ||
request._url = url.parse(request.url); | ||
@@ -260,3 +234,33 @@ if (request._url.query) { | ||
} | ||
return true; | ||
} | ||
function _parseHead(request, response) { | ||
assert.ok(request); | ||
assert.ok(response); | ||
if (log.trace()) { | ||
log.trace('_parseHead:\n%s %s HTTP/%s\nHeaders: %o', | ||
request.method, | ||
request.url, | ||
request.httpVersion, | ||
request.headers); | ||
} | ||
if (!_parseAccept(request, response)) return false; | ||
if (!_parseDate(request, response)) return false; | ||
if (!_parseApiVersion(request, response)) return false; | ||
if (!_parseQueryString(request, response)) return false; | ||
if (!_parseContentType(request, response)) return false; | ||
return true; | ||
} | ||
function _parseRequest(request, response, next) { | ||
assert.ok(request); | ||
assert.ok(response); | ||
assert.ok(next); | ||
request.body = ''; | ||
@@ -287,2 +291,4 @@ request.on('data', function(chunk) { | ||
} | ||
var contentType = request.contentType(); | ||
var bParams; | ||
@@ -347,5 +353,2 @@ if (contentType === Constants.ContentTypeFormEncoded) { | ||
* Default: application/json. | ||
* - clockSkew: If a Date header is present, allow N seconds | ||
* of skew. | ||
* Default: 300 | ||
* - apiVersion: Default API version to support; setting this | ||
@@ -355,4 +358,7 @@ * means clients are required to send an | ||
* Default: None. | ||
* - clockSkew: If a Date header is present, allow N seconds | ||
* of skew. | ||
* Default: 300 | ||
* - logTo: a `Writable Stream` where log messages should go. | ||
* Default: process.stderr | ||
* Default: process.stderr. | ||
* | ||
@@ -367,9 +373,14 @@ * @return {Object} node HTTP server, with restify "magic". | ||
_response = response; | ||
request.requestId = response.requestId = uuid().toLowerCase(); | ||
request.startTime = response.startTime = new Date().getTime(); | ||
request._serverVersioned = response._serverVersioned = server._versioned; | ||
request.requestId = response.requestId = uuid().toLowerCase(); | ||
request._apiVersion = server._config.defaultVersion; | ||
request._config = server._config; | ||
request.params = {}; | ||
request.uriParams = {}; | ||
response._apiVersion = server._config.defaultVersion; | ||
response._allowedMethods = []; | ||
response._config = server._config; | ||
request.startTime = response.startTime = new Date().getTime(); | ||
response._allowedMethods = []; | ||
@@ -381,4 +392,19 @@ var route; | ||
request.url = path; | ||
if (server.routes[request.method]) { | ||
var routes = server.routes[request.method]; | ||
if (!_parseHead(request, response)) return; | ||
if (!server.routes[request._apiVersion]) { | ||
if (log.trace()) { | ||
log.trace('restify: no routes (at all) found for version %s', | ||
request._apiVersion); | ||
} | ||
return response.send(HttpCodes.NotFound); | ||
} | ||
if (log.trace()) | ||
log.trace('Looking up route for API version: %s', request._apiVersion); | ||
if (server.routes[request._apiVersion][request.method]) { | ||
var routes = server.routes[request._apiVersion][request.method]; | ||
for (i = 0; i < routes.length; i++) { | ||
@@ -394,3 +420,3 @@ params = _matches(path, routes[i]); | ||
if (route) { | ||
server.routes.urls[route.url].forEach(function(r) { | ||
server.routes.urls[request._apiVersion][route.url].forEach(function(r) { | ||
response._allowedMethods.push(r.method); | ||
@@ -432,5 +458,9 @@ }); | ||
var _code = HttpCodes.NotFound; | ||
for (k in server.routes.urls) { | ||
if (server.routes.urls.hasOwnProperty(k)) { | ||
route = server.routes.urls[k]; | ||
for (k in server.routes.urls[request._apiVersion]) { | ||
if (server.routes.urls[request._apiVersion].hasOwnProperty(k)) { | ||
route = server.routes.urls[request._apiVersion][k]; | ||
if (log.trace()) | ||
log.trace('restify: 405 path: looking at route %o', route); | ||
var _methods = []; | ||
@@ -473,17 +503,9 @@ | ||
server._config.apiVersion = null; | ||
var installedExceptionHandler = false; | ||
if (options) { | ||
if (options.apiVersion) | ||
server._config.apiVersion = options.apiVersion; | ||
if (options.serverName) | ||
server._config.serverName = options.serverName; | ||
if (options.exceptionHandler) { | ||
process.on('uncaughtException', options.exceptionHandler); | ||
installedExceptionHandler = true; | ||
} | ||
if (options.apiVersion) | ||
server._config.defaultVersion = options.apiVersion; | ||
@@ -507,2 +529,5 @@ if (options.maxRequestSize) | ||
if (!server._config.defaultVersion) | ||
server._config.defaultVersion = Constants.NoApiVersion; | ||
if (!server._config.serverName) | ||
@@ -509,0 +534,0 @@ server._config.serverName = Constants.DefaultServerName; |
{ | ||
"name": "restify", | ||
"description": "REST framework specifically meant for web service APIs", | ||
"version": "0.1.13", | ||
"version": "0.1.14", | ||
"repository": { | ||
@@ -16,3 +16,3 @@ "type": "git", | ||
"pretest": "./node_modules/.bin/jshint lib tst", | ||
"test": "./node_modules/.bin/whiskey -t \"`find tst -name *.test.js | xargs`\"" | ||
"test": "./node_modules/.bin/whiskey --timeout 500 -t \"`find tst -name *.test.js | xargs`\"" | ||
}, | ||
@@ -19,0 +19,0 @@ "man": [ |
@@ -7,5 +7,5 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
var restify = require('../lib/restify'); | ||
restify.log.level(restify.LogLevel.Trace); | ||
// --- Globals | ||
@@ -12,0 +12,0 @@ |
@@ -104,187 +104,2 @@ // Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved. | ||
// exports.test_create_default_error_handler = function(test, assert) { | ||
// var server = restify.createServer(); | ||
// var socket = '/tmp/.' + uuid(); | ||
// server.get('/', function(req, res, next) { | ||
// fs.stat('/tmp', function(err, stats) { | ||
// throw new Error('Default me!'); | ||
// }); | ||
// }); | ||
// server.listen(socket, function() { | ||
// var opts = common.newOptions(socket, '/'); | ||
// http.request(opts, function(res) { | ||
// common.checkResponse(assert, res); | ||
// assert.equal(res.headers.server, 'node.js'); | ||
// assert.equal(res.statusCode, 500); | ||
// server.on('close', function() { | ||
// test.finish(); | ||
// }); | ||
// server.close(); | ||
// }).end(); | ||
// }); | ||
// }; | ||
// exports.test_create_user_error_handler = function(test, assert) { | ||
// var server = restify.createServer({ | ||
// onError: function(err, req, res) { | ||
// assert.ok(res); | ||
// res.send(503); | ||
// } | ||
// }); | ||
// var socket = '/tmp/.' + uuid(); | ||
// server.get('/', function(req, res, next) { throw new Error('503 me!'); }); | ||
// server.listen(socket, function() { | ||
// var opts = common.newOptions(socket, '/'); | ||
// http.request(opts, function(res) { | ||
// common.checkResponse(assert, res); | ||
// assert.equal(res.headers.server, 'node.js'); | ||
// assert.equal(res.statusCode, 503); | ||
// server.on('close', function() { | ||
// test.finish(); | ||
// }); | ||
// server.close(); | ||
// }).end(); | ||
// }); | ||
// }; | ||
exports.test_accept_default = function(test, assert) { | ||
var server = restify.createServer(); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
opts.headers.accept = 'application/json'; | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.headers.server, 'node.js'); | ||
assert.equal(res.statusCode, 200); | ||
server.on('close', function() { | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_accept_bad = function(test, assert) { | ||
var server = restify.createServer(); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
opts.headers.accept = 'application/xml'; | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.headers.server, 'node.js'); | ||
assert.equal(res.statusCode, 406); | ||
server.on('close', function() { | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_accept_partial_wildcard = function(test, assert) { | ||
var server = restify.createServer(); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
opts.headers.accept = 'application/*'; | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.headers.server, 'node.js'); | ||
assert.equal(res.statusCode, 200); | ||
server.on('close', function() { | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_accept_double_wildcard = function(test, assert) { | ||
var server = restify.createServer(); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
opts.headers.accept = '*/*'; | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.headers.server, 'node.js'); | ||
assert.equal(res.statusCode, 200); | ||
server.on('close', function() { | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_accept_explicit = function(test, assert) { | ||
var server = restify.createServer({ | ||
accept: ['text/html'] | ||
}); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
opts.headers.accept = 'text/html'; | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.headers.server, 'node.js'); | ||
assert.equal(res.statusCode, 200); | ||
server.on('close', function() { | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_multiple_accept = function(test, assert) { | ||
var server = restify.createServer({ | ||
accept: ['text/html', 'text/xml'] | ||
}); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
opts.headers.accept = 'text/xml'; | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.headers.server, 'node.js'); | ||
assert.equal(res.statusCode, 200); | ||
server.on('close', function() { | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_server_name = function(test, assert) { | ||
@@ -370,2 +185,3 @@ var server = restify.createServer({ | ||
http.request(opts, function(res) { | ||
res._skipAllowedMethods = true; | ||
common.checkResponse(assert, res); | ||
@@ -380,97 +196,1 @@ assert.equal(res.statusCode, 400); | ||
}; | ||
exports.test_log_stdout = function(test, assert) { | ||
var server = restify.createServer({ | ||
logTo: process.stdout | ||
}); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.statusCode, 200); | ||
server.on('close', function() { | ||
log.writeTo(process.stderr); | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_log_off = function(test, assert) { | ||
log.level(log.Level.Off); | ||
var server = restify.createServer(); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.statusCode, 200); | ||
server.on('close', function() { | ||
log.level(log.Level.Trace); | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_options_with_resource = function(test, assert) { | ||
var server = restify.createServer(); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.put('/', _handler); | ||
server.del('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '/'); | ||
opts.method = 'OPTIONS'; | ||
http.request(opts, function(res) { | ||
common.checkResponse(assert, res); | ||
assert.equal(res.statusCode, 200); | ||
assert.ok(res.headers.allow); | ||
assert.ok(res.headers.allow, 'GET, PUT, DELETE'); | ||
server.on('close', function() { | ||
test.finish(); | ||
}); | ||
server.close(); | ||
}).end(); | ||
}); | ||
}; | ||
exports.test_options_wildcard_resource = function(test, assert) { | ||
var server = restify.createServer(); | ||
var socket = '/tmp/.' + uuid(); | ||
server.get('/', _handler); | ||
server.put('/', _handler); | ||
server.del('/', _handler); | ||
server.listen(socket, function() { | ||
var opts = common.newOptions(socket, '*'); | ||
opts.method = 'OPTIONS'; | ||
http.request(opts, function(res) { | ||
res._skipAllowedMethods = true; | ||
common.checkResponse(assert, res); | ||
assert.equal(res.statusCode, 200); | ||
assert.ok(!res.headers.allow); | ||
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
117167
34
2218
5
11