2012-02-11 09:02:01 -08:00
|
|
|
// Copyright 2012 Mark Cavage, Inc. All rights reserved.
|
2011-12-19 13:49:03 -08:00
|
|
|
|
2015-05-20 18:46:32 -07:00
|
|
|
'use strict';
|
2017-10-24 10:05:49 +02:00
|
|
|
/* eslint-disable func-names */
|
2015-05-20 18:46:32 -07:00
|
|
|
|
2012-10-14 19:52:05 +00:00
|
|
|
var assert = require('assert-plus');
|
2015-09-14 16:06:35 -07:00
|
|
|
var bunyan = require('bunyan');
|
2016-03-18 13:38:09 -07:00
|
|
|
var childprocess = require('child_process');
|
2011-12-19 13:49:03 -08:00
|
|
|
var http = require('http');
|
2016-05-12 09:49:53 -07:00
|
|
|
var stream = require('stream');
|
2011-12-19 13:49:03 -08:00
|
|
|
|
2015-09-10 01:20:32 -07:00
|
|
|
var errors = require('restify-errors');
|
2012-01-21 16:05:28 -08:00
|
|
|
var filed = require('filed');
|
2015-06-29 19:31:06 -07:00
|
|
|
var restifyClients = require('restify-clients');
|
2016-12-06 18:29:36 +01:00
|
|
|
var uuid = require('uuid');
|
2011-12-19 13:49:03 -08:00
|
|
|
|
2015-06-21 16:04:00 -07:00
|
|
|
var RestError = errors.RestError;
|
2012-02-07 08:47:51 -08:00
|
|
|
var restify = require('../lib');
|
2011-12-19 13:49:03 -08:00
|
|
|
|
2015-05-20 18:46:32 -07:00
|
|
|
if (require.cache[__dirname + '/lib/helper.js']) {
|
2014-02-05 09:44:44 +01:00
|
|
|
delete require.cache[__dirname + '/lib/helper.js'];
|
2015-05-20 18:46:32 -07:00
|
|
|
}
|
2012-12-23 19:21:49 +00:00
|
|
|
var helper = require('./lib/helper.js');
|
2012-05-15 15:41:14 -07:00
|
|
|
|
2011-12-19 13:49:03 -08:00
|
|
|
///--- Globals
|
|
|
|
|
|
2012-05-15 15:41:14 -07:00
|
|
|
var after = helper.after;
|
|
|
|
|
var before = helper.before;
|
|
|
|
|
var test = helper.test;
|
|
|
|
|
|
2017-11-02 17:25:17 +01:00
|
|
|
var SKIP_IP_V6 = !!process.env.TEST_SKIP_IP_V6;
|
2012-10-15 16:17:42 +00:00
|
|
|
var PORT = process.env.UNIT_TEST_PORT || 0;
|
2012-05-15 15:41:14 -07:00
|
|
|
var CLIENT;
|
2015-09-08 00:37:58 -07:00
|
|
|
var FAST_CLIENT;
|
2012-05-15 15:41:14 -07:00
|
|
|
var SERVER;
|
2011-12-19 13:49:03 -08:00
|
|
|
|
2017-11-02 17:25:17 +01:00
|
|
|
if (SKIP_IP_V6) {
|
|
|
|
|
console.warning('IPv6 tests are skipped: No IPv6 network is available');
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-15 15:41:14 -07:00
|
|
|
///--- Tests
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
before(function(cb) {
|
2014-02-05 09:44:44 +01:00
|
|
|
try {
|
|
|
|
|
SERVER = restify.createServer({
|
|
|
|
|
dtrace: helper.dtrace,
|
2016-03-18 13:38:09 -07:00
|
|
|
handleUncaughtExceptions: true,
|
2014-02-05 09:44:44 +01:00
|
|
|
log: helper.getLog('server'),
|
2018-03-26 19:18:37 +02:00
|
|
|
version: ['2.0.0', '0.5.4', '1.4.3'],
|
|
|
|
|
ignoreTrailingSlash: true
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.listen(PORT, '127.0.0.1', function() {
|
2014-02-05 09:44:44 +01:00
|
|
|
PORT = SERVER.address().port;
|
2015-06-29 19:31:06 -07:00
|
|
|
CLIENT = restifyClients.createJsonClient({
|
2014-02-05 09:44:44 +01:00
|
|
|
url: 'http://127.0.0.1:' + PORT,
|
|
|
|
|
dtrace: helper.dtrace,
|
|
|
|
|
retry: false
|
|
|
|
|
});
|
2015-09-08 00:37:58 -07:00
|
|
|
FAST_CLIENT = restifyClients.createJsonClient({
|
|
|
|
|
url: 'http://127.0.0.1:' + PORT,
|
|
|
|
|
dtrace: helper.dtrace,
|
|
|
|
|
retry: false,
|
2015-09-14 16:06:35 -07:00
|
|
|
requestTimeout: 500
|
2015-09-08 00:37:58 -07:00
|
|
|
});
|
2014-02-05 09:44:44 +01:00
|
|
|
|
|
|
|
|
cb();
|
|
|
|
|
});
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error(e.stack);
|
|
|
|
|
process.exit(1);
|
|
|
|
|
}
|
2011-12-21 18:11:46 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
after(function(cb) {
|
2014-02-05 09:44:44 +01:00
|
|
|
try {
|
|
|
|
|
CLIENT.close();
|
2015-09-08 00:37:58 -07:00
|
|
|
FAST_CLIENT.close();
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.close(function() {
|
2014-02-05 09:44:44 +01:00
|
|
|
CLIENT = null;
|
2015-09-14 16:06:35 -07:00
|
|
|
FAST_CLIENT = null;
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER = null;
|
|
|
|
|
cb();
|
|
|
|
|
});
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error(e.stack);
|
|
|
|
|
process.exit(1);
|
|
|
|
|
}
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('listen and close (port only)', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var server = restify.createServer();
|
2017-10-31 19:29:49 +01:00
|
|
|
server.listen(0, function() {
|
|
|
|
|
server.close(function() {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
2012-05-15 15:41:14 -07:00
|
|
|
});
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('listen and close (port only) w/ port number as string', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var server = restify.createServer();
|
2017-10-31 19:29:49 +01:00
|
|
|
server.listen(String(0), function() {
|
|
|
|
|
server.close(function() {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
2012-05-15 15:41:14 -07:00
|
|
|
});
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('listen and close (socketPath)', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var server = restify.createServer();
|
2017-10-31 19:29:49 +01:00
|
|
|
server.listen('/tmp/.' + uuid(), function() {
|
|
|
|
|
server.close(function() {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
2015-02-16 11:29:28 -06:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-11-02 17:25:17 +01:00
|
|
|
// Run IPv6 tests only if IPv6 network is available
|
|
|
|
|
if (!SKIP_IP_V6) {
|
|
|
|
|
test('gh-751 IPv4/IPv6 server URL', function(t) {
|
|
|
|
|
t.equal(SERVER.url, 'http://127.0.0.1:' + PORT, 'ipv4 url');
|
2015-02-16 11:29:28 -06:00
|
|
|
|
2017-11-02 17:25:17 +01:00
|
|
|
var server = restify.createServer();
|
|
|
|
|
server.listen(PORT + 1, '::1', function() {
|
|
|
|
|
t.equal(server.url, 'http://[::1]:' + (PORT + 1), 'ipv6 url');
|
2015-02-16 11:29:28 -06:00
|
|
|
|
2017-11-02 17:25:17 +01:00
|
|
|
server.close(function() {
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-05-15 15:41:14 -07:00
|
|
|
});
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
2017-11-02 17:25:17 +01:00
|
|
|
}
|
2011-12-19 13:49:03 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('get (path only)', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var r = SERVER.get('/foo/:id', function echoId(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
2015-01-29 19:33:38 +01:00
|
|
|
t.equal(req.isUpload(), false);
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var count = 0;
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('after', function(req, res, route) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(req);
|
|
|
|
|
t.ok(res);
|
|
|
|
|
t.equal(r, route.name);
|
2015-05-22 19:58:34 -07:00
|
|
|
|
2015-05-20 18:46:32 -07:00
|
|
|
if (++count === 2) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
2015-05-20 18:46:32 -07:00
|
|
|
}
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/bar', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2015-05-22 19:58:34 -07:00
|
|
|
|
2015-05-20 18:46:32 -07:00
|
|
|
if (++count === 2) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
2015-05-20 18:46:32 -07:00
|
|
|
}
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2018-03-26 19:18:37 +02:00
|
|
|
test('get (path only - with trailing slash)', function(t) {
|
|
|
|
|
SERVER.get('/foo/', function echoId(req, res, next) {
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo/', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
|
|
|
|
|
if (++count === 2) {
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
|
|
|
|
|
if (++count === 2) {
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('get (path only - with trailing slash and nested route)', function(t) {
|
|
|
|
|
SERVER.get('/foo/', function echoId(req, res, next) {
|
|
|
|
|
res.statusCode = 200;
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.get('/foo/bar', function echoId(req, res, next) {
|
|
|
|
|
res.statusCode = 201;
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo/', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
|
|
|
|
|
if (++count === 4) {
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
|
|
|
|
|
if (++count === 4) {
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo/bar/', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 201);
|
|
|
|
|
|
|
|
|
|
if (++count === 4) {
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo/bar', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 201);
|
|
|
|
|
|
|
|
|
|
if (++count === 4) {
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('use + get (path only)', function(t) {
|
|
|
|
|
SERVER.use(function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
SERVER.get('/foo/:id', function tester(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/bar', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('rm', function(t) {
|
2018-02-23 11:20:44 -08:00
|
|
|
var routeName = SERVER.get('/foo/:id', function foosy(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.get('/bar/:id', function barsy(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'foo');
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
t.ok(SERVER.rm(routeName));
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/bar', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 404);
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/bar/foo', function(err2, __, res2) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err2);
|
|
|
|
|
t.equal(res2.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-12-18 18:59:17 +01:00
|
|
|
test(
|
2018-02-23 11:20:44 -08:00
|
|
|
'_routeErrorResponse does not cause uncaughtException when called when' +
|
|
|
|
|
'header has already been sent',
|
2017-12-18 18:59:17 +01:00
|
|
|
function(t) {
|
|
|
|
|
SERVER.on('MethodNotAllowed', function(req, res, error, next) {
|
|
|
|
|
res.json(405, { status: 'MethodNotAllowed' });
|
|
|
|
|
try {
|
|
|
|
|
next();
|
|
|
|
|
} catch (err) {
|
|
|
|
|
t.fail(
|
|
|
|
|
'next() should not throw error' +
|
|
|
|
|
'when header has already been sent'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2017-11-21 08:04:32 +01:00
|
|
|
|
2017-12-18 18:59:17 +01:00
|
|
|
SERVER.post('/routePostOnly', function tester(req, res, next) {
|
2017-10-31 19:29:49 +01:00
|
|
|
next();
|
2017-12-18 18:59:17 +01:00
|
|
|
});
|
2016-09-27 16:43:40 -04:00
|
|
|
|
2017-12-18 18:59:17 +01:00
|
|
|
CLIENT.get('/routePostOnly', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 405);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
2016-09-27 16:43:40 -04:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('use - throws TypeError on non function as argument', function(t) {
|
2015-12-17 00:35:39 -08:00
|
|
|
var errMsg = 'handler (function) is required';
|
2012-10-14 19:52:05 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
t.throws(
|
|
|
|
|
function() {
|
|
|
|
|
SERVER.use('/nonfn');
|
|
|
|
|
},
|
|
|
|
|
assert.AssertionError,
|
|
|
|
|
errMsg
|
|
|
|
|
);
|
2012-10-14 19:52:05 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
t.throws(
|
|
|
|
|
function() {
|
|
|
|
|
SERVER.use({ an: 'object' });
|
|
|
|
|
},
|
|
|
|
|
assert.AssertionError,
|
|
|
|
|
errMsg
|
|
|
|
|
);
|
2012-10-14 19:52:05 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
t.throws(
|
|
|
|
|
function() {
|
|
|
|
|
SERVER.use(
|
|
|
|
|
function good(req, res, next) {
|
|
|
|
|
next();
|
|
|
|
|
},
|
|
|
|
|
'/bad',
|
|
|
|
|
{
|
|
|
|
|
really: 'bad'
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
assert.AssertionError,
|
|
|
|
|
errMsg
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-05-15 15:41:14 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('405', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.post('/foo/:id', function posty(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/bar', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 405);
|
|
|
|
|
t.equal(res.headers.allow, 'POST');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('PUT ok', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.put('/foo/:id', function tester(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
2015-01-29 19:33:38 +01:00
|
|
|
t.equal(req.isUpload(), true);
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.put('/foo/bar', {}, function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('PATCH ok', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.patch('/foo/:id', function tester(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
2015-01-29 19:33:38 +01:00
|
|
|
t.equal(req.isUpload(), true);
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
2015-06-24 16:47:54 -07:00
|
|
|
hostname: '127.0.0.1',
|
2014-02-05 09:44:44 +01:00
|
|
|
port: PORT,
|
|
|
|
|
path: '/foo/bar',
|
|
|
|
|
method: 'PATCH',
|
|
|
|
|
agent: false
|
|
|
|
|
};
|
2018-06-05 16:55:05 -07:00
|
|
|
http.request(opts, function(res) {
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
res.on('end', function() {
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
res.resume();
|
|
|
|
|
}).end();
|
2012-04-16 11:44:31 -04:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('HEAD ok', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.head('/foo/:id', function tester(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
2015-01-29 19:33:38 +01:00
|
|
|
t.equal(req.isUpload(), false);
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send('hi there');
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
2015-06-24 16:47:54 -07:00
|
|
|
hostname: '127.0.0.1',
|
2014-02-05 09:44:44 +01:00
|
|
|
port: PORT,
|
|
|
|
|
path: '/foo/bar',
|
|
|
|
|
method: 'HEAD',
|
|
|
|
|
agent: false
|
|
|
|
|
};
|
2018-06-05 16:55:05 -07:00
|
|
|
http.request(opts, function(res) {
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
res.on('data', function(chunk) {
|
|
|
|
|
t.fail('Data was sent on HEAD');
|
|
|
|
|
});
|
|
|
|
|
res.on('end', function() {
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
}).end();
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('DELETE ok', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.del('/foo/:id', function tester(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
2015-01-29 19:33:38 +01:00
|
|
|
t.equal(req.isUpload(), false);
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(204, 'hi there');
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
2015-06-24 16:47:54 -07:00
|
|
|
hostname: '127.0.0.1',
|
2014-02-05 09:44:44 +01:00
|
|
|
port: PORT,
|
|
|
|
|
path: '/foo/bar',
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
agent: false
|
|
|
|
|
};
|
2018-06-05 16:55:05 -07:00
|
|
|
http.request(opts, function(res) {
|
|
|
|
|
t.equal(res.statusCode, 204);
|
|
|
|
|
res.on('data', function(chunk) {
|
|
|
|
|
t.fail('Data was sent on 204');
|
|
|
|
|
});
|
|
|
|
|
t.end();
|
|
|
|
|
}).end();
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('OPTIONS', function(t) {
|
|
|
|
|
['get', 'post', 'put', 'del'].forEach(function(method) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER[method]('/foo/:id', function tester(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
2015-06-24 16:47:54 -07:00
|
|
|
hostname: '127.0.0.1',
|
2014-02-05 09:44:44 +01:00
|
|
|
port: PORT,
|
|
|
|
|
path: '*',
|
|
|
|
|
method: 'OPTIONS',
|
|
|
|
|
agent: false
|
|
|
|
|
};
|
2018-06-05 16:55:05 -07:00
|
|
|
http.request(opts, function(res) {
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
}).end();
|
2011-12-19 13:49:03 -08:00
|
|
|
});
|
2012-01-21 16:05:28 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('RegExp ok', function(t) {
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.get('/example/:file(^\\d+).png', function tester(req, res, next) {
|
|
|
|
|
t.deepEqual(req.params, {
|
|
|
|
|
file: '12'
|
|
|
|
|
});
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send('hi there');
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
CLIENT.get('/example/12.png', function(err, _, res, obj) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.equal(obj, 'hi there');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-05-15 15:41:14 -07:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('get (path and version ok)', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
url: '/foo/:id',
|
|
|
|
|
version: '1.2.3'
|
|
|
|
|
},
|
|
|
|
|
function tester(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
|
|
|
|
var opts = {
|
|
|
|
|
path: '/foo/bar',
|
|
|
|
|
headers: {
|
|
|
|
|
'accept-version': '~1.2'
|
|
|
|
|
}
|
|
|
|
|
};
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get(opts, function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-05-15 15:41:14 -07:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-56 streaming with filed (download)', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.get('/', function tester(req, res, next) {
|
|
|
|
|
filed(__filename).pipe(res);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
2015-06-24 16:47:54 -07:00
|
|
|
hostname: '127.0.0.1',
|
2014-02-05 09:44:44 +01:00
|
|
|
port: PORT,
|
|
|
|
|
path: '/',
|
|
|
|
|
method: 'GET',
|
|
|
|
|
agent: false
|
|
|
|
|
};
|
2018-06-05 16:55:05 -07:00
|
|
|
http.request(opts, function(res) {
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
var body = '';
|
|
|
|
|
res.setEncoding('utf8');
|
|
|
|
|
res.on('data', function(chunk) {
|
|
|
|
|
body += chunk;
|
|
|
|
|
});
|
|
|
|
|
res.on('end', function() {
|
|
|
|
|
t.ok(body.length > 0);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
}).end();
|
2012-01-28 10:40:02 -06:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-63 res.send 204 is sending a body', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.del('/hello/:name', function tester(req, res, next) {
|
|
|
|
|
res.send(204);
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
2015-06-24 16:47:54 -07:00
|
|
|
hostname: '127.0.0.1',
|
2014-02-05 09:44:44 +01:00
|
|
|
port: PORT,
|
|
|
|
|
path: '/hello/mark',
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
agent: false,
|
|
|
|
|
headers: {
|
|
|
|
|
accept: 'text/plain'
|
|
|
|
|
}
|
|
|
|
|
};
|
2012-05-15 15:41:14 -07:00
|
|
|
|
2018-06-05 16:55:05 -07:00
|
|
|
http.request(opts, function(res) {
|
|
|
|
|
t.equal(res.statusCode, 204);
|
|
|
|
|
var body = '';
|
|
|
|
|
res.setEncoding('utf8');
|
|
|
|
|
res.on('data', function(chunk) {
|
|
|
|
|
body += chunk;
|
|
|
|
|
});
|
|
|
|
|
res.on('end', function() {
|
|
|
|
|
t.notOk(body);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
}).end();
|
2012-01-21 16:05:28 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-64 prerouting chain', function(t) {
|
|
|
|
|
SERVER.pre(function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
req.log.debug('testing log is set');
|
|
|
|
|
req.headers.accept = 'application/json';
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.get('/hello/:name', function tester(req, res, next) {
|
|
|
|
|
res.send(req.params.name);
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
2015-06-24 16:47:54 -07:00
|
|
|
hostname: '127.0.0.1',
|
2014-02-05 09:44:44 +01:00
|
|
|
port: PORT,
|
|
|
|
|
path: '/hello/mark',
|
|
|
|
|
method: 'GET',
|
|
|
|
|
agent: false,
|
|
|
|
|
headers: {
|
|
|
|
|
accept: 'text/plain'
|
|
|
|
|
}
|
|
|
|
|
};
|
2018-06-05 16:55:05 -07:00
|
|
|
http.request(opts, function(res) {
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
var body = '';
|
|
|
|
|
res.setEncoding('utf8');
|
|
|
|
|
res.on('data', function(chunk) {
|
|
|
|
|
body += chunk;
|
|
|
|
|
});
|
|
|
|
|
res.on('end', function() {
|
|
|
|
|
t.equal(body, '"mark"');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
}).end();
|
2017-10-31 19:29:49 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('GH-64 prerouting chain with error', function(t) {
|
|
|
|
|
SERVER.pre(function(req, res, next) {
|
|
|
|
|
next(
|
|
|
|
|
new RestError(
|
|
|
|
|
{
|
|
|
|
|
statusCode: 400,
|
|
|
|
|
restCode: 'BadRequest'
|
|
|
|
|
},
|
|
|
|
|
'screw you client'
|
|
|
|
|
)
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.get('/hello/:name', function tester(req, res, next) {
|
|
|
|
|
res.send(req.params.name);
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/hello/mark', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 400);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-02-01 09:46:17 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-67 extend access-control headers', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.get('/hello/:name', function tester(req, res, next) {
|
2017-10-31 19:29:49 +01:00
|
|
|
res.header(
|
|
|
|
|
'Access-Control-Allow-Headers',
|
|
|
|
|
res.header('Access-Control-Allow-Headers') +
|
|
|
|
|
', If-Match, If-None-Match'
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
|
|
|
|
res.send(req.params.name);
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/hello/mark', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.ok(res.headers['access-control-allow-headers'].indexOf('If-Match'));
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
|
|
|
|
});
|
2012-02-03 09:40:01 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-77 uncaughtException (default behavior)', function(t) {
|
|
|
|
|
SERVER.get('/', function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
throw new Error('Catch me!');
|
|
|
|
|
});
|
2012-02-20 10:38:37 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
2018-10-29 17:42:35 -07:00
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line
|
|
|
|
|
test('handleUncaughtExceptions should not call handler for internal errors', function(t) {
|
|
|
|
|
SERVER.get('/', function(req, res, next) {
|
|
|
|
|
// This route is not used for the test but at least one route needs to
|
|
|
|
|
// be registered to Restify in order for routing logic to be run
|
|
|
|
|
assert.fail('should not run');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.on('uncaughtException', function throwError(err) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.head('/', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 405);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line
|
|
|
|
|
test('handleUncaughtExceptions should not call handler for next(new Error())', function(t) {
|
|
|
|
|
SERVER.get('/', function(req, res, next) {
|
|
|
|
|
next(new Error('I am not fatal'));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.on('uncaughtException', function throwError(err) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
|
|
|
|
});
|
2012-02-20 10:38:37 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-77 uncaughtException (with custom handler)', function(t) {
|
|
|
|
|
SERVER.on('uncaughtException', function(req, res, route, err) {
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(204);
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/', function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
throw new Error('Catch me!');
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 204);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-03-05 16:45:57 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-180 can parse DELETE body', function(t) {
|
|
|
|
|
SERVER.use(restify.plugins.bodyParser({ mapParams: false }));
|
2012-12-26 22:40:19 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.del('/', function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(200, req.body);
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
2015-06-24 16:47:54 -07:00
|
|
|
hostname: '127.0.0.1',
|
2014-02-05 09:44:44 +01:00
|
|
|
port: PORT,
|
|
|
|
|
path: '/',
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
agent: false,
|
|
|
|
|
headers: {
|
2015-05-22 12:14:52 -07:00
|
|
|
accept: 'application/json',
|
2014-02-05 09:44:44 +01:00
|
|
|
'content-type': 'application/json',
|
|
|
|
|
'transfer-encoding': 'chunked'
|
|
|
|
|
}
|
|
|
|
|
};
|
2018-06-05 16:55:05 -07:00
|
|
|
http.request(opts, function(res) {
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
res.setEncoding('utf8');
|
|
|
|
|
res.body = '';
|
|
|
|
|
res.on('data', function(chunk) {
|
|
|
|
|
res.body += chunk;
|
|
|
|
|
});
|
|
|
|
|
res.on('end', function() {
|
|
|
|
|
t.equal(res.body, '{"param1":1234}');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
}).end('{"param1": 1234}');
|
2012-12-26 22:40:19 +00:00
|
|
|
});
|
2012-12-27 01:41:33 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('returning error from a handler (with domains)', function(t) {
|
|
|
|
|
SERVER.get('/', function(req, res, next) {
|
2016-05-13 15:49:40 -07:00
|
|
|
next(new errors.InternalError('bah!'));
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
2012-12-27 01:41:33 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-12-27 01:41:33 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('emitting error from a handler (with domains)', function(t) {
|
|
|
|
|
SERVER.get('/', function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
req.emit('error', new Error('bah!'));
|
|
|
|
|
});
|
2012-12-27 01:41:33 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-12-27 01:41:33 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('re-emitting redirect from a response', function(t) {
|
2015-12-15 11:42:16 -08:00
|
|
|
var redirectLocation;
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.on('redirect', function(payload) {
|
2015-12-15 11:42:16 -08:00
|
|
|
redirectLocation = payload;
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/', function(req, res, next) {
|
2015-12-15 11:42:16 -08:00
|
|
|
res.redirect('/10', next);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2015-12-15 11:42:16 -08:00
|
|
|
t.equal(redirectLocation, '/10');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('throwing error from a handler (with domains)', function(t) {
|
|
|
|
|
SERVER.get('/', function(req, res, next) {
|
|
|
|
|
process.nextTick(function() {
|
2014-02-05 09:44:44 +01:00
|
|
|
throw new Error('bah!');
|
2012-12-27 01:41:33 +00:00
|
|
|
});
|
2014-02-05 09:44:44 +01:00
|
|
|
});
|
2012-12-27 01:41:33 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2012-12-27 01:41:33 +00:00
|
|
|
});
|
2013-01-03 02:12:32 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-278 missing router error events (404)', function(t) {
|
|
|
|
|
SERVER.once('NotFound', function(req, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(404, 'foo');
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/' + uuid.v4(), function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.message, '"foo"');
|
|
|
|
|
t.equal(res.statusCode, 404);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-01-03 02:12:32 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-278 missing router error events (405)', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var p = '/' + uuid.v4();
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.post(p, function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(201);
|
|
|
|
|
next();
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('MethodNotAllowed', function(req, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(405, 'foo');
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get(p, function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.message, '"foo"');
|
|
|
|
|
t.equal(res.statusCode, 405);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-01-03 02:12:32 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-329 wrong values in res.methods', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
function route(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SERVER.get('/stuff', route);
|
|
|
|
|
SERVER.post('/stuff', route);
|
|
|
|
|
SERVER.get('/stuff/:id', route);
|
|
|
|
|
SERVER.put('/stuff/:id', route);
|
|
|
|
|
SERVER.del('/stuff/:id', route);
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('MethodNotAllowed', function(req, res, cb) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(res.methods);
|
2018-02-23 11:20:44 -08:00
|
|
|
t.deepEqual(res.methods, ['DELETE', 'GET', 'PUT']);
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(405);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.post('/stuff/foo', {}, function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-02-18 09:21:37 -08:00
|
|
|
});
|
2013-02-24 20:55:33 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH #704: Route with a valid RegExp params', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'regexp_param1',
|
|
|
|
|
path: '/foo/:id([0-9]+)'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
t.equal(req.params.id, '0123456789');
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2013-02-24 20:55:33 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/0123456789', function(err, _, res) {
|
2015-02-26 11:57:25 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
test('GH #704: Route with an invalid RegExp params', function(t) {
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'regexp_param2',
|
|
|
|
|
path: '/foo/:id([0-9]+)'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
t.equal(req.params.id, 'A__M');
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2015-02-26 11:57:25 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/A__M', function(err, _, res) {
|
2015-02-26 11:57:25 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 404);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-193 basic', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
next('bar');
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-03-12 01:15:54 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-193 route name normalization', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
next('b-a-r');
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-12-10 11:03:26 +11:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'b-a-r',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-12-10 11:03:26 +11:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2014-12-10 11:03:26 +11:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-193 route ENOEXIST', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
next('baz');
|
|
|
|
|
}
|
|
|
|
|
);
|
2013-03-12 01:15:54 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-03-12 01:15:54 +00:00
|
|
|
});
|
|
|
|
|
|
2017-11-27 18:47:52 +01:00
|
|
|
test('run param only with existing req.params', function(t) {
|
|
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
|
|
SERVER.param('name', function(req, res, next) {
|
|
|
|
|
count++;
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.param('userId', function(req, res, next) {
|
2017-11-27 18:47:52 +01:00
|
|
|
count++;
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.get('/users/:userId', function(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/users/1', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.equal(count, 1);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
test('run param only with existing req.params', function(t) {
|
2017-11-27 18:47:52 +01:00
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
|
|
SERVER.param('name', function(req, res, next) {
|
|
|
|
|
count++;
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.param('userId', function(req, res, next, param, name) {
|
2018-02-23 11:20:44 -08:00
|
|
|
t.equal(param, '1');
|
2017-11-27 18:47:52 +01:00
|
|
|
t.equal(name, 'userId');
|
|
|
|
|
count++;
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.get('/users/:userId', function(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
CLIENT.get('/users/1', function(err, _, res) {
|
2017-11-27 18:47:52 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.equal(count, 1);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-193 route only run use once', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var count = 0;
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.use(function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
count++;
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
next('bar');
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.equal(count, 1);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-03-12 01:15:54 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-193 route chained', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
|
|
SERVER.use(function addCounter(req, res, next) {
|
|
|
|
|
count++;
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function getFoo(req, res, next) {
|
|
|
|
|
next('bar');
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function getBar(req, res, next) {
|
|
|
|
|
next('baz');
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'baz',
|
|
|
|
|
path: '/baz'
|
|
|
|
|
},
|
|
|
|
|
function getBaz(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2018-02-23 11:20:44 -08:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2014-02-05 09:44:44 +01:00
|
|
|
t.equal(count, 1);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-03-12 01:15:54 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-193 route params basic', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var count = 0;
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.use(function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
count++;
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo/:id'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
t.equal(req.params.id, 'blah');
|
|
|
|
|
next('bar');
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar/:baz'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
t.notOk(req.params.baz);
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/blah', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.equal(count, 1);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-03-12 01:15:54 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-193 next("route") from a use plugin', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
var count = 0;
|
|
|
|
|
|
|
|
|
|
SERVER.use(function plugin(req, res, next) {
|
|
|
|
|
count++;
|
|
|
|
|
next('bar');
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function getFoo(req, res, next) {
|
|
|
|
|
res.send(500);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function getBar(req, res, next) {
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-02-05 09:44:44 +01:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.equal(count, 1);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-02-28 15:47:43 +00:00
|
|
|
});
|
2013-04-10 15:50:31 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('res.charSet', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.get('/foo', function getFoo(req, res, next) {
|
|
|
|
|
res.charSet('ISO-8859-1');
|
|
|
|
|
res.set('Content-Type', 'text/plain');
|
2017-10-31 19:29:49 +01:00
|
|
|
res.send(200, { foo: 'bar' });
|
2014-02-05 09:44:44 +01:00
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.equal(res.headers['content-type'], 'text/plain; charset=ISO-8859-1');
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
|
|
|
|
});
|
2013-04-10 15:50:31 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('res.charSet override', function(t) {
|
2014-02-05 09:44:44 +01:00
|
|
|
SERVER.get('/foo', function getFoo(req, res, next) {
|
|
|
|
|
res.charSet('ISO-8859-1');
|
|
|
|
|
res.set('Content-Type', 'text/plain;charset=utf-8');
|
2017-10-31 19:29:49 +01:00
|
|
|
res.send(200, { foo: 'bar' });
|
2014-02-05 09:44:44 +01:00
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.equal(res.headers['content-type'], 'text/plain; charset=ISO-8859-1');
|
2014-02-05 09:44:44 +01:00
|
|
|
t.end();
|
|
|
|
|
});
|
2013-04-10 15:50:31 +00:00
|
|
|
});
|
2013-05-03 15:38:48 +00:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-384 res.json(200, {}) broken', function(t) {
|
|
|
|
|
SERVER.get('/foo', function(req, res, next) {
|
|
|
|
|
res.json(200, { foo: 'bar' });
|
2014-02-05 09:44:44 +01:00
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res, obj) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.ok(obj);
|
|
|
|
|
t.equal((obj || {}).foo, 'bar');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-05-21 23:22:05 +00:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('explicitly sending a 403 with custom error', function(t) {
|
|
|
|
|
function MyCustomError() {}
|
2013-12-10 17:31:40 +02:00
|
|
|
|
2014-02-05 09:44:44 +01:00
|
|
|
MyCustomError.prototype = Object.create(Error.prototype);
|
2013-12-10 17:31:40 +02:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/', function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(403, new MyCustomError('bah!'));
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 403);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-12-10 17:31:40 +02:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('explicitly sending a 403 on error', function(t) {
|
|
|
|
|
SERVER.get('/', function(req, res, next) {
|
2014-02-05 09:44:44 +01:00
|
|
|
res.send(403, new Error('bah!'));
|
|
|
|
|
});
|
2013-12-10 17:31:40 +02:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2014-02-05 09:44:44 +01:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 403);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2013-12-10 17:31:40 +02:00
|
|
|
});
|
2015-01-21 13:55:10 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('fire event on error', function(t) {
|
|
|
|
|
SERVER.once('InternalServer', function(req, res, err, cb) {
|
2015-01-21 13:55:10 -08:00
|
|
|
t.ok(req);
|
|
|
|
|
t.ok(res);
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.ok(cb);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.equal(typeof cb, 'function');
|
|
|
|
|
return cb();
|
2015-01-21 13:55:10 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/', function(req, res, next) {
|
|
|
|
|
return next(new errors.InternalServerError('bah!'));
|
2015-01-21 13:55:10 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2015-01-21 13:55:10 -08:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
2015-02-17 23:24:47 -06:00
|
|
|
t.expect(7);
|
2015-01-21 13:55:10 -08:00
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2015-02-17 23:24:47 -06:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('error handler defers "after" event', function(t) {
|
2015-02-17 23:24:47 -06:00
|
|
|
t.expect(9);
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('NotFound', function(req, res, err, cb) {
|
2015-02-17 23:24:47 -06:00
|
|
|
t.ok(req);
|
|
|
|
|
t.ok(res);
|
|
|
|
|
t.ok(cb);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.equal(typeof cb, 'function');
|
2015-02-17 23:24:47 -06:00
|
|
|
t.ok(err);
|
|
|
|
|
|
|
|
|
|
SERVER.removeAllListeners('after');
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('after', function(req2, res2) {
|
2015-02-17 23:24:47 -06:00
|
|
|
t.ok(req2);
|
|
|
|
|
t.ok(res2);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
return cb();
|
2015-02-17 23:24:47 -06:00
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('after', function() {
|
2015-02-17 23:24:47 -06:00
|
|
|
// do not fire prematurely
|
|
|
|
|
t.notOk(true);
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/' + uuid.v4(), function(err, _, res) {
|
2015-02-17 23:24:47 -06:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 404);
|
2015-02-25 13:33:50 -08:00
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
// eslint-disable-next-line
|
|
|
|
|
test('gh-757 req.absoluteUri() defaults path segment to req.path()', function(t) {
|
|
|
|
|
SERVER.get('/the-original-path', function(req, res, next) {
|
|
|
|
|
var prefix = 'http://127.0.0.1:' + PORT;
|
|
|
|
|
t.equal(
|
|
|
|
|
req.absoluteUri('?key=value'),
|
|
|
|
|
prefix + '/the-original-path/?key=value'
|
|
|
|
|
);
|
|
|
|
|
t.equal(
|
|
|
|
|
req.absoluteUri('#fragment'),
|
|
|
|
|
prefix + '/the-original-path/#fragment'
|
|
|
|
|
);
|
|
|
|
|
t.equal(
|
|
|
|
|
req.absoluteUri('?key=value#fragment'),
|
|
|
|
|
prefix + '/the-original-path/?key=value#fragment'
|
|
|
|
|
);
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
2015-02-25 15:19:31 -08:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
CLIENT.get('/the-original-path', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2015-02-25 15:19:31 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-693 sending multiple response header values', function(t) {
|
|
|
|
|
SERVER.get('/', function(req, res, next) {
|
2015-02-25 15:19:31 -08:00
|
|
|
res.link('/', 'self');
|
|
|
|
|
res.link('/foo', 'foo');
|
|
|
|
|
res.link('/bar', 'bar');
|
|
|
|
|
res.send(200, 'root');
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function(err, _, res) {
|
2015-02-25 15:19:31 -08:00
|
|
|
t.equal(res.statusCode, 200);
|
2015-02-25 21:43:39 -07:00
|
|
|
t.equal(res.headers.link.split(',').length, 3);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-762 res.noCache()', function(t) {
|
|
|
|
|
SERVER.get('/some-path', function(req, res, next) {
|
2015-02-25 21:43:39 -07:00
|
|
|
res.noCache();
|
|
|
|
|
res.send('data');
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/some-path', function(err, _, res) {
|
|
|
|
|
t.equal(
|
|
|
|
|
res.headers['cache-control'],
|
|
|
|
|
'no-cache, no-store, must-revalidate'
|
|
|
|
|
);
|
2015-02-25 21:43:39 -07:00
|
|
|
t.equal(res.headers.pragma, 'no-cache');
|
|
|
|
|
t.equal(res.headers.expires, '0');
|
2015-02-25 15:19:31 -08:00
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2015-03-17 10:26:35 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('gh-779 set-cookie fields should never have commas', function(t) {
|
|
|
|
|
SERVER.get('/set-cookie', function(req, res, next) {
|
2015-03-17 10:26:35 -07:00
|
|
|
res.header('set-cookie', 'foo');
|
|
|
|
|
res.header('set-cookie', 'bar');
|
|
|
|
|
res.send(200);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/set-cookie', function(err, _, res) {
|
2015-03-17 10:26:35 -07:00
|
|
|
t.ifError(err);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.equal(
|
2018-02-08 17:18:35 -08:00
|
|
|
res.rawHeaders.filter(function(keyOrValue) {
|
|
|
|
|
return keyOrValue === 'set-cookie';
|
|
|
|
|
}).length,
|
|
|
|
|
2,
|
|
|
|
|
'multiple set-cookie headers should not be merged'
|
2017-10-31 19:29:49 +01:00
|
|
|
);
|
2018-02-08 17:18:35 -08:00
|
|
|
t.equal(res.headers['set-cookie'][0], 'foo');
|
|
|
|
|
t.equal(res.headers['set-cookie'][1], 'bar');
|
2015-03-17 10:26:35 -07:00
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2015-06-19 23:03:20 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test(
|
|
|
|
|
'gh-986 content-type fields should never have commas' +
|
|
|
|
|
' (via `res.header(...)`)',
|
|
|
|
|
function(t) {
|
|
|
|
|
SERVER.get('/content-type', function(req, res, next) {
|
|
|
|
|
res.header('content-type', 'foo');
|
|
|
|
|
res.header('content-type', 'bar');
|
|
|
|
|
res.send(200);
|
|
|
|
|
});
|
2015-06-19 23:03:20 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/content-type', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(
|
|
|
|
|
Array.isArray(res.headers['content-type']),
|
|
|
|
|
false,
|
|
|
|
|
'content-type header should not be an array'
|
|
|
|
|
);
|
|
|
|
|
t.equal(res.headers['content-type'], 'bar');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
test(
|
|
|
|
|
'gh-986 content-type fields should never have commas' +
|
|
|
|
|
' (via `res.setHeader(...)`)',
|
|
|
|
|
function(t) {
|
|
|
|
|
SERVER.get('/content-type', function(req, res, next) {
|
|
|
|
|
res.setHeader('content-type', 'foo');
|
|
|
|
|
res.setHeader('content-type', 'bar');
|
|
|
|
|
res.send(200);
|
|
|
|
|
});
|
2016-01-04 08:57:43 -05:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/content-type', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(
|
|
|
|
|
Array.isArray(res.headers['content-type']),
|
|
|
|
|
false,
|
|
|
|
|
'content-type header should not be an array'
|
|
|
|
|
);
|
|
|
|
|
t.equal(res.headers['content-type'], 'bar');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
2016-01-04 08:57:43 -05:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-877 content-type should be case insensitive', function(t) {
|
|
|
|
|
SERVER.use(restify.plugins.bodyParser({ maxBodySize: 1024 }));
|
2015-08-13 17:49:40 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/cl', function(req, res, next) {
|
2015-08-13 17:49:40 -07:00
|
|
|
t.equal(req.getContentType(), 'application/json');
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var opts = {
|
|
|
|
|
hostname: '127.0.0.1',
|
|
|
|
|
port: PORT,
|
|
|
|
|
path: '/cl',
|
|
|
|
|
method: 'GET',
|
|
|
|
|
agent: false,
|
|
|
|
|
headers: {
|
|
|
|
|
accept: 'application/json',
|
|
|
|
|
'content-type': 'APPLicatioN/JSon',
|
|
|
|
|
'transfer-encoding': 'chunked'
|
|
|
|
|
}
|
|
|
|
|
};
|
2017-10-31 19:29:49 +01:00
|
|
|
var client = http.request(opts, function(res) {
|
2015-08-13 17:49:40 -07:00
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
client.end();
|
|
|
|
|
});
|
2015-08-24 22:22:27 -04:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-882: route name is same as specified', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'my-r$-%-x',
|
|
|
|
|
path: '/m1'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
res.send({ name: req.route.name });
|
|
|
|
|
}
|
|
|
|
|
);
|
2015-09-08 00:37:58 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/m1', function(err, _, res) {
|
2015-08-24 22:22:27 -04:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.body, '{"name":"my-r$-%-x"}');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2015-09-08 00:37:58 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test(
|
|
|
|
|
'GH-733 if request closed early, stop processing. ensure only ' +
|
|
|
|
|
'relevant audit logs output.',
|
|
|
|
|
function(t) {
|
|
|
|
|
// Dirty hack to capture the log record using a ring buffer.
|
|
|
|
|
var numCount = 0;
|
2015-09-08 00:37:58 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
// FAST_CLIENT times out at 500ms, should capture two records then close
|
|
|
|
|
// the request.
|
|
|
|
|
SERVER.get('/audit', [
|
|
|
|
|
function first(req, res, next) {
|
|
|
|
|
req.startHandlerTimer('first');
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
numCount++;
|
|
|
|
|
req.endHandlerTimer('first');
|
|
|
|
|
return next();
|
|
|
|
|
}, 300);
|
|
|
|
|
},
|
|
|
|
|
function second(req, res, next) {
|
|
|
|
|
req.startHandlerTimer('second');
|
2018-02-23 11:20:44 -08:00
|
|
|
numCount++;
|
|
|
|
|
req.endHandlerTimer('second');
|
2017-10-31 19:29:49 +01:00
|
|
|
setTimeout(function() {
|
|
|
|
|
return next();
|
|
|
|
|
}, 300);
|
|
|
|
|
},
|
|
|
|
|
function third(req, res, next) {
|
|
|
|
|
req.endHandlerTimer('third');
|
2015-09-14 16:06:35 -07:00
|
|
|
numCount++;
|
2017-10-31 19:29:49 +01:00
|
|
|
res.send({ hello: 'world' });
|
2015-09-14 16:06:35 -07:00
|
|
|
return next();
|
2017-10-31 19:29:49 +01:00
|
|
|
}
|
|
|
|
|
]);
|
2015-09-14 16:06:35 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
// set up audit logs
|
|
|
|
|
var ringbuffer = new bunyan.RingBuffer({ limit: 1 });
|
|
|
|
|
SERVER.on(
|
|
|
|
|
'after',
|
|
|
|
|
restify.plugins.auditLogger({
|
|
|
|
|
log: bunyan.createLogger({
|
|
|
|
|
name: 'audit',
|
|
|
|
|
streams: [
|
|
|
|
|
{
|
|
|
|
|
level: 'info',
|
|
|
|
|
type: 'raw',
|
|
|
|
|
stream: ringbuffer
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}),
|
|
|
|
|
event: 'after'
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
SERVER.on('after', function(req, res, route, err) {
|
|
|
|
|
if (req.href() === '/audit?v=2') {
|
|
|
|
|
// should request timeout error
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.name, 'RequestCloseError');
|
|
|
|
|
|
|
|
|
|
// check records
|
|
|
|
|
t.ok(ringbuffer.records[0], 'no log records');
|
|
|
|
|
t.equal(
|
|
|
|
|
ringbuffer.records.length,
|
|
|
|
|
1,
|
|
|
|
|
'should only have 1 log record'
|
|
|
|
|
);
|
|
|
|
|
// TODO: fix this after plugin is fixed to use
|
|
|
|
|
// req.connectionState()
|
|
|
|
|
// t.equal(ringbuffer.records[0].req.clientClosed, true);
|
|
|
|
|
|
|
|
|
|
// check timers
|
|
|
|
|
var handlers = Object.keys(ringbuffer.records[0].req.timers);
|
|
|
|
|
t.equal(handlers.length, 2, 'should only have 2 req timers');
|
|
|
|
|
t.equal(
|
|
|
|
|
handlers[0],
|
|
|
|
|
'first',
|
|
|
|
|
'first handler timer not in order'
|
|
|
|
|
);
|
|
|
|
|
t.equal(
|
|
|
|
|
handlers[handlers.length - 1],
|
|
|
|
|
'second',
|
|
|
|
|
'second handler not last'
|
|
|
|
|
);
|
|
|
|
|
t.end();
|
|
|
|
|
|
|
|
|
|
// ensure third handler never ran
|
|
|
|
|
t.equal(numCount, 2);
|
|
|
|
|
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/audit?v=1', function(err, req, res, data) {
|
2017-10-31 19:29:49 +01:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.deepEqual(data, { hello: 'world' });
|
|
|
|
|
t.equal(numCount, 3);
|
|
|
|
|
|
|
|
|
|
// reset numCount
|
|
|
|
|
numCount = 0;
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
FAST_CLIENT.get('/audit?v=2', function(err2, req2, res2, data2) {
|
|
|
|
|
t.ok(err2);
|
|
|
|
|
t.equal(err2.name, 'RequestTimeoutError');
|
2017-10-31 19:29:49 +01:00
|
|
|
});
|
2015-09-08 00:37:58 -07:00
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
}
|
|
|
|
|
);
|
2015-09-08 01:21:04 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-667 emit error event for generic Errors', function(t) {
|
2015-09-08 01:21:04 -07:00
|
|
|
var restifyErrorFired = 0;
|
|
|
|
|
var notFoundFired = 0;
|
|
|
|
|
var myErr = new errors.NotFoundError('foobar');
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/1', function(req, res, next) {
|
2015-09-08 01:21:04 -07:00
|
|
|
return next(new Error('foobar'));
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/2', function(req, res, next) {
|
2015-09-08 01:21:04 -07:00
|
|
|
return next(myErr);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/3', function(req, res, next) {
|
|
|
|
|
SERVER.on('NotFound', function(req2, res2, err, cb) {
|
2015-09-08 01:21:04 -07:00
|
|
|
notFoundFired++;
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err, myErr);
|
|
|
|
|
t.end();
|
|
|
|
|
return cb();
|
|
|
|
|
});
|
|
|
|
|
return next(myErr);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.on('restifyError', function(req, res, err, cb) {
|
2015-09-08 01:21:04 -07:00
|
|
|
restifyErrorFired++;
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err instanceof Error, true);
|
|
|
|
|
|
|
|
|
|
if (err instanceof errors.NotFoundError) {
|
|
|
|
|
t.equal(err, myErr);
|
|
|
|
|
}
|
|
|
|
|
return cb();
|
|
|
|
|
});
|
|
|
|
|
|
2016-05-12 09:49:53 -07:00
|
|
|
/*eslint-disable no-shadow*/
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/1', function(err, req, res, data) {
|
2015-09-08 01:21:04 -07:00
|
|
|
// should get regular error
|
2016-05-13 15:49:40 -07:00
|
|
|
// fail here. But why?
|
2015-09-08 01:21:04 -07:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(restifyErrorFired, 1);
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/2', function(err, req, res, data) {
|
2015-09-08 01:21:04 -07:00
|
|
|
// should get not found error
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(restifyErrorFired, 2);
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/3', function(err, req, res, data) {
|
2015-09-08 01:21:04 -07:00
|
|
|
// should get notfounderror
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(restifyErrorFired, 3);
|
|
|
|
|
t.equal(notFoundFired, 1);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
2016-05-12 09:49:53 -07:00
|
|
|
/*eslint-enable no-shadow*/
|
2015-09-08 01:21:04 -07:00
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
// eslint-disable-next-line
|
|
|
|
|
test('GH-667 returning error in error handler should not do anything', function(t) {
|
|
|
|
|
SERVER.on('ImATeapot', function(req, res, err, cb) {
|
|
|
|
|
// attempt to pass a new error back
|
|
|
|
|
return cb(new errors.LockedError('oh noes'));
|
|
|
|
|
});
|
2015-09-08 01:21:04 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.get('/1', function(req, res, next) {
|
|
|
|
|
return next(new errors.ImATeapotError('foobar'));
|
|
|
|
|
});
|
2016-03-18 13:38:09 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
CLIENT.get('/1', function(err, req, res, data) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
// should still get the original error
|
|
|
|
|
t.equal(err.name, 'ImATeapotError');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2016-03-18 13:38:09 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-958 RCS does not write triggering record', function(t) {
|
2016-05-12 09:49:53 -07:00
|
|
|
var passThrough = new stream.PassThrough();
|
|
|
|
|
var count = 1;
|
|
|
|
|
// we would expect to get 3 logging statements
|
2017-10-31 19:29:49 +01:00
|
|
|
passThrough.on('data', function(chunk) {
|
2016-05-12 09:49:53 -07:00
|
|
|
var obj = JSON.parse(chunk.toString());
|
|
|
|
|
t.equal(obj.msg, count.toString());
|
|
|
|
|
|
|
|
|
|
if (count === 3) {
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
count++;
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.log = helper.getLog('server', [
|
|
|
|
|
{
|
2016-05-12 09:49:53 -07:00
|
|
|
level: bunyan.DEBUG,
|
|
|
|
|
type: 'raw',
|
|
|
|
|
stream: new restify.bunyan.RequestCaptureStream({
|
|
|
|
|
level: bunyan.WARN,
|
|
|
|
|
stream: passThrough
|
2017-10-31 19:29:49 +01:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
]);
|
2016-05-12 09:49:53 -07:00
|
|
|
|
2017-05-12 17:48:56 -07:00
|
|
|
SERVER.use(restify.plugins.requestLogger());
|
2016-05-12 09:49:53 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/rcs', function(req, res, next) {
|
2016-05-12 09:49:53 -07:00
|
|
|
req.log.debug('1');
|
|
|
|
|
req.log.info('2');
|
|
|
|
|
req.log.error('3');
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/rcs', function(err, _, res) {
|
2016-05-12 09:49:53 -07:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-1024 disable uncaughtException handler', function(t) {
|
2016-03-18 13:38:09 -07:00
|
|
|
// With uncaughtException handling disabled, the node process will abort,
|
|
|
|
|
// so testing of this feature must occur in a separate node process.
|
|
|
|
|
|
|
|
|
|
var allStderr = '';
|
|
|
|
|
var serverPath = __dirname + '/lib/server-withDisableUncaughtException.js';
|
2017-10-31 19:29:49 +01:00
|
|
|
var serverProc = childprocess.fork(serverPath, { silent: true });
|
2016-03-18 13:38:09 -07:00
|
|
|
|
|
|
|
|
// Record stderr, to check for the correct exception stack.
|
2017-10-31 19:29:49 +01:00
|
|
|
serverProc.stderr.on('data', function(data) {
|
2016-03-18 13:38:09 -07:00
|
|
|
allStderr += String(data);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Handle serverPortResponse and then make the client request - the request
|
|
|
|
|
// should receive a connection closed error (because the server aborts).
|
2017-10-31 19:29:49 +01:00
|
|
|
serverProc.on('message', function(msg) {
|
2016-03-18 13:38:09 -07:00
|
|
|
if (msg.task !== 'serverPortResponse') {
|
|
|
|
|
serverProc.kill();
|
|
|
|
|
t.end();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var port = msg.port;
|
|
|
|
|
var client = restifyClients.createJsonClient({
|
|
|
|
|
url: 'http://127.0.0.1:' + port,
|
|
|
|
|
dtrace: helper.dtrace,
|
|
|
|
|
retry: false
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
client.get('/', function(err, _, res) {
|
2016-03-18 13:38:09 -07:00
|
|
|
// Should get a connection closed error, but no response object.
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.code, 'ECONNRESET');
|
|
|
|
|
t.equal(res, undefined);
|
|
|
|
|
|
|
|
|
|
serverProc.kill(); // Ensure it's dead.
|
|
|
|
|
|
|
|
|
|
t.ok(allStderr.indexOf('Error: Catch me!') > 0);
|
|
|
|
|
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
serverProc.send({ task: 'serverPortRequest' });
|
2016-03-18 13:38:09 -07:00
|
|
|
});
|
2016-05-04 18:21:36 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-999 Custom 404 handler does not send response', function(t) {
|
2016-05-04 18:21:36 -07:00
|
|
|
// make the 404 handler act like other error handlers - must modify
|
|
|
|
|
// err.body to send a custom response.
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.on('NotFound', function(req, res, err, cb) {
|
2016-05-04 18:21:36 -07:00
|
|
|
err.body = {
|
|
|
|
|
message: 'my custom not found'
|
|
|
|
|
};
|
|
|
|
|
return cb();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/notfound', function(err, _, res) {
|
2016-05-04 18:21:36 -07:00
|
|
|
t.ok(err);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.deepEqual(
|
|
|
|
|
res.body,
|
|
|
|
|
JSON.stringify({
|
|
|
|
|
message: 'my custom not found'
|
|
|
|
|
})
|
|
|
|
|
);
|
2016-05-04 18:21:36 -07:00
|
|
|
t.end();
|
|
|
|
|
});
|
2016-05-13 15:49:40 -07:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('calling next(false) should early exit from pre handlers', function(t) {
|
2016-05-13 16:24:51 -07:00
|
|
|
var afterFired = false;
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.pre(function(req, res, next) {
|
2016-05-13 16:24:51 -07:00
|
|
|
res.send('early exit');
|
|
|
|
|
return next(false);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/1', function(req, res, next) {
|
2016-05-13 16:24:51 -07:00
|
|
|
res.send('hello world');
|
|
|
|
|
return next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.on('after', function() {
|
2016-05-13 16:24:51 -07:00
|
|
|
afterFired = true;
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/1', function(err, req, res, data) {
|
2016-05-13 16:24:51 -07:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(data, 'early exit');
|
|
|
|
|
// ensure after event fired
|
|
|
|
|
t.ok(afterFired);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2016-05-23 17:13:29 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
test('calling next(false) should early exit from use handlers', function(t) {
|
|
|
|
|
var steps = 0;
|
|
|
|
|
|
|
|
|
|
SERVER.use(function(req, res, next) {
|
|
|
|
|
res.send('early exit');
|
|
|
|
|
return next(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.get('/1', function(req, res, next) {
|
|
|
|
|
res.send('hello world');
|
|
|
|
|
return next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.on('after', function() {
|
|
|
|
|
steps++;
|
|
|
|
|
t.equal(steps, 2);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/1', function(err, req, res, data) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(data, 'early exit');
|
|
|
|
|
steps++;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('calling next(err) from pre should still emit after event', function(t) {
|
|
|
|
|
setTimeout(function() {
|
2017-09-19 09:58:41 -07:00
|
|
|
t.fail('Timed out');
|
|
|
|
|
t.end();
|
|
|
|
|
}, 2000);
|
|
|
|
|
var error = new Error();
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.pre(function(req, res, next) {
|
2017-09-19 09:58:41 -07:00
|
|
|
next(error);
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/', function(req, res, next) {
|
2017-09-19 09:58:41 -07:00
|
|
|
t.fail('should have aborted stack before routing');
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.on('after', function(req, res, route, err) {
|
2017-09-19 09:58:41 -07:00
|
|
|
t.equal(err, error);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/', function() {});
|
2017-09-19 09:58:41 -07:00
|
|
|
});
|
2016-05-23 17:13:29 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-1078: server name should default to restify', function(t) {
|
2016-06-02 15:18:20 -07:00
|
|
|
var myServer = restify.createServer();
|
|
|
|
|
var port = 3000;
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
myServer.get('/', function(req, res, next) {
|
2016-06-02 15:18:20 -07:00
|
|
|
res.send('hi');
|
|
|
|
|
return next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var myClient = restifyClients.createStringClient({
|
|
|
|
|
url: 'http://127.0.0.1:' + port,
|
|
|
|
|
headers: {
|
|
|
|
|
connection: 'close'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
myServer.listen(port, function() {
|
|
|
|
|
myClient.get('/', function(err, req, res, data) {
|
2016-06-02 15:18:20 -07:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.headers.server, 'restify');
|
|
|
|
|
myServer.close(t.end);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('GH-1078: server name should be customizable', function(t) {
|
2016-06-02 15:18:20 -07:00
|
|
|
var myServer = restify.createServer({
|
|
|
|
|
name: 'foo'
|
|
|
|
|
});
|
|
|
|
|
var port = 3000;
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
myServer.get('/', function(req, res, next) {
|
2016-06-02 15:18:20 -07:00
|
|
|
res.send('hi');
|
|
|
|
|
return next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var myClient = restifyClients.createStringClient({
|
|
|
|
|
url: 'http://127.0.0.1:' + port,
|
|
|
|
|
headers: {
|
|
|
|
|
connection: 'close'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
myServer.listen(port, function() {
|
|
|
|
|
myClient.get('/', function(err, req, res, data) {
|
2016-06-02 15:18:20 -07:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.headers.server, 'foo');
|
|
|
|
|
myServer.close(t.end);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
// eslint-disable-next-line
|
|
|
|
|
test('GH-1078: server name should be overridable and not sent down', function(t) {
|
|
|
|
|
var myServer = restify.createServer({
|
|
|
|
|
name: ''
|
|
|
|
|
});
|
|
|
|
|
var port = 3000;
|
2016-06-02 15:18:20 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
myServer.get('/', function(req, res, next) {
|
|
|
|
|
res.send('hi');
|
|
|
|
|
return next();
|
|
|
|
|
});
|
2016-06-02 15:18:20 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
var myClient = restifyClients.createStringClient({
|
|
|
|
|
url: 'http://127.0.0.1:' + port,
|
|
|
|
|
headers: {
|
|
|
|
|
connection: 'close'
|
|
|
|
|
}
|
|
|
|
|
});
|
2016-06-02 15:18:20 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
myServer.listen(port, function() {
|
|
|
|
|
myClient.get('/', function(err, req, res, data) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.headers.hasOwnProperty('server'), false);
|
|
|
|
|
myServer.close(t.end);
|
2016-06-02 15:18:20 -07:00
|
|
|
});
|
2018-02-23 11:20:44 -08:00
|
|
|
});
|
|
|
|
|
});
|
2016-12-14 15:50:02 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test("should emit 'after' on successful request", function(t) {
|
|
|
|
|
SERVER.on('after', function(req, res, route, err) {
|
2016-12-14 15:50:02 -08:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/foobar', function(req, res, next) {
|
2016-12-14 15:50:02 -08:00
|
|
|
res.send('hello world');
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foobar', function(err, _, res) {
|
2016-12-14 15:50:02 -08:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-06-07 13:39:27 -07:00
|
|
|
test("should emit 'after' on successful request with work", function(t) {
|
|
|
|
|
SERVER.on('after', function(req, res, route, err) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SERVER.get('/foobar', function(req, res, next) {
|
|
|
|
|
// with timeouts we are testing that request lifecycle
|
|
|
|
|
// events are firing in the correct order
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
res.send('hello world');
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
next();
|
|
|
|
|
}, 500);
|
|
|
|
|
}, 500);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foobar', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test("should emit 'after' on errored request", function(t) {
|
|
|
|
|
SERVER.on('after', function(req, res, route, err) {
|
2016-12-14 15:50:02 -08:00
|
|
|
t.ok(err);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/foobar', function(req, res, next) {
|
2016-12-14 15:50:02 -08:00
|
|
|
next(new Error('oh noes'));
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foobar', function(err, _, res) {
|
2016-12-14 15:50:02 -08:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test("should emit 'after' on uncaughtException", function(t) {
|
|
|
|
|
SERVER.on('after', function(req, res, route, err) {
|
2016-12-14 15:50:02 -08:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.message, 'oh noes');
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/foobar', function(req, res, next) {
|
2016-12-14 15:50:02 -08:00
|
|
|
throw new Error('oh noes');
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foobar', function(err, _, res) {
|
2016-12-14 15:50:02 -08:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.name, 'InternalError');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test("should emit 'after' when sending res on uncaughtException", function(t) {
|
|
|
|
|
SERVER.on('after', function(req, res, route, err) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.message, 'oh noes');
|
2016-12-14 15:50:02 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.on('uncaughtException', function(req, res, route, err) {
|
|
|
|
|
res.send(504, 'boom');
|
2016-12-14 15:50:02 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/foobar', function(req, res, next) {
|
|
|
|
|
throw new Error('oh noes');
|
2016-12-14 15:50:02 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foobar', function(err, _, res) {
|
2016-12-14 15:50:02 -08:00
|
|
|
t.ok(err);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.equal(err.name, 'GatewayTimeoutError');
|
|
|
|
|
t.end();
|
2016-12-14 15:50:02 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test(
|
|
|
|
|
"should emit 'after' on client closed request " +
|
|
|
|
|
"(req.connectionState(): 'close')",
|
|
|
|
|
function(t) {
|
|
|
|
|
SERVER.on('after', function(req, res, route, err) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(req.connectionState(), 'close');
|
2018-06-07 13:39:27 -07:00
|
|
|
t.equal(res.statusCode, 444);
|
2017-10-31 19:29:49 +01:00
|
|
|
t.equal(err.name, 'RequestCloseError');
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
2016-12-14 15:50:02 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/foobar', function(req, res, next) {
|
|
|
|
|
// fast client times out at 500ms, wait for 800ms which should cause
|
|
|
|
|
// client to timeout
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
return next();
|
|
|
|
|
}, 800);
|
|
|
|
|
});
|
2016-12-14 15:50:02 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
FAST_CLIENT.get('/foobar', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.name, 'RequestTimeoutError');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
2016-12-14 15:50:02 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('should increment/decrement inflight request count', function(t) {
|
|
|
|
|
SERVER.get('/foo', function(req, res, next) {
|
2017-02-24 09:59:06 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 1);
|
2016-12-15 14:39:00 -08:00
|
|
|
res.send();
|
|
|
|
|
return next();
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.on('after', function() {
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 0);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
2016-12-15 14:39:00 -08:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2018-02-23 11:20:44 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 1);
|
2016-12-15 14:39:00 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
// eslint-disable-next-line
|
|
|
|
|
test('should increment/decrement inflight request count for concurrent reqs', function(t) {
|
|
|
|
|
SERVER.get('/foo1', function(req, res, next) {
|
|
|
|
|
// other request is already sent
|
|
|
|
|
t.equal(SERVER.inflightRequests() >= 1, true);
|
|
|
|
|
setTimeout(function() {
|
2016-12-15 14:39:00 -08:00
|
|
|
res.send();
|
|
|
|
|
return next();
|
2018-02-23 11:20:44 -08:00
|
|
|
}, 250);
|
|
|
|
|
});
|
2016-12-15 14:39:00 -08:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.get('/foo2', function(req, res, next) {
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 2);
|
|
|
|
|
res.send();
|
|
|
|
|
return next();
|
|
|
|
|
});
|
2016-12-15 14:39:00 -08:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
CLIENT.get('/foo1', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 1);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo2', function(err, _, res) {
|
|
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 2);
|
|
|
|
|
});
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
|
|
|
|
|
test("should emit 'close' on server close", function(t) {
|
2017-01-17 19:40:03 +01:00
|
|
|
var server = restify.createServer();
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
server.listen(PORT + 1, '127.0.0.1', function() {
|
|
|
|
|
server.on('close', function() {
|
2017-01-17 19:40:03 +01:00
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
server.close();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('should cleanup inflight requests count for 404s', function(t) {
|
|
|
|
|
SERVER.get('/foo1', function(req, res, next) {
|
2017-02-24 09:59:06 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 1);
|
2016-12-15 14:39:00 -08:00
|
|
|
res.send();
|
|
|
|
|
return next();
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.on('after', function(req) {
|
|
|
|
|
if (req.path() === '/doesnotexist') {
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 0);
|
|
|
|
|
t.end();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo1', function(err, _, res) {
|
2016-12-15 14:39:00 -08:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2018-02-23 11:20:44 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 1);
|
2016-12-15 14:39:00 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/doesnotexist', function(err2, _2, res2) {
|
2016-12-15 14:39:00 -08:00
|
|
|
t.ok(err2);
|
|
|
|
|
t.equal(res2.statusCode, 404);
|
2017-02-24 09:59:06 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 0);
|
2016-12-15 14:39:00 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('should cleanup inflight requests count for timeouts', function(t) {
|
2018-02-23 11:20:44 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 0);
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/foo1', function(req, res, next) {
|
2018-02-23 11:20:44 -08:00
|
|
|
// othr request is already sent
|
|
|
|
|
t.equal(SERVER.inflightRequests() >= 1, true);
|
2017-10-31 19:29:49 +01:00
|
|
|
setTimeout(function() {
|
2016-12-15 14:39:00 -08:00
|
|
|
res.send();
|
|
|
|
|
return next();
|
|
|
|
|
}, 1000);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get('/foo2', function(req, res, next) {
|
2017-02-24 09:59:06 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 2);
|
2016-12-15 14:39:00 -08:00
|
|
|
res.send();
|
|
|
|
|
return next();
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.on('after', function(req) {
|
|
|
|
|
if (req.path() === '/foo1') {
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 0);
|
|
|
|
|
t.end();
|
|
|
|
|
} else if (req.path() === '/foo2') {
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 1);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
FAST_CLIENT.get('/foo1', function(err, _, res) {
|
2016-12-15 14:39:00 -08:00
|
|
|
t.ok(err);
|
2017-02-24 09:59:06 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 1);
|
2016-12-15 14:39:00 -08:00
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo2', function(err, _, res) {
|
2016-12-15 14:39:00 -08:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2018-02-23 11:20:44 -08:00
|
|
|
t.equal(SERVER.inflightRequests(), 2);
|
2016-12-15 14:39:00 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
// eslint-disable-next-line
|
|
|
|
|
test('should cleanup inflight requests count on uncaughtExceptions', function(t) {
|
|
|
|
|
SERVER.on('uncaughtException', function(req, res, route, err) {
|
|
|
|
|
res.send(500, 'asplode');
|
|
|
|
|
});
|
2017-01-10 18:39:58 -08:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.get('/foo1', function(req, res, next) {
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 1);
|
|
|
|
|
throw new Error('oh noes');
|
|
|
|
|
});
|
2017-01-10 18:39:58 -08:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
CLIENT.get('/foo1', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(SERVER.inflightRequests(), 0);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2017-01-10 18:39:58 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('should show debug information', function(t) {
|
|
|
|
|
SERVER.pre(function pre(req, res, next) {
|
2017-02-24 09:59:06 -08:00
|
|
|
return next();
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.pre(function pre2(req, res, next) {
|
2017-02-24 09:59:06 -08:00
|
|
|
return next();
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.use(function use(req, res, next) {
|
2017-02-24 09:59:06 -08:00
|
|
|
return next();
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.use(function use2(req, res, next) {
|
2017-02-24 09:59:06 -08:00
|
|
|
return next();
|
|
|
|
|
});
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.on('after', function aft() {});
|
|
|
|
|
SERVER.on('after', function aft2() {});
|
2017-02-24 09:47:37 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.get(
|
|
|
|
|
'/foo',
|
|
|
|
|
function(req, res, next) {
|
2017-02-24 09:47:37 -08:00
|
|
|
return next();
|
|
|
|
|
},
|
|
|
|
|
function foo(req, res, next) {
|
|
|
|
|
res.end();
|
|
|
|
|
return next();
|
|
|
|
|
}
|
|
|
|
|
);
|
2017-01-10 18:39:58 -08:00
|
|
|
|
|
|
|
|
SERVER.get('/bar/:a/:b', function bar(req, res, next) {
|
|
|
|
|
res.end();
|
|
|
|
|
return next();
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
SERVER.get('/example/:file(^\\d+).png', function freeform(req, res, next) {
|
2017-10-31 19:29:49 +01:00
|
|
|
res.end();
|
|
|
|
|
return next();
|
|
|
|
|
});
|
2017-01-10 18:39:58 -08:00
|
|
|
|
2017-03-03 09:52:57 -08:00
|
|
|
var debugInfo = SERVER.getDebugInfo();
|
2017-01-10 18:39:58 -08:00
|
|
|
|
|
|
|
|
t.ok(debugInfo);
|
|
|
|
|
t.ok(debugInfo.routes);
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
debugInfo.routes.forEach(function(route) {
|
2017-01-10 18:39:58 -08:00
|
|
|
t.ok(route);
|
|
|
|
|
t.equal(typeof route.name, 'string');
|
|
|
|
|
t.equal(typeof route.method, 'string');
|
|
|
|
|
|
|
|
|
|
t.equal(route.handlers instanceof Array, true);
|
2017-10-31 19:29:49 +01:00
|
|
|
route.handlers.forEach(function(handlerFn) {
|
2017-02-24 09:47:37 -08:00
|
|
|
t.equal(typeof handlerFn, 'string');
|
2017-01-10 18:39:58 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
// // check /foo
|
|
|
|
|
// TODO: should it contain use handlers?
|
2017-02-24 09:47:37 -08:00
|
|
|
t.equal(debugInfo.routes[0].handlers[0], 'use');
|
|
|
|
|
t.equal(debugInfo.routes[0].handlers[1], 'use2');
|
|
|
|
|
t.equal(debugInfo.routes[0].handlers[2], 'anonymous');
|
|
|
|
|
t.equal(debugInfo.routes[0].handlers[3], 'foo');
|
|
|
|
|
|
|
|
|
|
// check /bar
|
|
|
|
|
t.equal(debugInfo.routes[0].handlers[0], 'use');
|
|
|
|
|
t.equal(debugInfo.routes[0].handlers[1], 'use2');
|
|
|
|
|
t.equal(debugInfo.routes[1].handlers[2], 'bar');
|
|
|
|
|
|
|
|
|
|
// check use, pre, and after handlers
|
|
|
|
|
t.ok(debugInfo.server.use);
|
|
|
|
|
t.equal(debugInfo.server.use[0], 'use');
|
|
|
|
|
t.equal(debugInfo.server.use[1], 'use2');
|
|
|
|
|
|
|
|
|
|
t.ok(debugInfo.server.pre);
|
|
|
|
|
t.equal(debugInfo.server.pre[0], 'pre');
|
|
|
|
|
t.equal(debugInfo.server.pre[1], 'pre2');
|
|
|
|
|
|
|
|
|
|
t.ok(debugInfo.server.after);
|
|
|
|
|
t.equal(debugInfo.server.after[0], 'aft');
|
|
|
|
|
t.equal(debugInfo.server.after[1], 'aft2');
|
|
|
|
|
|
2017-01-10 18:39:58 -08:00
|
|
|
// detailed test for compiled regex
|
|
|
|
|
// verify url parameter regex
|
2018-02-23 11:20:44 -08:00
|
|
|
t.deepEqual(debugInfo.routes[1].name, 'getbarab');
|
2017-01-10 18:39:58 -08:00
|
|
|
t.deepEqual(debugInfo.routes[1].method, 'get');
|
2018-02-23 11:20:44 -08:00
|
|
|
|
2017-01-10 18:39:58 -08:00
|
|
|
// verify freeform regex
|
2018-02-23 11:20:44 -08:00
|
|
|
t.deepEqual(debugInfo.routes[2].name, 'getexamplefiledpng');
|
2017-01-10 18:39:58 -08:00
|
|
|
t.deepEqual(debugInfo.routes[2].method, 'get');
|
|
|
|
|
|
|
|
|
|
// verify other server details
|
|
|
|
|
t.deepEqual(Object.keys(debugInfo.server.formatters), [
|
|
|
|
|
'application/javascript',
|
|
|
|
|
'application/json',
|
|
|
|
|
'text/plain',
|
|
|
|
|
'application/octet-stream'
|
|
|
|
|
]);
|
|
|
|
|
t.equal(debugInfo.server.address, '127.0.0.1');
|
|
|
|
|
t.equal(typeof debugInfo.server.port, 'number');
|
2017-02-24 09:59:06 -08:00
|
|
|
t.equal(typeof debugInfo.server.inflightRequests, 'number');
|
2017-02-24 09:47:37 -08:00
|
|
|
|
2017-01-10 18:39:58 -08:00
|
|
|
t.end();
|
|
|
|
|
});
|
2017-03-09 14:32:24 -08:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test("should emit 'pre' event on a 200", function(t) {
|
2017-03-09 14:32:24 -08:00
|
|
|
SERVER.get('/foo/:id', function echoId(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
|
|
|
|
t.equal(req.isUpload(), false);
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('pre', function(req, res) {
|
2017-03-09 14:32:24 -08:00
|
|
|
t.ok(req);
|
|
|
|
|
t.ok(res);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/bar', function(err, _, res) {
|
2017-03-09 14:32:24 -08:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2017-03-10 09:56:40 -08:00
|
|
|
t.end();
|
2017-03-09 14:32:24 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test("should emit 'pre' event on 404", function(t) {
|
2017-03-09 14:32:24 -08:00
|
|
|
SERVER.get('/foo/:id', function echoId(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
|
|
|
|
t.equal(req.isUpload(), false);
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('pre', function(req, res) {
|
2017-03-09 14:32:24 -08:00
|
|
|
t.ok(req);
|
|
|
|
|
t.ok(res);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/badroute', function(err, _, res) {
|
2017-03-09 14:32:24 -08:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 404);
|
2017-03-10 09:56:40 -08:00
|
|
|
t.end();
|
2017-03-09 14:32:24 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test("should emit 'routed' event on a 200", function(t) {
|
2017-03-09 14:32:24 -08:00
|
|
|
SERVER.get('/foo/:id', function echoId(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
|
|
|
|
t.equal(req.isUpload(), false);
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('routed', function(req, res, route) {
|
2017-03-09 14:32:24 -08:00
|
|
|
t.ok(req);
|
|
|
|
|
t.ok(res);
|
|
|
|
|
t.ok(route);
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/foo/bar', function(err, _, res) {
|
2017-03-09 14:32:24 -08:00
|
|
|
t.ifError(err);
|
|
|
|
|
t.equal(res.statusCode, 200);
|
2017-03-10 09:56:40 -08:00
|
|
|
t.end();
|
2017-03-09 14:32:24 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test("should not emit 'routed' event on 404", function(t) {
|
2017-03-09 14:32:24 -08:00
|
|
|
SERVER.get('/foo/:id', function echoId(req, res, next) {
|
|
|
|
|
t.ok(req.params);
|
|
|
|
|
t.equal(req.params.id, 'bar');
|
|
|
|
|
t.equal(req.isUpload(), false);
|
|
|
|
|
res.send();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('routed', function(req, res, route) {
|
2017-03-09 14:32:24 -08:00
|
|
|
t.fail();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/badroute', function(err, _, res) {
|
2017-03-09 14:32:24 -08:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 404);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2017-08-15 20:34:55 -07:00
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
test('should emit restifyError even for router errors', function(t) {
|
2017-08-15 20:34:55 -07:00
|
|
|
var notFoundFired = false;
|
|
|
|
|
var restifyErrFired = false;
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('NotFound', function(req, res, err, cb) {
|
2017-08-15 20:34:55 -07:00
|
|
|
notFoundFired = true;
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err instanceof Error, true);
|
|
|
|
|
t.equal(err.name, 'ResourceNotFoundError');
|
|
|
|
|
return cb();
|
|
|
|
|
});
|
|
|
|
|
|
2017-10-31 19:29:49 +01:00
|
|
|
SERVER.once('restifyError', function(req, res, err, cb) {
|
2017-08-15 20:34:55 -07:00
|
|
|
restifyErrFired = true;
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err instanceof Error, true);
|
|
|
|
|
t.equal(err.name, 'ResourceNotFoundError');
|
|
|
|
|
return cb();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/*eslint-disable no-shadow*/
|
2017-10-31 19:29:49 +01:00
|
|
|
CLIENT.get('/dne', function(err, req, res, data) {
|
2017-08-15 20:34:55 -07:00
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.name, 'ResourceNotFoundError');
|
|
|
|
|
t.equal(notFoundFired, true);
|
|
|
|
|
t.equal(restifyErrFired, true);
|
|
|
|
|
t.done();
|
|
|
|
|
});
|
|
|
|
|
});
|
2017-09-06 12:10:06 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
test('should emit error with multiple next calls with strictNext', function(t) {
|
|
|
|
|
var server = restify.createServer({
|
|
|
|
|
dtrace: helper.dtrace,
|
|
|
|
|
strictNext: true,
|
|
|
|
|
handleUncaughtExceptions: true,
|
|
|
|
|
log: helper.getLog('server')
|
2017-09-06 12:10:06 -07:00
|
|
|
});
|
2018-02-23 11:20:44 -08:00
|
|
|
var client;
|
|
|
|
|
var port;
|
2017-09-06 12:10:06 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
server.listen(PORT + 1, '127.0.0.1', function() {
|
|
|
|
|
port = server.address().port;
|
|
|
|
|
client = restifyClients.createJsonClient({
|
|
|
|
|
url: 'http://127.0.0.1:' + port,
|
|
|
|
|
dtrace: helper.dtrace,
|
|
|
|
|
retry: false
|
|
|
|
|
});
|
2017-09-06 12:10:06 -07:00
|
|
|
|
2018-02-23 11:20:44 -08:00
|
|
|
server.get('/strict-next', function(req, res, next) {
|
|
|
|
|
next();
|
|
|
|
|
next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
server.on('uncaughtException', function(req, res, route, err) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(err.message, "next shouldn't be called more than once");
|
|
|
|
|
res.send(err);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
client.get('/strict-next', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
|
|
|
|
|
client.close();
|
|
|
|
|
server.close(function() {
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
2017-09-06 12:10:06 -07:00
|
|
|
});
|
|
|
|
|
});
|
2018-05-24 12:40:16 +05:30
|
|
|
|
2018-11-16 15:40:48 -08:00
|
|
|
test('uncaughtException should not trigger named routeHandler', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
throw 'bar'; //eslint-disable-line no-throw-literal
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
// This code should not run, but we can test against the status code
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('uncaughtException should handle thrown undefined literal', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
throw undefined; //eslint-disable-line no-throw-literal
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
// This code should not run, but we can test against the status code
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('uncaughtException should handle thrown Number', function(t) {
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'foo',
|
|
|
|
|
path: '/foo'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
throw 1; //eslint-disable-line no-throw-literal
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
SERVER.get(
|
|
|
|
|
{
|
|
|
|
|
name: 'bar',
|
|
|
|
|
path: '/bar'
|
|
|
|
|
},
|
|
|
|
|
function(req, res, next) {
|
|
|
|
|
// This code should not run, but we can test against the status code
|
|
|
|
|
res.send(200);
|
|
|
|
|
next();
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
CLIENT.get('/foo', function(err, _, res) {
|
|
|
|
|
t.ok(err);
|
|
|
|
|
t.equal(res.statusCode, 500);
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-05-24 12:40:16 +05:30
|
|
|
test('should have proxy event handlers as instance', function(t) {
|
|
|
|
|
var server = restify.createServer({
|
|
|
|
|
handleUpgrades: false
|
|
|
|
|
});
|
|
|
|
|
t.equal(server.proxyEvents.length, 7);
|
|
|
|
|
|
|
|
|
|
server = restify.createServer({
|
|
|
|
|
handleUpgrades: true
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
t.equal(server.proxyEvents.length, 6);
|
|
|
|
|
server.close(function() {
|
|
|
|
|
t.end();
|
|
|
|
|
});
|
|
|
|
|
});
|