123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
-
-
- 'use strict';
-
-
-
- var finalhandler = require('finalhandler');
- var Router = require('./router');
- var methods = require('methods');
- var middleware = require('./middleware/init');
- var query = require('./middleware/query');
- var debug = require('debug')('express:application');
- var View = require('./view');
- var http = require('http');
- var compileETag = require('./utils').compileETag;
- var compileQueryParser = require('./utils').compileQueryParser;
- var compileTrust = require('./utils').compileTrust;
- var deprecate = require('depd')('express');
- var flatten = require('array-flatten');
- var merge = require('utils-merge');
- var resolve = require('path').resolve;
- var setPrototypeOf = require('setprototypeof')
- var slice = Array.prototype.slice;
-
-
-
- var app = exports = module.exports = {};
-
-
-
- var trustProxyDefaultSymbol = '@@symbol:trust_proxy_default';
-
-
-
- app.init = function init() {
- this.cache = {};
- this.engines = {};
- this.settings = {};
-
- this.defaultConfiguration();
- };
-
-
-
- app.defaultConfiguration = function defaultConfiguration() {
- var env = process.env.NODE_ENV || 'development';
-
-
- this.enable('x-powered-by');
- this.set('etag', 'weak');
- this.set('env', env);
- this.set('query parser', 'extended');
- this.set('subdomain offset', 2);
- this.set('trust proxy', false);
-
-
- Object.defineProperty(this.settings, trustProxyDefaultSymbol, {
- configurable: true,
- value: true
- });
-
- debug('booting in %s mode', env);
-
- this.on('mount', function onmount(parent) {
-
- if (this.settings[trustProxyDefaultSymbol] === true
- && typeof parent.settings['trust proxy fn'] === 'function') {
- delete this.settings['trust proxy'];
- delete this.settings['trust proxy fn'];
- }
-
-
- setPrototypeOf(this.request, parent.request)
- setPrototypeOf(this.response, parent.response)
- setPrototypeOf(this.engines, parent.engines)
- setPrototypeOf(this.settings, parent.settings)
- });
-
-
- this.locals = Object.create(null);
-
-
- this.mountpath = '/';
-
-
- this.locals.settings = this.settings;
-
-
- this.set('view', View);
- this.set('views', resolve('views'));
- this.set('jsonp callback name', 'callback');
-
- if (env === 'production') {
- this.enable('view cache');
- }
-
- Object.defineProperty(this, 'router', {
- get: function() {
- throw new Error('\'app.router\' is deprecated!\nPlease see the 3.x to 4.x migration guide for details on how to update your app.');
- }
- });
- };
-
-
- app.lazyrouter = function lazyrouter() {
- if (!this._router) {
- this._router = new Router({
- caseSensitive: this.enabled('case sensitive routing'),
- strict: this.enabled('strict routing')
- });
-
- this._router.use(query(this.get('query parser fn')));
- this._router.use(middleware.init(this));
- }
- };
-
-
-
- app.handle = function handle(req, res, callback) {
- var router = this._router;
-
-
- var done = callback || finalhandler(req, res, {
- env: this.get('env'),
- onerror: logerror.bind(this)
- });
-
-
- if (!router) {
- debug('no routes defined on app');
- done();
- return;
- }
-
- router.handle(req, res, done);
- };
-
-
-
- app.use = function use(fn) {
- var offset = 0;
- var path = '/';
-
-
-
- if (typeof fn !== 'function') {
- var arg = fn;
-
- while (Array.isArray(arg) && arg.length !== 0) {
- arg = arg[0];
- }
-
-
- if (typeof arg !== 'function') {
- offset = 1;
- path = fn;
- }
- }
-
- var fns = flatten(slice.call(arguments, offset));
-
- if (fns.length === 0) {
- throw new TypeError('app.use() requires a middleware function')
- }
-
-
- this.lazyrouter();
- var router = this._router;
-
- fns.forEach(function (fn) {
-
- if (!fn || !fn.handle || !fn.set) {
- return router.use(path, fn);
- }
-
- debug('.use app under %s', path);
- fn.mountpath = path;
- fn.parent = this;
-
-
- router.use(path, function mounted_app(req, res, next) {
- var orig = req.app;
- fn.handle(req, res, function (err) {
- setPrototypeOf(req, orig.request)
- setPrototypeOf(res, orig.response)
- next(err);
- });
- });
-
-
- fn.emit('mount', this);
- }, this);
-
- return this;
- };
-
-
-
- app.route = function route(path) {
- this.lazyrouter();
- return this._router.route(path);
- };
-
-
-
- app.engine = function engine(ext, fn) {
- if (typeof fn !== 'function') {
- throw new Error('callback function required');
- }
-
-
- var extension = ext[0] !== '.'
- ? '.' + ext
- : ext;
-
-
- this.engines[extension] = fn;
-
- return this;
- };
-
-
-
- app.param = function param(name, fn) {
- this.lazyrouter();
-
- if (Array.isArray(name)) {
- for (var i = 0; i < name.length; i++) {
- this.param(name[i], fn);
- }
-
- return this;
- }
-
- this._router.param(name, fn);
-
- return this;
- };
-
-
-
- app.set = function set(setting, val) {
- if (arguments.length === 1) {
-
- return this.settings[setting];
- }
-
- debug('set "%s" to %o', setting, val);
-
-
- this.settings[setting] = val;
-
-
- 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));
-
-
- Object.defineProperty(this.settings, trustProxyDefaultSymbol, {
- configurable: true,
- value: false
- });
-
- break;
- }
-
- return this;
- };
-
-
-
- app.path = function path() {
- return this.parent
- ? this.parent.path() + this.mountpath
- : '';
- };
-
-
-
- app.enabled = function enabled(setting) {
- return Boolean(this.set(setting));
- };
-
-
-
- app.disabled = function disabled(setting) {
- return !this.set(setting);
- };
-
-
-
- app.enable = function enable(setting) {
- return this.set(setting, true);
- };
-
-
-
- app.disable = function disable(setting) {
- return this.set(setting, false);
- };
-
-
-
- methods.forEach(function(method){
- app[method] = function(path){
- if (method === 'get' && arguments.length === 1) {
-
- return this.set(path);
- }
-
- this.lazyrouter();
-
- var route = this._router.route(path);
- route[method].apply(route, slice.call(arguments, 1));
- return this;
- };
- });
-
-
-
- app.all = function all(path) {
- this.lazyrouter();
-
- var route = this._router.route(path);
- var args = slice.call(arguments, 1);
-
- for (var i = 0; i < methods.length; i++) {
- route[methods[i]].apply(route, args);
- }
-
- return this;
- };
-
-
-
- app.del = deprecate.function(app.delete, 'app.del: Use app.delete instead');
-
-
-
- app.render = function render(name, options, callback) {
- var cache = this.cache;
- var done = callback;
- var engines = this.engines;
- var opts = options;
- var renderOptions = {};
- var view;
-
-
- if (typeof options === 'function') {
- done = options;
- opts = {};
- }
-
-
- merge(renderOptions, this.locals);
-
-
- if (opts._locals) {
- merge(renderOptions, opts._locals);
- }
-
-
- merge(renderOptions, opts);
-
-
- if (renderOptions.cache == null) {
- renderOptions.cache = this.enabled('view cache');
- }
-
-
- if (renderOptions.cache) {
- view = cache[name];
- }
-
-
- if (!view) {
- var View = this.get('view');
-
- view = new View(name, {
- defaultEngine: this.get('view engine'),
- root: this.get('views'),
- engines: engines
- });
-
- 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);
- }
-
-
- if (renderOptions.cache) {
- cache[name] = view;
- }
- }
-
-
- tryRender(view, renderOptions, done);
- };
-
-
-
- app.listen = function listen() {
- var server = http.createServer(this);
- return server.listen.apply(server, arguments);
- };
-
-
-
- function logerror(err) {
-
- if (this.get('env') !== 'test') console.error(err.stack || err.toString());
- }
-
-
-
- function tryRender(view, options, callback) {
- try {
- view.render(options, callback);
- } catch (err) {
- callback(err);
- }
- }
|