diff --git a/README.md b/README.md
index 53a2b7a4..75d4fe01 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
[](https://www.npmjs.com/package/@dadi/web)
-[](https://github.com/dadi/web)
+[](https://github.com/dadi/web)
[](https://travis-ci.org/dadi/web)
[](http://standardjs.com/)
diff --git a/dadi/lib/api/index.js b/dadi/lib/api/index.js
index caff79fc..106207a9 100755
--- a/dadi/lib/api/index.js
+++ b/dadi/lib/api/index.js
@@ -212,13 +212,11 @@ Api.prototype.listener = function (req, res) {
req.params = {}
req.paths = []
- // get matching routes, and add req.params
- var matches = this._match(req)
-
var originalReqParams = req.params
+ var pathsLoaded = false
- var doStack = function (i) {
- return function (err) {
+ var doStack = stackIdx => {
+ return err => {
if (err) return errStack(0)(err)
// add the original params back, in case a middleware
@@ -226,28 +224,51 @@ Api.prototype.listener = function (req, res) {
_.extend(req.params, originalReqParams)
try {
- self.stack[i](req, res, doStack(++i))
+ // if end of the stack, no middleware could handle the current
+ // request, so get matching routes from the loaded page components and
+ // add them to the stack after the cache handler but just before the
+ // 404 handler, then continue the loop
+ if (this.stack[stackIdx].name === 'cache' && !pathsLoaded) {
+ // find path specific handlers
+ var hrstart = process.hrtime()
+
+ var matches = this.getMatchingRoutes(req)
+
+ var hrend = process.hrtime(hrstart)
+ debug(
+ 'getMatchingRoutes execution %ds %dms',
+ hrend[0],
+ hrend[1] / 1000000
+ )
+
+ if (!_.isEmpty(matches)) {
+ // add the matches after the cache middleware and before the final 404 handler
+ _.each(matches, match => {
+ this.stack.splice(-1, 0, match)
+ })
+ } else {
+ }
+
+ pathsLoaded = true
+ }
+
+ this.stack[stackIdx](req, res, doStack(++stackIdx))
} catch (e) {
return errStack(0)(e)
}
}
}
- var self = this
-
- var errStack = function (i) {
- return function (err) {
- self.errors[i](err, req, res, errStack(++i))
+ var errStack = stackIdx => {
+ return err => {
+ this.errors[stackIdx](err, req, res, errStack(++stackIdx))
}
}
- // add path specific handlers
- this.stack = this.stack.concat(matches)
-
- // add 404 handler
+ // push the 404 handler
this.stack.push(notFound(this, req, res))
- // start going through the middleware/routes
+ // start going through the middleware
doStack(0)()
}
@@ -274,7 +295,7 @@ Api.prototype.redirectListener = function (req, res) {
* @return {Array} handlers - the handlers that best matched the current URL
* @api private
*/
-Api.prototype._match = function (req) {
+Api.prototype.getMatchingRoutes = function (req) {
var path = url.parse(req.url).pathname
var handlers = []
diff --git a/dadi/lib/api/middleware.js b/dadi/lib/api/middleware.js
index 4525d9e1..c6af7a9d 100644
--- a/dadi/lib/api/middleware.js
+++ b/dadi/lib/api/middleware.js
@@ -34,7 +34,7 @@ var compileTrust = function (val) {
}
middleware.handleHostHeader = function () {
- return function (req, res, next) {
+ return function hostHeaderCheck (req, res, next) {
if (!req.headers.host || req.headers.host === '') {
res.statusCode = 400
return res.end()
@@ -45,7 +45,7 @@ middleware.handleHostHeader = function () {
}
middleware.setUpRequest = function () {
- return function (req, res, next) {
+ return function populateRequest (req, res, next) {
Object.defineProperty(req, 'protocol', {
get: function () {
var protocol = config.get('server.protocol')
@@ -138,7 +138,7 @@ middleware.transportSecurity = function () {
log.info('Transport security is not enabled.')
}
- return function (req, res, next) {
+ return function protocolRedirect (req, res, next) {
if (securityEnabled() && !req.secure) {
log.info('Redirecting insecure request for', req.url)
redirect(req, res, HTTPS)
diff --git a/dadi/lib/auth/index.js b/dadi/lib/auth/index.js
index 9f69a4de..2bb1dd76 100755
--- a/dadi/lib/auth/index.js
+++ b/dadi/lib/auth/index.js
@@ -9,8 +9,8 @@ var log = require('@dadi/logger')
// This attaches middleware to the passed in app instance
module.exports = function (server) {
- server.app.use(function (req, res, next) {
- log.debug(
+ server.app.use(function authentication (req, res, next) {
+ log.info(
{ module: 'auth' },
'Retrieving access token for "' + req.url + '"'
)
diff --git a/dadi/lib/cache/index.js b/dadi/lib/cache/index.js
index 61d44978..4bd0203a 100755
--- a/dadi/lib/cache/index.js
+++ b/dadi/lib/cache/index.js
@@ -151,7 +151,7 @@ Cache.prototype.init = function () {
* @param {IncomingMessage} req - the current HTTP request
* @returns {object}
*/
- this.server.app.use(function (req, res, next) {
+ this.server.app.use(function cache (req, res, next) {
var enabled = self.cachingEnabled(req)
debug('%s%s, cache enabled: %s', req.headers.host, req.url, enabled)
diff --git a/dadi/lib/controller/forceDomain.js b/dadi/lib/controller/forceDomain.js
index 83645604..0c73df9b 100644
--- a/dadi/lib/controller/forceDomain.js
+++ b/dadi/lib/controller/forceDomain.js
@@ -2,7 +2,7 @@ var _ = require('underscore')
var url = require('url')
var forceDomain = function (options) {
- return function (req, res, next) {
+ return function forceDomain (req, res, next) {
var protocol = req.headers['x-forwarded-proto'] || req.protocol || 'http'
var newRoute = domainRedirect(protocol, req.headers.host, req.url, options)
var statusCode
diff --git a/dadi/lib/controller/router.js b/dadi/lib/controller/router.js
index 0d439c49..46da3801 100644
--- a/dadi/lib/controller/router.js
+++ b/dadi/lib/controller/router.js
@@ -346,7 +346,7 @@ module.exports = function (server, options) {
server.app.Router = new Router(server, options)
// middleware which blocks requests when we're too busy
- server.app.use(function (req, res, next) {
+ server.app.use(function tooBusy (req, res, next) {
if (config.get('toobusy.enabled') && toobusy()) {
res.statusCode = 503
return res.end('HTTP Error 503 - Server Busy')
@@ -362,12 +362,12 @@ module.exports = function (server, options) {
rewriteFunction = rewrite(server.app.Router.rules)
// process rewrite rules first
- server.app.use((req, res, next) => {
+ server.app.use(function rewrites (req, res, next) {
rewriteFunction(req, res, next)
})
// load rewrites from our DS and handle them
- server.app.use((req, res, next) => {
+ server.app.use(function datasourceRewrites (req, res, next) {
debug('processing %s', req.url)
if (
@@ -448,7 +448,7 @@ module.exports = function (server, options) {
})
// handle generic url rewrite rules
- server.app.use((req, res, next) => {
+ server.app.use(function configurableRewrites (req, res, next) {
debug('processing configurable rewrites %s', req.url)
var redirect = false
diff --git a/dadi/lib/index.js b/dadi/lib/index.js
index 3f3c3624..052f1404 100755
--- a/dadi/lib/index.js
+++ b/dadi/lib/index.js
@@ -60,8 +60,6 @@ var Server = function () {
}
Server.prototype.start = function (done) {
- var self = this
-
this.readyState = 2
var options = this.loadPaths()
@@ -75,7 +73,7 @@ Server.prototype.start = function (done) {
}
// override configuration variables based on request's host header
- app.use((req, res, next) => {
+ app.use(function virtualHosts (req, res, next) {
var virtualHosts = config.get('virtualHosts')
if (_.isEmpty(virtualHosts)) {
@@ -125,9 +123,11 @@ Server.prototype.start = function (done) {
// add middleware for domain redirects
if (config.get('rewrites.forceDomain') !== '') {
+ var domain = config.get('rewrites.forceDomain')
+
app.use(
forceDomain({
- hostname: config.get('rewrites.forceDomain'),
+ hostname: domain,
port: 80
})
)
@@ -142,6 +142,9 @@ Server.prototype.start = function (done) {
app.use(compress())
}
+ // request logging middleware
+ app.use(log.requestLogger)
+
// serve static files (css,js,fonts)
if (options.mediaPath) {
app.use(serveStatic(options.mediaPath, { index: false }))
@@ -222,9 +225,6 @@ Server.prototype.start = function (done) {
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }))
- // request logging middleware
- app.use(log.requestLogger)
-
// session manager
var sessionConfig = config.get('sessions')
@@ -248,14 +248,14 @@ Server.prototype.start = function (done) {
}
// set up cache
- var cacheLayer = cache(self)
+ var cacheLayer = cache(this)
// handle routing & redirects
- router(self, options)
+ router(this, options)
if (config.get('api.enabled')) {
// authentication layer
- auth(self)
+ auth(this)
}
// initialise the cache
@@ -327,19 +327,28 @@ Server.prototype.start = function (done) {
// do something when app is closing
process.on(
'exit',
- this.exitHandler.bind(null, { server: this, cleanup: true })
+ this.exitHandler.bind(null, {
+ server: this,
+ cleanup: true
+ })
)
// catches ctrl+c event
process.on(
'SIGINT',
- this.exitHandler.bind(null, { server: this, exit: true })
+ this.exitHandler.bind(null, {
+ server: this,
+ exit: true
+ })
)
// catches uncaught exceptions
process.on(
'uncaughtException',
- this.exitHandler.bind(null, { server: this, exit: true })
+ this.exitHandler.bind(null, {
+ server: this,
+ exit: true
+ })
)
}
@@ -459,10 +468,11 @@ Server.prototype.loadApi = function (options, reload, callback) {
package: '@dadi/web',
version: version,
healthCheck: {
- baseUrl: 'http://' +
- config.get('server.host') +
- ':' +
- config.get('server.port'),
+ baseUrl:
+ 'http://' +
+ config.get('server.host') +
+ ':' +
+ config.get('server.port'),
routes: config.get('status.routes')
}
}
diff --git a/dadi/lib/providers/remote.js b/dadi/lib/providers/remote.js
index 38e542b2..05a2619f 100644
--- a/dadi/lib/providers/remote.js
+++ b/dadi/lib/providers/remote.js
@@ -123,12 +123,12 @@ RemoteProvider.prototype.load = function (requestUrl, done) {
this.options = _.extend(this.options, headers)
- this.makeRequest(done)
+ this.makeRequest(requestUrl, done)
})
})
}
-RemoteProvider.prototype.makeRequest = function (done) {
+RemoteProvider.prototype.makeRequest = function (requestUrl, done) {
debug(
'GET datasource "%s" %o',
this.datasource.schema.datasource.key,
@@ -158,9 +158,9 @@ RemoteProvider.prototype.makeRequest = function (done) {
this.options = _.extend(this.options, options)
debug('following %s redirect to %s', res.statusCode, res.headers.location)
- this.makeRequest(done)
+ this.makeRequest(requestUrl, done)
} else {
- this.handleResponse(res, done)
+ this.handleResponse(requestUrl, res, done)
}
})
diff --git a/scripts/coverage.js b/scripts/coverage.js
index e3428005..380785ec 100755
--- a/scripts/coverage.js
+++ b/scripts/coverage.js
@@ -1,46 +1,64 @@
#! /usr/bin/env node
-var fs = require('fs');
-var path = require('path');
+var fs = require("fs")
+var path = require("path")
-var coberturaBadger = require('istanbul-cobertura-badger');
+var coberturaBadger = require("istanbul-cobertura-badger")
var opts = {
badgeFileName: "coverage",
destinationDir: __dirname,
- istanbulReportFile: path.resolve(__dirname + "/../coverage", "cobertura-coverage.xml"),
+ istanbulReportFile: path.resolve(
+ __dirname + "/../coverage",
+ "cobertura-coverage.xml"
+ ),
thresholds: {
excellent: 90, // overall percent >= excellent, green badge
good: 60 // overall percent < excellent and >= good, yellow badge
// overall percent < good, red badge
}
-};
-
-//console.log(opts);
+}
// Load the badge for the report$
coberturaBadger(opts, function parsingResults(err, badgeStatus) {
if (err) {
- console.log("An error occurred: " + err.message);
+ console.log("An error occurred: " + err.message)
}
- //console.log(badgeStatus);
+ // console.log(badgeStatus);
- var readme = path.resolve(__dirname + '/../README.md');
- var badgeUrl = badgeStatus.url; // e.g. http://img.shields.io/badge/coverage-60%-yellow.svg
+ var readme = path.resolve(__dirname + "/../README.md")
+ var badgeUrl = badgeStatus.url // e.g. http://img.shields.io/badge/coverage-60%-yellow.svg
// open the README.md and add this url
- fs.readFile(readme, {encoding: 'utf-8'}, function (err, body) {
- body = body.replace(/(!\[coverage\]\()(.+?)(\))/g, function(whole, a, b, c) {
- return a + badgeUrl.replace('%', '%25') + '?style=flat-square' + c;
- });
+ fs.readFile(readme, { encoding: "utf-8" }, function(err, body) {
+ var existingCoverage = body.match(/coverage-(\d+)/)[1]
- fs.writeFile(readme, body, {encoding: 'utf-8'}, function (err) {
- if (err) console.log(err.toString());
+ body = body.replace(/(!\[coverage\]\()(.+?)(\))/g, function(
+ whole,
+ a,
+ b,
+ c
+ ) {
+ return a + badgeUrl.replace("%", "%25") + "?style=flat-square" + c
+ })
- console.log("Coverage badge successfully added to " + readme);
- });
- })
+ console.log("Existing coverage:", existingCoverage + "%")
+ console.log("New Coverage:", badgeStatus.overallPercent + "%")
+ console.log(
+ badgeStatus.overallPercent < existingCoverage
+ ? "Coverage check failed"
+ : "Coverage check passed"
+ )
+
+ if (badgeStatus.overallPercent < existingCoverage) {
+ process.exit(1)
+ }
- //console.log(badgeStatus);
-});
+ fs.writeFile(readme, body, { encoding: "utf-8" }, function(err) {
+ if (err) console.log(err.toString())
+
+ console.log("Coverage badge successfully added to " + readme)
+ })
+ })
+})
diff --git a/test/acceptance/app.js b/test/acceptance/app.js
index abe42e2c..fd506087 100644
--- a/test/acceptance/app.js
+++ b/test/acceptance/app.js
@@ -108,7 +108,6 @@ describe("Application", function() {
TestHelper.startServer(pages).then(() => {
client.get("/categories/Crime").end((err, res) => {
if (err) return done(err)
-
res.text.should.eql("