SIGN IN SIGN UP
/*!
* express
* Copyright(c) 2009-2013 TJ Holowaychuk
* Copyright(c) 2013 Roman Shtylman
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
2015-06-18 23:01:18 -04:00
'use strict';
2011-10-07 09:29:36 -07:00
/**
* Module dependencies.
* @private
2011-10-07 09:29:36 -07:00
*/
var finalhandler = require('finalhandler');
2014-03-25 15:23:04 -07:00
var debug = require('debug')('express:application');
var View = require('./view');
var http = require('node:http');
var methods = require('./utils').methods;
2014-05-30 22:17:51 -04:00
var compileETag = require('./utils').compileETag;
var compileQueryParser = require('./utils').compileQueryParser;
2014-05-18 11:17:37 -04:00
var compileTrust = require('./utils').compileTrust;
var resolve = require('node:path').resolve;
2017-02-20 17:36:39 -06:00
var once = require('once')
var Router = require('router');
/**
* Module variables.
* @private
*/
var slice = Array.prototype.slice;
var flatten = Array.prototype.flat;
2011-10-07 09:29:36 -07:00
/**
2011-12-09 14:32:35 -08:00
* Application prototype.
2011-10-07 09:29:36 -07:00
*/
var app = exports = module.exports = {};
/**
* Variable for trust proxy inheritance back-compat
* @private
*/
var trustProxyDefaultSymbol = '@@symbol:trust_proxy_default';
2011-10-07 09:29:36 -07:00
/**
* Initialize the server.
*
2011-10-07 15:10:30 -07:00
* - setup default configuration
* - setup default middleware
* - setup route reflection methods
*
* @private
2011-10-07 09:29:36 -07:00
*/
app.init = function init() {
2014-07-14 00:27:25 -04:00
var router = null;
this.cache = Object.create(null);
this.engines = Object.create(null);
this.settings = Object.create(null);
2011-10-07 15:10:30 -07:00
this.defaultConfiguration();
2014-07-14 00:27:25 -04:00
// Setup getting to lazily add base router
Object.defineProperty(this, 'router', {
configurable: true,
enumerable: true,
get: function getrouter() {
if (router === null) {
router = new Router({
caseSensitive: this.enabled('case sensitive routing'),
strict: this.enabled('strict routing')
});
}
return router;
}
});
2011-10-07 15:10:30 -07:00
};
/**
* Initialize application configuration.
* @private
2011-10-07 15:10:30 -07:00
*/
app.defaultConfiguration = function defaultConfiguration() {
var env = process.env.NODE_ENV || 'development';
2011-10-07 14:04:59 -07:00
// default settings
2012-09-13 09:52:35 -07:00
this.enable('x-powered-by');
this.set('etag', 'weak');
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
this.set('env', env);
this.set('query parser', 'simple')
this.set('subdomain offset', 2);
this.set('trust proxy', false);
2011-10-07 14:04:59 -07:00
// trust proxy inherit back-compat
Object.defineProperty(this.settings, trustProxyDefaultSymbol, {
configurable: true,
value: true
});
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
debug('booting in %s mode', env);
2011-10-07 09:29:36 -07:00
this.on('mount', function onmount(parent) {
// inherit trust proxy
if (this.settings[trustProxyDefaultSymbol] === true
&& typeof parent.settings['trust proxy fn'] === 'function') {
delete this.settings['trust proxy'];
delete this.settings['trust proxy fn'];
}
// inherit protos
Object.setPrototypeOf(this.request, parent.request)
Object.setPrototypeOf(this.response, parent.response)
Object.setPrototypeOf(this.engines, parent.engines)
Object.setPrototypeOf(this.settings, parent.settings)
2012-04-26 03:53:49 -07:00
});
2012-05-03 08:42:18 -07:00
// setup locals
this.locals = Object.create(null);
2012-05-03 08:42:18 -07:00
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
// top-most app is mounted at /
this.mountpath = '/';
2011-10-07 09:29:36 -07:00
// default locals
this.locals.settings = this.settings;
// default configuration
this.set('view', View);
this.set('views', resolve('views'));
2012-07-06 08:53:19 -07:00
this.set('jsonp callback name', 'callback');
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
if (env === 'production') {
2011-10-07 09:29:36 -07:00
this.enable('view cache');
2014-01-19 23:53:48 +08:00
}
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
};
2011-10-07 09:29:36 -07:00
/**
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
* Dispatch a req, res pair into the application. Starts pipeline processing.
*
* If no callback is provided, then default error handlers will respond
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
* in the event of an error bubbling through the stack.
*
* @private
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
*/
app.handle = function handle(req, res, callback) {
// final handler
var done = callback || finalhandler(req, res, {
env: this.get('env'),
onerror: logerror.bind(this)
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
});
2014-07-14 00:06:33 -04:00
// set powered by header
if (this.enabled('x-powered-by')) {
res.setHeader('X-Powered-By', 'Express');
}
// set circular references
req.res = res;
res.req = req;
// alter the prototypes
Object.setPrototypeOf(req, this.request)
Object.setPrototypeOf(res, this.response)
2014-07-14 00:06:33 -04:00
// setup locals
if (!res.locals) {
res.locals = Object.create(null);
}
2014-07-14 00:27:25 -04:00
this.router.handle(req, res, done);
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
};
/**
* Proxy `Router#use()` to add middleware to the app router.
* See Router#use() documentation for details.
*
* If the _fn_ parameter is an express app, then it will be
* mounted at the _route_ specified.
2011-10-07 09:29:36 -07:00
*
* @public
2011-10-07 09:29:36 -07:00
*/
app.use = function use(fn) {
var offset = 0;
var path = '/';
// default path to '/'
// disambiguate app.use([fn])
if (typeof fn !== 'function') {
var arg = fn;
while (Array.isArray(arg) && arg.length !== 0) {
arg = arg[0];
}
// first arg is the path
if (typeof arg !== 'function') {
offset = 1;
path = fn;
}
}
var fns = flatten.call(slice.call(arguments, offset), Infinity);
if (fns.length === 0) {
throw new TypeError('app.use() requires a middleware function')
}
2011-10-07 09:29:36 -07:00
2014-07-14 00:27:25 -04:00
// get router
var router = this.router;
2011-10-07 09:29:36 -07:00
fns.forEach(function (fn) {
// non-express app
if (!fn || !fn.handle || !fn.set) {
return router.use(path, fn);
}
debug('.use app under %s', path);
fn.mountpath = path;
fn.parent = this;
// restore .app property on req and res
router.use(path, function mounted_app(req, res, next) {
2011-10-07 09:29:36 -07:00
var orig = req.app;
fn.handle(req, res, function (err) {
Object.setPrototypeOf(req, orig.request)
Object.setPrototypeOf(res, orig.response)
2011-10-07 09:29:36 -07:00
next(err);
});
});
2011-10-07 09:29:36 -07:00
// mounted an app
fn.emit('mount', this);
}, this);
2011-10-07 09:29:36 -07:00
return this;
};
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
/**
* Proxy to the app `Router#route()`
* Returns a new `Route` instance for the _path_.
*
* Routes are isolated middleware stacks for specific paths.
* See the Route api docs for details.
*
* @public
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
*/
2014-07-14 00:27:25 -04:00
app.route = function route(path) {
return this.router.route(path);
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
};
2011-10-07 09:29:36 -07:00
/**
2011-10-07 13:19:29 -07:00
* Register the given template engine callback `fn`
2012-04-18 17:23:54 -07:00
* as `ext`.
*
* By default will `require()` the engine based on the
* file extension. For example if you try to render
* a "foo.ejs" file Express will invoke the following internally:
2012-04-18 17:23:54 -07:00
*
* app.engine('ejs', require('ejs').__express);
2012-04-18 17:23:54 -07:00
*
* For engines that do not provide `.__express` out of the box,
* or if you wish to "map" a different extension to the template engine
* you may use this method. For example mapping the EJS template engine to
2012-04-25 17:59:02 -07:00
* ".html" files:
2011-10-07 09:29:36 -07:00
*
2012-04-15 21:01:17 -07:00
* app.engine('html', require('ejs').renderFile);
2011-10-07 13:19:29 -07:00
*
2012-04-15 21:01:17 -07:00
* In this case EJS provides a `.renderFile()` method with
2012-04-18 17:23:54 -07:00
* the same signature that Express expects: `(path, options, callback)`,
* though note that it aliases this method as `ejs.__express` internally
2021-04-11 22:28:56 +02:00
* so if you're using ".ejs" extensions you don't need to do anything.
2011-10-07 13:19:29 -07:00
*
2012-04-15 21:01:17 -07:00
* Some template engines do not follow this convention, the
2014-10-23 02:20:51 -04:00
* [Consolidate.js](https://github.com/tj/consolidate.js)
2012-04-15 21:01:17 -07:00
* library was created to map all of node's popular template
* engines to follow this convention, thus allowing them to
2013-02-08 08:42:47 -08:00
* work seamlessly within Express.
2011-10-07 13:19:29 -07:00
*
* @param {String} ext
* @param {Function} fn
* @return {app} for chaining
* @public
2011-10-07 09:29:36 -07:00
*/
app.engine = function engine(ext, fn) {
if (typeof fn !== 'function') {
throw new Error('callback function required');
}
// get file extension
var extension = ext[0] !== '.'
? '.' + ext
: ext;
// store engine
this.engines[extension] = fn;
2011-10-07 09:29:36 -07:00
return this;
};
/**
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
* Proxy to `Router#param()` with one added api feature. The _name_ parameter
* can be an array of names.
*
* See the Router#param() docs for more details.
2011-10-07 09:29:36 -07:00
*
2012-04-15 21:01:17 -07:00
* @param {String|Array} name
2011-10-07 09:29:36 -07:00
* @param {Function} fn
* @return {app} for chaining
* @public
2011-10-07 09:29:36 -07:00
*/
2014-07-14 00:27:25 -04:00
app.param = function param(name, fn) {
2011-10-07 09:29:36 -07:00
if (Array.isArray(name)) {
2014-07-14 00:27:25 -04:00
for (var i = 0; i < name.length; i++) {
this.param(name[i], fn);
}
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
return this;
2011-10-07 09:29:36 -07:00
}
2014-07-14 00:27:25 -04:00
this.router.param(name, fn);
2011-10-07 09:29:36 -07:00
return this;
};
/**
* Assign `setting` to `val`, or return `setting`'s value.
2012-04-15 21:01:17 -07:00
*
* app.set('foo', 'bar');
* app.set('foo');
2012-04-15 21:01:17 -07:00
* // => "bar"
*
2011-10-07 09:29:36 -07:00
* Mounted servers inherit their parent server's settings.
*
* @param {String} setting
* @param {*} [val]
2012-04-15 21:01:17 -07:00
* @return {Server} for chaining
* @public
2011-10-07 09:29:36 -07:00
*/
app.set = function set(setting, val) {
if (arguments.length === 1) {
// app.get(setting)
return this.settings[setting];
}
debug('set "%s" to %o', setting, val);
// set value
this.settings[setting] = val;
// trigger matched settings
switch (setting) {
case 'etag':
this.set('etag fn', compileETag(val));
break;
case 'query parser':
this.set('query parser fn', compileQueryParser(val));
break;
case 'trust proxy':
this.set('trust proxy fn', compileTrust(val));
// trust proxy inherit back-compat
Object.defineProperty(this.settings, trustProxyDefaultSymbol, {
configurable: true,
value: false
});
break;
2011-10-07 09:29:36 -07:00
}
return this;
2011-10-07 09:29:36 -07:00
};
2011-12-06 15:36:44 -08:00
/**
* Return the app's absolute pathname
* based on the parent(s) that have
* mounted it.
*
2012-04-15 21:01:17 -07:00
* For example if the application was
* mounted as "/admin", which itself
* was mounted as "/blog" then the
* return value would be "/blog/admin".
*
2011-12-06 15:36:44 -08:00
* @return {String}
* @private
2011-12-06 15:36:44 -08:00
*/
app.path = function path() {
2011-12-06 15:36:44 -08:00
return this.parent
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
? this.parent.path() + this.mountpath
2011-12-06 15:36:44 -08:00
: '';
};
2011-10-07 09:29:36 -07:00
/**
2012-04-15 21:01:17 -07:00
* Check if `setting` is enabled (truthy).
*
* app.enabled('foo')
* // => false
*
* app.enable('foo')
* app.enabled('foo')
* // => true
2011-10-07 09:29:36 -07:00
*
* @param {String} setting
* @return {Boolean}
* @public
2011-10-07 09:29:36 -07:00
*/
app.enabled = function enabled(setting) {
return Boolean(this.set(setting));
2011-10-07 09:29:36 -07:00
};
/**
* Check if `setting` is disabled.
*
2012-04-15 21:01:17 -07:00
* app.disabled('foo')
* // => true
*
* app.enable('foo')
* app.disabled('foo')
* // => false
*
2011-10-07 09:29:36 -07:00
* @param {String} setting
* @return {Boolean}
* @public
2011-10-07 09:29:36 -07:00
*/
app.disabled = function disabled(setting) {
2011-10-07 09:29:36 -07:00
return !this.set(setting);
};
/**
* Enable `setting`.
*
* @param {String} setting
* @return {app} for chaining
* @public
2011-10-07 09:29:36 -07:00
*/
app.enable = function enable(setting) {
2011-10-07 09:29:36 -07:00
return this.set(setting, true);
};
/**
* Disable `setting`.
*
* @param {String} setting
* @return {app} for chaining
* @public
2011-10-07 09:29:36 -07:00
*/
app.disable = function disable(setting) {
2011-10-07 09:29:36 -07:00
return this.set(setting, false);
};
/**
* Delegate `.VERB(...)` calls to `router.VERB(...)`.
2011-10-07 09:29:36 -07:00
*/
methods.forEach(function (method) {
app[method] = function (path) {
if (method === 'get' && arguments.length === 1) {
// app.get(setting)
return this.set(path);
}
2014-07-14 00:27:25 -04:00
var route = this.route(path);
route[method].apply(route, slice.call(arguments, 1));
return this;
};
2011-10-07 09:29:36 -07:00
});
/**
* Special-cased "all" method, applying the given route `path`,
* middleware, and callback to _every_ HTTP method.
*
* @param {String} path
* @param {Function} ...
* @return {app} for chaining
* @public
2011-10-07 09:29:36 -07:00
*/
app.all = function all(path) {
2014-07-14 00:27:25 -04:00
var route = this.route(path);
var args = slice.call(arguments, 1);
for (var i = 0; i < methods.length; i++) {
route[methods[i]].apply(route, args);
}
remove app.router and refactor middleware processing This is an overhaul of middleware processing, Router and Route. Connect is no longer used to process the middleware stack. This functionality has been split into two parts: middleware stack and default error response. The entry point for request processing is the `app.handle` method. It sets up the default error response handle (to run in the event of no other error handler) and then triggers the app router (instance of Router) to handle the request. The app router `handle` function contains the middleware dispatch layer previously in the connect codebase. This layer handle the logic for dispatching `.use` calls (stripping paths if needed). The app contains a base router `app._router`. New routes can be created and `.use`d on this router to organize routes into files. Routers now have the following methods `.use`, `.all`, `.param` which are all public. Additionally, Routers have a `.route(path)` method which returns a new instance of Route for the requested path. Route(s) are isolated middleware stacks and contain methods for the HTTP verbs as well as an `.all` method to act similar to middleware. These methods are chainable to easily describe requirements for a route. var route = Router.route('/foo'); // or 'app.route('/foo')' route .all(auth) .get(function(...) {}) .all(more_checks) .post(function(...) {}) Any Route and Router methods which accept handlers also accept error (arity 4) handlers which will also behave as expected. Finally, the `app.router` getter has been removed. Middleware and handlers are run IN THE ORDER they are seen in the file. This means that code which injected the `app.router` and then added error handlers (or other middleware) will need to be updated to move those handlers after any requests added on the app object. The examples have been updated accordingly. This is the largest breaking change to codebases in this commit.
2014-01-25 17:57:25 -05:00
2011-10-07 09:29:36 -07:00
return this;
};
2011-10-07 13:07:19 -07:00
/**
2011-10-07 14:51:06 -07:00
* Render the given view `name` name with `options`
2011-10-07 13:07:19 -07:00
* and a callback accepting an error and the
* rendered template string.
*
2012-04-15 21:01:17 -07:00
* Example:
*
* app.render('email', { name: 'Tobi' }, function(err, html){
* // ...
* })
*
2011-10-07 14:51:06 -07:00
* @param {String} name
* @param {Object|Function} options or fn
* @param {Function} callback
* @public
2011-10-07 13:07:19 -07:00
*/
app.render = function render(name, options, callback) {
2014-03-25 15:23:04 -07:00
var cache = this.cache;
var done = callback;
2014-03-25 15:23:04 -07:00
var engines = this.engines;
var opts = options || {};
2014-03-25 15:23:04 -07:00
var view;
2011-10-07 13:07:19 -07:00
// support callback function as second arg
if (typeof options === 'function') {
done = options;
opts = {};
2011-10-07 13:07:19 -07:00
}
2011-10-07 13:50:31 -07:00
// merge options
var renderOptions = { ...this.locals, ...opts._locals, ...opts };
2011-10-07 13:07:19 -07:00
2011-10-07 14:51:06 -07:00
// set .cache unless explicitly provided
if (renderOptions.cache == null) {
renderOptions.cache = this.enabled('view cache');
}
2011-10-07 13:07:19 -07:00
2011-10-07 14:51:06 -07:00
// primed cache
if (renderOptions.cache) {
view = cache[name];
}
2011-10-07 13:07:19 -07:00
2011-10-07 14:51:06 -07:00
// view
if (!view) {
var View = this.get('view');
view = new View(name, {
defaultEngine: this.get('view engine'),
root: this.get('views'),
engines: engines
2011-10-07 14:51:06 -07:00
});
if (!view.path) {
var dirs = Array.isArray(view.root) && view.root.length > 1
? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"'
: 'directory "' + view.root + '"'
var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs);
err.view = view;
return done(err);
}
2011-10-07 14:51:06 -07:00
// prime the cache
if (renderOptions.cache) {
cache[name] = view;
}
2011-10-07 14:51:06 -07:00
}
2011-10-07 13:07:19 -07:00
// render
2015-06-20 13:36:40 -04:00
tryRender(view, renderOptions, done);
2011-10-07 13:07:19 -07:00
};
2012-04-15 21:01:17 -07:00
/**
* Listen for connections.
*
* A node `http.Server` is returned, with this
* application (which is a `Function`) as its
* callback. If you wish to create both an HTTP
* and HTTPS server you may do so with the "http"
2012-04-25 17:59:02 -07:00
* and "https" modules as shown here:
2012-04-15 21:01:17 -07:00
*
* var http = require('node:http')
* , https = require('node:https')
2012-04-15 21:01:17 -07:00
* , express = require('express')
* , app = express();
*
* http.createServer(app).listen(80);
* https.createServer({ ... }, app).listen(443);
2012-04-15 21:01:17 -07:00
*
* @return {http.Server}
* @public
2012-04-15 21:01:17 -07:00
*/
app.listen = function listen() {
2017-02-20 17:36:39 -06:00
var server = http.createServer(this)
var args = slice.call(arguments)
2017-02-20 17:36:39 -06:00
if (typeof args[args.length - 1] === 'function') {
var done = args[args.length - 1] = once(args[args.length - 1])
server.once('error', done)
}
return server.listen.apply(server, args)
}
/**
* Log error using console.error.
*
* @param {Error} err
* @private
*/
function logerror(err) {
/* istanbul ignore next */
if (this.get('env') !== 'test') console.error(err.stack || err.toString());
}
2015-06-20 13:36:40 -04:00
/**
* Try rendering a view.
* @private
*/
function tryRender(view, options, callback) {
try {
view.render(options, callback);
} catch (err) {
callback(err);
}
}