diff options
author | Timoney, Daniel (dt5972) <dtimoney@att.com> | 2017-02-15 10:37:53 -0500 |
---|---|---|
committer | Timoney, Daniel (dt5972) <dtimoney@att.com> | 2017-02-15 10:40:37 -0500 |
commit | 324ee36fe31763e507b422ab0a88e4230045e205 (patch) | |
tree | d0b04520f6657601c918ce63fd27575977624187 /dgbuilder/dgeflows/node_modules/express/lib/router | |
parent | f0c97e8db427481e28c0a16b789bc73801b35e47 (diff) |
Initial commit for OpenECOMP SDN-C OA&M
Change-Id: I7ab579fd0d206bf356f36d52dcdf4f71f1fa2680
Signed-off-by: Timoney, Daniel (dt5972) <dtimoney@att.com>
Former-commit-id: 2a9f0edd09581f907e62ec4689b5ac94dd5382ba
Diffstat (limited to 'dgbuilder/dgeflows/node_modules/express/lib/router')
3 files changed, 979 insertions, 0 deletions
diff --git a/dgbuilder/dgeflows/node_modules/express/lib/router/index.js b/dgbuilder/dgeflows/node_modules/express/lib/router/index.js new file mode 100644 index 00000000..209f881b --- /dev/null +++ b/dgbuilder/dgeflows/node_modules/express/lib/router/index.js @@ -0,0 +1,630 @@ + +/** + * Module dependencies. + */ + +var Route = require('./route'); +var Layer = require('./layer'); +var methods = require('methods'); +var mixin = require('utils-merge'); +var debug = require('debug')('express:router'); +var deprecate = require('depd')('express'); +var parseUrl = require('parseurl'); +var utils = require('../utils'); + +/** + * Module variables. + */ + +var objectRegExp = /^\[object (\S+)\]$/; +var slice = Array.prototype.slice; +var toString = Object.prototype.toString; + +/** + * Initialize a new `Router` with the given `options`. + * + * @param {Object} options + * @return {Router} which is an callable function + * @api public + */ + +var proto = module.exports = function(options) { + options = options || {}; + + function router(req, res, next) { + router.handle(req, res, next); + } + + // mixin Router class functions + router.__proto__ = proto; + + router.params = {}; + router._params = []; + router.caseSensitive = options.caseSensitive; + router.mergeParams = options.mergeParams; + router.strict = options.strict; + router.stack = []; + + return router; +}; + +/** + * Map the given param placeholder `name`(s) to the given callback. + * + * Parameter mapping is used to provide pre-conditions to routes + * which use normalized placeholders. For example a _:user_id_ parameter + * could automatically load a user's information from the database without + * any additional code, + * + * The callback uses the same signature as middleware, the only difference + * being that the value of the placeholder is passed, in this case the _id_ + * of the user. Once the `next()` function is invoked, just like middleware + * it will continue on to execute the route, or subsequent parameter functions. + * + * Just like in middleware, you must either respond to the request or call next + * to avoid stalling the request. + * + * app.param('user_id', function(req, res, next, id){ + * User.find(id, function(err, user){ + * if (err) { + * return next(err); + * } else if (!user) { + * return next(new Error('failed to load user')); + * } + * req.user = user; + * next(); + * }); + * }); + * + * @param {String} name + * @param {Function} fn + * @return {app} for chaining + * @api public + */ + +proto.param = function param(name, fn) { + // param logic + if (typeof name === 'function') { + deprecate('router.param(fn): Refactor to use path params'); + this._params.push(name); + return; + } + + // apply param functions + var params = this._params; + var len = params.length; + var ret; + + if (name[0] === ':') { + deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.substr(1)) + ', fn) instead'); + name = name.substr(1); + } + + for (var i = 0; i < len; ++i) { + if (ret = params[i](name, fn)) { + fn = ret; + } + } + + // ensure we end up with a + // middleware function + if ('function' != typeof fn) { + throw new Error('invalid param() call for ' + name + ', got ' + fn); + } + + (this.params[name] = this.params[name] || []).push(fn); + return this; +}; + +/** + * Dispatch a req, res into the router. + * + * @api private + */ + +proto.handle = function(req, res, done) { + var self = this; + + debug('dispatching %s %s', req.method, req.url); + + var search = 1 + req.url.indexOf('?'); + var pathlength = search ? search - 1 : req.url.length; + var fqdn = req.url[0] !== '/' && 1 + req.url.substr(0, pathlength).indexOf('://'); + var protohost = fqdn ? req.url.substr(0, req.url.indexOf('/', 2 + fqdn)) : ''; + var idx = 0; + var removed = ''; + var slashAdded = false; + var paramcalled = {}; + + // store options for OPTIONS request + // only used if OPTIONS request + var options = []; + + // middleware and routes + var stack = self.stack; + + // manage inter-router variables + var parentParams = req.params; + var parentUrl = req.baseUrl || ''; + done = restore(done, req, 'baseUrl', 'next', 'params'); + + // setup next layer + req.next = next; + + // for options requests, respond with a default if nothing else responds + if (req.method === 'OPTIONS') { + done = wrap(done, function(old, err) { + if (err || options.length === 0) return old(err); + sendOptionsResponse(res, options, old); + }); + } + + // setup basic req values + req.baseUrl = parentUrl; + req.originalUrl = req.originalUrl || req.url; + + next(); + + function next(err) { + var layerError = err === 'route' + ? null + : err; + + // remove added slash + if (slashAdded) { + req.url = req.url.substr(1); + slashAdded = false; + } + + // restore altered req.url + if (removed.length !== 0) { + req.baseUrl = parentUrl; + req.url = protohost + removed + req.url.substr(protohost.length); + removed = ''; + } + + // no more matching layers + if (idx >= stack.length) { + setImmediate(done, layerError); + return; + } + + // get pathname of request + var path = getPathname(req); + + if (path == null) { + return done(layerError); + } + + // find next matching layer + var layer; + var match; + var route; + + while (match !== true && idx < stack.length) { + layer = stack[idx++]; + match = matchLayer(layer, path); + route = layer.route; + + if (typeof match !== 'boolean') { + // hold on to layerError + layerError = layerError || match; + } + + if (match !== true) { + continue; + } + + if (!route) { + // process non-route handlers normally + continue; + } + + if (layerError) { + // routes do not match with a pending error + match = false; + continue; + } + + var method = req.method; + var has_method = route._handles_method(method); + + // build up automatic options response + if (!has_method && method === 'OPTIONS') { + appendMethods(options, route._options()); + } + + // don't even bother matching route + if (!has_method && method !== 'HEAD') { + match = false; + continue; + } + } + + // no match + if (match !== true) { + return done(layerError); + } + + // store route for dispatch on change + if (route) { + req.route = route; + } + + // Capture one-time layer values + req.params = self.mergeParams + ? mergeParams(layer.params, parentParams) + : layer.params; + var layerPath = layer.path; + + // this should be done for the layer + self.process_params(layer, paramcalled, req, res, function (err) { + if (err) { + return next(layerError || err); + } + + if (route) { + return layer.handle_request(req, res, next); + } + + trim_prefix(layer, layerError, layerPath, path); + }); + } + + function trim_prefix(layer, layerError, layerPath, path) { + var c = path[layerPath.length]; + if (c && '/' !== c && '.' !== c) return next(layerError); + + // Trim off the part of the url that matches the route + // middleware (.use stuff) needs to have the path stripped + if (layerPath.length !== 0) { + debug('trim prefix (%s) from url %s', layerPath, req.url); + removed = layerPath; + req.url = protohost + req.url.substr(protohost.length + removed.length); + + // Ensure leading slash + if (!fqdn && req.url[0] !== '/') { + req.url = '/' + req.url; + slashAdded = true; + } + + // Setup base URL (no trailing slash) + req.baseUrl = parentUrl + (removed[removed.length - 1] === '/' + ? removed.substring(0, removed.length - 1) + : removed); + } + + debug('%s %s : %s', layer.name, layerPath, req.originalUrl); + + if (layerError) { + layer.handle_error(layerError, req, res, next); + } else { + layer.handle_request(req, res, next); + } + } +}; + +/** + * Process any parameters for the layer. + * + * @api private + */ + +proto.process_params = function(layer, called, req, res, done) { + var params = this.params; + + // captured parameters from the layer, keys and values + var keys = layer.keys; + + // fast track + if (!keys || keys.length === 0) { + return done(); + } + + var i = 0; + var name; + var paramIndex = 0; + var key; + var paramVal; + var paramCallbacks; + var paramCalled; + + // process params in order + // param callbacks can be async + function param(err) { + if (err) { + return done(err); + } + + if (i >= keys.length ) { + return done(); + } + + paramIndex = 0; + key = keys[i++]; + + if (!key) { + return done(); + } + + name = key.name; + paramVal = req.params[name]; + paramCallbacks = params[name]; + paramCalled = called[name]; + + if (paramVal === undefined || !paramCallbacks) { + return param(); + } + + // param previously called with same value or error occurred + if (paramCalled && (paramCalled.error || paramCalled.match === paramVal)) { + // restore value + req.params[name] = paramCalled.value; + + // next param + return param(paramCalled.error); + } + + called[name] = paramCalled = { + error: null, + match: paramVal, + value: paramVal + }; + + paramCallback(); + } + + // single param callbacks + function paramCallback(err) { + var fn = paramCallbacks[paramIndex++]; + + // store updated value + paramCalled.value = req.params[key.name]; + + if (err) { + // store error + paramCalled.error = err; + param(err); + return; + } + + if (!fn) return param(); + + try { + fn(req, res, paramCallback, paramVal, key.name); + } catch (e) { + paramCallback(e); + } + } + + param(); +}; + +/** + * Use the given middleware function, with optional path, defaulting to "/". + * + * Use (like `.all`) will run for any http METHOD, but it will not add + * handlers for those methods so OPTIONS requests will not consider `.use` + * functions even if they could respond. + * + * The other difference is that _route_ path is stripped and not visible + * to the handler function. The main effect of this feature is that mounted + * handlers can operate without any code changes regardless of the "prefix" + * pathname. + * + * @api public + */ + +proto.use = function use(fn) { + var offset = 0; + var path = '/'; + + // default path to '/' + // disambiguate router.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 callbacks = utils.flatten(slice.call(arguments, offset)); + + if (callbacks.length === 0) { + throw new TypeError('Router.use() requires middleware functions'); + } + + callbacks.forEach(function (fn) { + if (typeof fn !== 'function') { + throw new TypeError('Router.use() requires middleware function but got a ' + gettype(fn)); + } + + // add the middleware + debug('use %s %s', path, fn.name || '<anonymous>'); + + var layer = new Layer(path, { + sensitive: this.caseSensitive, + strict: false, + end: false + }, fn); + + layer.route = undefined; + + this.stack.push(layer); + }, this); + + return this; +}; + +/** + * Create a new Route for the given path. + * + * Each route contains a separate middleware stack and VERB handlers. + * + * See the Route api documentation for details on adding handlers + * and middleware to routes. + * + * @param {String} path + * @return {Route} + * @api public + */ + +proto.route = function(path){ + var route = new Route(path); + + var layer = new Layer(path, { + sensitive: this.caseSensitive, + strict: this.strict, + end: true + }, route.dispatch.bind(route)); + + layer.route = route; + + this.stack.push(layer); + return route; +}; + +// create Router#VERB functions +methods.concat('all').forEach(function(method){ + proto[method] = function(path){ + var route = this.route(path) + route[method].apply(route, slice.call(arguments, 1)); + return this; + }; +}); + +// append methods to a list of methods +function appendMethods(list, addition) { + for (var i = 0; i < addition.length; i++) { + var method = addition[i]; + if (list.indexOf(method) === -1) { + list.push(method); + } + } +} + +// get pathname of request +function getPathname(req) { + try { + return parseUrl(req).pathname; + } catch (err) { + return undefined; + } +} + +// get type for error message +function gettype(obj) { + var type = typeof obj; + + if (type !== 'object') { + return type; + } + + // inspect [[Class]] for objects + return toString.call(obj) + .replace(objectRegExp, '$1'); +} + +/** + * Match path to a layer. + * + * @param {Layer} layer + * @param {string} path + * @private + */ + +function matchLayer(layer, path) { + try { + return layer.match(path); + } catch (err) { + return err; + } +} + +// merge params with parent params +function mergeParams(params, parent) { + if (typeof parent !== 'object' || !parent) { + return params; + } + + // make copy of parent for base + var obj = mixin({}, parent); + + // simple non-numeric merging + if (!(0 in params) || !(0 in parent)) { + return mixin(obj, params); + } + + var i = 0; + var o = 0; + + // determine numeric gaps + while (i === o || o in parent) { + if (i in params) i++; + if (o in parent) o++; + } + + // offset numeric indices in params before merge + for (i--; i >= 0; i--) { + params[i + o] = params[i]; + + // create holes for the merge when necessary + if (i < o) { + delete params[i]; + } + } + + return mixin(parent, params); +} + +// restore obj props after function +function restore(fn, obj) { + var props = new Array(arguments.length - 2); + var vals = new Array(arguments.length - 2); + + for (var i = 0; i < props.length; i++) { + props[i] = arguments[i + 2]; + vals[i] = obj[props[i]]; + } + + return function(err){ + // restore vals + for (var i = 0; i < props.length; i++) { + obj[props[i]] = vals[i]; + } + + return fn.apply(this, arguments); + }; +} + +// send an OPTIONS response +function sendOptionsResponse(res, options, next) { + try { + var body = options.join(','); + res.set('Allow', body); + res.send(body); + } catch (err) { + next(err); + } +} + +// wrap a function +function wrap(old, fn) { + return function proxy() { + var args = new Array(arguments.length + 1); + + args[0] = old; + for (var i = 0, len = arguments.length; i < len; i++) { + args[i + 1] = arguments[i]; + } + + fn.apply(this, args); + }; +} diff --git a/dgbuilder/dgeflows/node_modules/express/lib/router/layer.js b/dgbuilder/dgeflows/node_modules/express/lib/router/layer.js new file mode 100644 index 00000000..88ebd396 --- /dev/null +++ b/dgbuilder/dgeflows/node_modules/express/lib/router/layer.js @@ -0,0 +1,166 @@ +/** + * Module dependencies. + */ + +var pathRegexp = require('path-to-regexp'); +var debug = require('debug')('express:router:layer'); + +/** + * Module variables. + */ + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Expose `Layer`. + */ + +module.exports = Layer; + +function Layer(path, options, fn) { + if (!(this instanceof Layer)) { + return new Layer(path, options, fn); + } + + debug('new %s', path); + options = options || {}; + + this.handle = fn; + this.name = fn.name || '<anonymous>'; + this.params = undefined; + this.path = undefined; + this.regexp = pathRegexp(path, this.keys = [], options); + + if (path === '/' && options.end === false) { + this.regexp.fast_slash = true; + } +} + +/** + * Handle the error for the layer. + * + * @param {Error} error + * @param {Request} req + * @param {Response} res + * @param {function} next + * @api private + */ + +Layer.prototype.handle_error = function handle_error(error, req, res, next) { + var fn = this.handle; + + if (fn.length !== 4) { + // not a standard error handler + return next(error); + } + + try { + fn(error, req, res, next); + } catch (err) { + next(err); + } +}; + +/** + * Handle the request for the layer. + * + * @param {Request} req + * @param {Response} res + * @param {function} next + * @api private + */ + +Layer.prototype.handle_request = function handle(req, res, next) { + var fn = this.handle; + + if (fn.length > 3) { + // not a standard request handler + return next(); + } + + try { + fn(req, res, next); + } catch (err) { + next(err); + } +}; + +/** + * Check if this route matches `path`, if so + * populate `.params`. + * + * @param {String} path + * @return {Boolean} + * @api private + */ + +Layer.prototype.match = function match(path) { + if (path == null) { + // no path, nothing matches + this.params = undefined; + this.path = undefined; + return false; + } + + if (this.regexp.fast_slash) { + // fast path non-ending match for / (everything matches) + this.params = {}; + this.path = ''; + return true; + } + + var m = this.regexp.exec(path); + + if (!m) { + this.params = undefined; + this.path = undefined; + return false; + } + + // store values + this.params = {}; + this.path = m[0]; + + var keys = this.keys; + var params = this.params; + var prop; + var n = 0; + var key; + var val; + + for (var i = 1, len = m.length; i < len; ++i) { + key = keys[i - 1]; + prop = key + ? key.name + : n++; + val = decode_param(m[i]); + + if (val !== undefined || !(hasOwnProperty.call(params, prop))) { + params[prop] = val; + } + } + + return true; +}; + +/** + * Decode param value. + * + * @param {string} val + * @return {string} + * @api private + */ + +function decode_param(val){ + if (typeof val !== 'string') { + return val; + } + + try { + return decodeURIComponent(val); + } catch (e) { + var err = new TypeError("Failed to decode param '" + val + "'"); + err.status = 400; + throw err; + } +} diff --git a/dgbuilder/dgeflows/node_modules/express/lib/router/route.js b/dgbuilder/dgeflows/node_modules/express/lib/router/route.js new file mode 100644 index 00000000..6213b821 --- /dev/null +++ b/dgbuilder/dgeflows/node_modules/express/lib/router/route.js @@ -0,0 +1,183 @@ +/** + * Module dependencies. + */ + +var debug = require('debug')('express:router:route'); +var Layer = require('./layer'); +var methods = require('methods'); +var utils = require('../utils'); + +/** + * Expose `Route`. + */ + +module.exports = Route; + +/** + * Initialize `Route` with the given `path`, + * + * @param {String} path + * @api private + */ + +function Route(path) { + debug('new %s', path); + this.path = path; + this.stack = []; + + // route handlers for various http methods + this.methods = {}; +} + +/** + * @api private + */ + +Route.prototype._handles_method = function _handles_method(method) { + if (this.methods._all) { + return true; + } + + method = method.toLowerCase(); + + if (method === 'head' && !this.methods['head']) { + method = 'get'; + } + + return Boolean(this.methods[method]); +}; + +/** + * @return {Array} supported HTTP methods + * @api private + */ + +Route.prototype._options = function _options() { + var methods = Object.keys(this.methods); + + // append automatic head + if (this.methods.get && !this.methods.head) { + methods.push('head'); + } + + for (var i = 0; i < methods.length; i++) { + // make upper case + methods[i] = methods[i].toUpperCase(); + } + + return methods; +}; + +/** + * dispatch req, res into this route + * + * @api private + */ + +Route.prototype.dispatch = function(req, res, done){ + var idx = 0; + var stack = this.stack; + if (stack.length === 0) { + return done(); + } + + var method = req.method.toLowerCase(); + if (method === 'head' && !this.methods['head']) { + method = 'get'; + } + + req.route = this; + + next(); + + function next(err) { + if (err && err === 'route') { + return done(); + } + + var layer = stack[idx++]; + if (!layer) { + return done(err); + } + + if (layer.method && layer.method !== method) { + return next(err); + } + + if (err) { + layer.handle_error(err, req, res, next); + } else { + layer.handle_request(req, res, next); + } + } +}; + +/** + * Add a handler for all HTTP verbs to this route. + * + * Behaves just like middleware and can respond or call `next` + * to continue processing. + * + * You can use multiple `.all` call to add multiple handlers. + * + * function check_something(req, res, next){ + * next(); + * }; + * + * function validate_user(req, res, next){ + * next(); + * }; + * + * route + * .all(validate_user) + * .all(check_something) + * .get(function(req, res, next){ + * res.send('hello world'); + * }); + * + * @param {function} handler + * @return {Route} for chaining + * @api public + */ + +Route.prototype.all = function(){ + var callbacks = utils.flatten([].slice.call(arguments)); + callbacks.forEach(function(fn) { + if (typeof fn !== 'function') { + var type = {}.toString.call(fn); + var msg = 'Route.all() requires callback functions but got a ' + type; + throw new Error(msg); + } + + var layer = Layer('/', {}, fn); + layer.method = undefined; + + this.methods._all = true; + this.stack.push(layer); + }, this); + + return this; +}; + +methods.forEach(function(method){ + Route.prototype[method] = function(){ + var callbacks = utils.flatten([].slice.call(arguments)); + + callbacks.forEach(function(fn) { + if (typeof fn !== 'function') { + var type = {}.toString.call(fn); + var msg = 'Route.' + method + '() requires callback functions but got a ' + type; + throw new Error(msg); + } + + debug('%s %s', method, this.path); + + var layer = Layer('/', {}, fn); + layer.method = method; + + this.methods[method] = true; + this.stack.push(layer); + }, this); + return this; + }; +}); |