express
Advanced tools
Comparing version 4.10.8 to 4.11.0
@@ -203,9 +203,16 @@ /** | ||
req.param = function(name, defaultValue){ | ||
req.param = function param(name, defaultValue) { | ||
var params = this.params || {}; | ||
var body = this.body || {}; | ||
var query = this.query || {}; | ||
var args = arguments.length === 1 | ||
? 'name' | ||
: 'name, default'; | ||
deprecate('req.param(' + args + '): Use req.params, req.body, or req.query instead'); | ||
if (null != params[name] && params.hasOwnProperty(name)) return params[name]; | ||
if (null != body[name]) return body[name]; | ||
if (null != query[name]) return query[name]; | ||
return defaultValue; | ||
@@ -212,0 +219,0 @@ }; |
@@ -640,2 +640,31 @@ /** | ||
/** | ||
* Append additional header `field` with value `val`. | ||
* | ||
* Example: | ||
* | ||
* res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']); | ||
* res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly'); | ||
* res.append('Warning', '199 Miscellaneous warning'); | ||
* | ||
* @param {String} field | ||
* @param {String|Array} val | ||
* @return {ServerResponse} for chaining | ||
* @api public | ||
*/ | ||
res.append = function append(field, val) { | ||
var prev = this.get(field); | ||
var value = val; | ||
if (prev) { | ||
// concat the new and prev vals | ||
value = Array.isArray(prev) ? prev.concat(val) | ||
: Array.isArray(val) ? [prev].concat(val) | ||
: [prev, val]; | ||
} | ||
return this.set(field, value); | ||
}; | ||
/** | ||
* Set header `field` to `val`, or pass | ||
@@ -911,4 +940,14 @@ * an object of header fields. | ||
var done = false; | ||
var streaming = false; | ||
var streaming; | ||
// request aborted | ||
function onaborted() { | ||
if (done) return; | ||
done = true; | ||
var err = new Error('Request aborted'); | ||
err.code = 'ECONNABORT'; | ||
callback(err); | ||
} | ||
// directory | ||
@@ -926,3 +965,2 @@ function ondirectory() { | ||
function onerror(err) { | ||
if (!err) return; | ||
if (done) return; | ||
@@ -942,3 +980,3 @@ done = true; | ||
function onfile() { | ||
onFinished(res, onfinish); | ||
streaming = false; | ||
} | ||
@@ -952,14 +990,10 @@ | ||
setImmediate(function () { | ||
if (done) return; | ||
done = true; | ||
if (!streaming) { | ||
callback(); | ||
if (streaming !== false && !done) { | ||
onaborted(); | ||
return; | ||
} | ||
// response finished before end of file | ||
var err = new Error('Request aborted'); | ||
err.code = 'ECONNABORT'; | ||
callback(err); | ||
if (done) return; | ||
done = true; | ||
callback(); | ||
}); | ||
@@ -978,3 +1012,3 @@ } | ||
file.on('stream', onstream); | ||
onFinished(res, onerror); | ||
onFinished(res, onfinish); | ||
@@ -981,0 +1015,0 @@ if (options.headers) { |
@@ -11,2 +11,3 @@ | ||
var debug = require('debug')('express:router'); | ||
var deprecate = require('depd')('express'); | ||
var parseUrl = require('parseurl'); | ||
@@ -85,5 +86,6 @@ var utils = require('../utils'); | ||
proto.param = function(name, fn){ | ||
proto.param = function param(name, fn) { | ||
// param logic | ||
if ('function' == typeof name) { | ||
if (typeof name === 'function') { | ||
deprecate('router.param(fn): Refactor to use path params'); | ||
this._params.push(name); | ||
@@ -99,2 +101,3 @@ return; | ||
if (name[0] === ':') { | ||
deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.substr(1)) + ', fn) instead'); | ||
name = name.substr(1); | ||
@@ -173,4 +176,3 @@ } | ||
var layer = stack[idx++]; | ||
// remove added slash | ||
if (slashAdded) { | ||
@@ -181,2 +183,3 @@ req.url = req.url.substr(1); | ||
// restore altered req.url | ||
if (removed.length !== 0) { | ||
@@ -188,3 +191,4 @@ req.baseUrl = parentUrl; | ||
if (!layer) { | ||
// no more matching layers | ||
if (idx >= stack.length) { | ||
setImmediate(done, layerError); | ||
@@ -194,52 +198,81 @@ return; | ||
self.match_layer(layer, req, res, function (err, path) { | ||
if (err || path === undefined) { | ||
return next(layerError || err); | ||
// 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; | ||
} | ||
// route object and not middleware | ||
var route = layer.route; | ||
if (match !== true) { | ||
continue; | ||
} | ||
// if final route, then we support options | ||
if (route) { | ||
// we don't run any routes with error first | ||
if (layerError) { | ||
return next(layerError); | ||
} | ||
if (!route) { | ||
// process non-route handlers normally | ||
continue; | ||
} | ||
var method = req.method; | ||
var has_method = route._handles_method(method); | ||
if (layerError) { | ||
// routes do not match with a pending error | ||
match = false; | ||
continue; | ||
} | ||
// build up automatic options response | ||
if (!has_method && method === 'OPTIONS') { | ||
appendMethods(options, route._options()); | ||
} | ||
var method = req.method; | ||
var has_method = route._handles_method(method); | ||
// don't even bother | ||
if (!has_method && method !== 'HEAD') { | ||
return next(); | ||
} | ||
// build up automatic options response | ||
if (!has_method && method === 'OPTIONS') { | ||
appendMethods(options, route._options()); | ||
} | ||
// we can now dispatch to the route | ||
req.route = route; | ||
// don't even bother matching route | ||
if (!has_method && method !== 'HEAD') { | ||
match = false; | ||
continue; | ||
} | ||
} | ||
// Capture one-time layer values | ||
req.params = self.mergeParams | ||
? mergeParams(layer.params, parentParams) | ||
: layer.params; | ||
var layerPath = layer.path; | ||
// no match | ||
if (match !== true) { | ||
return done(layerError); | ||
} | ||
// this should be done for the layer | ||
self.process_params(layer, paramcalled, req, res, function (err) { | ||
if (err) { | ||
return next(layerError || err); | ||
} | ||
// store route for dispatch on change | ||
if (route) { | ||
req.route = route; | ||
} | ||
if (route) { | ||
return layer.handle_request(req, res, next); | ||
} | ||
// Capture one-time layer values | ||
req.params = self.mergeParams | ||
? mergeParams(layer.params, parentParams) | ||
: layer.params; | ||
var layerPath = layer.path; | ||
trim_prefix(layer, layerError, layerPath, 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); | ||
}); | ||
@@ -282,25 +315,2 @@ } | ||
/** | ||
* Match request to a layer. | ||
* | ||
* @api private | ||
*/ | ||
proto.match_layer = function match_layer(layer, req, res, done) { | ||
var error = null; | ||
var path; | ||
try { | ||
path = parseUrl(req).pathname; | ||
if (!layer.match(path)) { | ||
path = undefined; | ||
} | ||
} catch (err) { | ||
error = err; | ||
} | ||
done(error, path); | ||
}; | ||
/** | ||
* Process any parameters for the layer. | ||
@@ -511,2 +521,11 @@ * | ||
// get pathname of request | ||
function getPathname(req) { | ||
try { | ||
return parseUrl(req).pathname; | ||
} catch (err) { | ||
return undefined; | ||
} | ||
} | ||
// get type for error message | ||
@@ -525,2 +544,18 @@ function gettype(obj) { | ||
/** | ||
* 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 | ||
@@ -527,0 +562,0 @@ function mergeParams(params, parent) { |
@@ -55,6 +55,16 @@ /** | ||
Route.prototype._options = function(){ | ||
return Object.keys(this.methods).map(function(method) { | ||
return method.toUpperCase(); | ||
}); | ||
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; | ||
}; | ||
@@ -61,0 +71,0 @@ |
{ | ||
"name": "express", | ||
"description": "Fast, unopinionated, minimalist web framework", | ||
"version": "4.10.8", | ||
"version": "4.11.0", | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
@@ -30,3 +30,3 @@ "contributors": [ | ||
"dependencies": { | ||
"accepts": "~1.1.4", | ||
"accepts": "~1.2.2", | ||
"content-disposition": "0.5.0", | ||
@@ -41,3 +41,3 @@ "cookie-signature": "1.0.5", | ||
"media-typer": "0.3.0", | ||
"methods": "1.1.1", | ||
"methods": "~1.1.1", | ||
"on-finished": "~2.2.0", | ||
@@ -49,4 +49,4 @@ "parseurl": "~1.3.0", | ||
"range-parser": "~1.0.2", | ||
"send": "0.10.1", | ||
"serve-static": "~1.7.2", | ||
"send": "0.11.0", | ||
"serve-static": "~1.8.0", | ||
"type-is": "~1.5.5", | ||
@@ -60,7 +60,7 @@ "vary": "~1.0.0", | ||
"after": "0.8.1", | ||
"ejs": "2.0.8", | ||
"istanbul": "0.3.5", | ||
"mocha": "~2.0.0", | ||
"should": "~4.3.1", | ||
"mocha": "~2.1.0", | ||
"should": "~4.4.4", | ||
"supertest": "~0.15.0", | ||
"ejs": "~1.0.0", | ||
"marked": "0.3.2", | ||
@@ -71,4 +71,4 @@ "hjs": "~0.0.6", | ||
"cookie-parser": "~1.3.3", | ||
"express-session": "~1.9.2", | ||
"jade": "~1.8.2", | ||
"express-session": "~1.10.1", | ||
"jade": "~1.9.0", | ||
"method-override": "~2.3.1", | ||
@@ -75,0 +75,0 @@ "morgan": "~1.5.1", |
Sorry, the diff of this file is too big to display
168842
3057
+ Addedaccepts@1.2.13(transitive)
+ Addedmethods@1.1.2(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addednegotiator@0.5.3(transitive)
+ Addedsend@0.11.00.11.1(transitive)
+ Addedserve-static@1.8.1(transitive)
- Removedaccepts@1.1.4(transitive)
- Removedmethods@1.1.1(transitive)
- Removedms@0.6.2(transitive)
- Removednegotiator@0.4.9(transitive)
- Removedon-finished@2.1.1(transitive)
- Removedsend@0.10.1(transitive)
- Removedserve-static@1.7.2(transitive)
Updatedaccepts@~1.2.2
Updatedmethods@~1.1.1
Updatedsend@0.11.0
Updatedserve-static@~1.8.0