Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added validateResponse middleware

  • Loading branch information...
commit ff789b584fccb1dceac00faf31d7c1afabb3875b 1 parent da32c85
Nathan authored
Showing with 46 additions and 3 deletions.
  1. +2 −1  README.md
  2. +44 −2 lib/middleware.js
3  README.md
View
@@ -87,7 +87,8 @@ want to use them.
The batteries middleware creates the following JSGI chain where `nextApp` is the JSGI appliance passed as the first parameter
to `batteries`:
- error - directory - parted - methodOverride - session - flash - bodyAdapter - stringReturnAdapter - nextApp
+ error -> validateResponse -> directory -> parted -> methodOverride
+ -> session -> flash -> bodyAdapter -> stringReturnAdapter -> nextApp
The binary middleware is configured to check the path of the request and if it corresponds to a potential directory in the 'public' directory,
the request is routed to the `directory` middleware to serve a static file.
46 lib/middleware.js
View
@@ -151,7 +151,8 @@ exports.parted = exports.Parted = function(nextApp, opts) {
/**
* Translates rejected promises to a JSGI error response.
*
- * @param errorResponse {Function} A function that returns a JSGI response when passed an error.
+ * @param errorResponse {Function} Optional. A function that returns a JSGI response when passed an error.
+ * @returns {Function} JSGI response.
*/
exports.error = exports.Error = function(app, errorResponse) {
errorResponse = errorResponse ||
@@ -180,6 +181,45 @@ exports.error = exports.Error = function(app, errorResponse) {
};
};
+/**
+ * Validates that the response from nextApp is a valid JSGI response.
+ * Rejects the promise if the response is invalid.
+ *
+ * @param {Function} nextApp The next application in the JSGI chain.
+ * @returns {Function} JSGI response.
+ */
+exports.validateResponse = exports.ValidateResponse = function(nextApp) {
+ return function(req) {
+ return when(nextApp(req), function(resp) {
+ if (!resp) {
+ throw 'Response must be an object.'
+ }
+
+ if (!resp.body) {
+ throw 'Response must have a body property.'
+ }
+
+ if (!resp.body.forEach) {
+ throw 'Response body must have a forEach method.';
+ }
+
+ if (typeof resp.body.forEach !== 'function') {
+ throw 'Response body has a forEach method but the forEach method is not a function.'
+ }
+
+ if (!resp.status) {
+ throw 'Response must have a status property.';
+ }
+
+ if (typeof resp.status.constructor !== '[Function: Number]') {
+ throw 'Response has a status property but the status property must be a number.'
+ }
+
+ return resp;
+ });
+ };
+};
+
var HTTP_METHODS = exports.HTTP_METHODS = {
"GET": true,
"HEAD": true,
@@ -569,7 +609,9 @@ exports.binary = function(conditional, appTrue, appFalse) {
* All the goodies in one convenient middleware.
*
* Includes the following JSGI Chain:
- * error - directory - parted - methodOverride - session - flash - bodyAdapter - stringReturnAdapter - nextApp
+ *
+ * error -> validateResponse -> directory -> parted -> methodOverride
+ * -> session -> flash -> bodyAdapter -> stringReturnAdapter -> nextApp
*
* @param {Object} config Optional configuration, if arity is two first parameter is config.
* @param {Function} nextApp The next application (Middleware, Bogart Router, etc...) in the JSGI chain.
Please sign in to comment.
Something went wrong with that request. Please try again.