Skip to content

Commit

Permalink
Merge pull request #362 from dadi/feature/debug-view
Browse files Browse the repository at this point in the history
New debug view #141
  • Loading branch information
jimlambie authored Mar 29, 2018
2 parents 0904253 + 27d3743 commit 29977b8
Show file tree
Hide file tree
Showing 38 changed files with 1,295 additions and 473 deletions.
5 changes: 5 additions & 0 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,11 @@ const conf = convict({
format: Boolean,
default: false
},
allowDebugView: {
doc: 'If true, allows appending ?debug= to the querystring to view how the page is constructed,',
format: Boolean,
default: false
},
toobusy: {
enabled: {
doc:
Expand Down
6 changes: 3 additions & 3 deletions dadi/lib/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const log = require('@dadi/logger')
const config = require(path.join(__dirname, '/../../../config'))

const Send = require(path.join(__dirname, '/../view/send'))
const errorView = require(path.join(__dirname, '/../view/errors'))
const errorView = require(path.join(__dirname, '/../debug/views')).error

/**
* Represents the main server.
Expand Down Expand Up @@ -347,7 +347,7 @@ function onError (api) {
path[0].handler(req, res)
} else {
// no user error page found for this statusCode, use default error template
Send.html(res, req, next, data.statusCode, 'text/html')(
Send.html(req, res, next, data.statusCode, 'text/html')(
null,
errorView({
headline: 'Something went wrong.',
Expand Down Expand Up @@ -377,7 +377,7 @@ function notFound (api, req, res) {
path[0].handler(req, res)
} else {
// otherwise, respond with default message
Send.html(res, req, null, 404, 'text/html')(
Send.html(req, res, null, 404, 'text/html')(
null,
errorView({
headline: 'Page not found.',
Expand Down
2 changes: 1 addition & 1 deletion dadi/lib/cache/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ module.exports = function (server) {
Cache.prototype.cachingEnabled = function (req) {
// Check it is not a json view
var query = url.parse(req.url, true).query
if (query.json && query.json !== 'false') return false
if ((query.json && query.json !== 'false') || query.debug) return false

// Disable cache for debug mode
if (config.get('debug')) return false
Expand Down
129 changes: 61 additions & 68 deletions dadi/lib/controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/
const async = require('async')
const clone = require('clone')
const crypto = require('crypto')
const debug = require('debug')('web:controller')
const getValue = require('get-value')
const path = require('path')
Expand All @@ -19,6 +18,7 @@ const Datasource = require(path.join(__dirname, '/../datasource'))
const Event = require(path.join(__dirname, '/../event'))
const Providers = require(path.join(__dirname, '/../providers'))
const View = require(path.join(__dirname, '/../view'))
const DebugView = require(path.join(__dirname, '/../debug'))
const Send = require(path.join(__dirname, '/../view/send'))
const Cache = require(path.join(__dirname, '/../cache'))

Expand All @@ -28,9 +28,6 @@ const Cache = require(path.join(__dirname, '/../cache'))
const Controller = function (page, options, meta, engine, cache) {
if (!page) throw new Error('Page instance required')

Controller.numInstances = (Controller.numInstances || 0) + 1
// console.log('Controller:', Controller.numInstances)

this.page = page

this.options = options || {}
Expand All @@ -42,6 +39,9 @@ const Controller = function (page, options, meta, engine, cache) {
this.events = []
this.preloadEvents = []

this.page.globalPostProcessors = config.get('globalPostProcessors') || []
this.page.globalEvents = config.get('globalEvents') || []

this.attachDatasources(err => {
if (err) {
log.error({ module: 'controller' }, err)
Expand Down Expand Up @@ -78,18 +78,13 @@ Controller.prototype.attachDatasources = function (done) {
*/
Controller.prototype.attachEvents = function (done) {
let event
// add global events first
config.get('globalEvents').forEach(eventName => {
event = new Event(this.page.name, eventName, this.options)
this.preloadEvents.push(event)
})

this.page.preloadEvents.forEach(eventName => {
event = new Event(this.page.name, eventName, this.options)
this.preloadEvents.push(event)
})

this.page.events.forEach(eventName => {
this.page.events.concat(this.page.globalEvents).forEach(eventName => {
event = new Event(this.page.name, eventName, this.options)
this.events.push(event)
})
Expand Down Expand Up @@ -159,15 +154,25 @@ Controller.prototype.buildInitialViewData = function (req) {
)
}

const urlData = url.parse(req.url, true)
const urlData = url.parse(
`${req.protocol}://${req.headers.host}${req.url}`,
true
)

data.query = urlData.query
data.params = {}
data.pathname = ''
data.host = req.headers.host
data.page = this.meta

if (urlData.pathname.length) data.pathname = urlData.pathname
data.page.name = this.page.name

data.url = {
protocol: urlData.protocol,
hostname: urlData.hostname,
host: urlData.host,
port: urlData.port,
path: urlData.path,
pathname: urlData.pathname,
href: urlData.href
}

// add request params (params from the path, e.g. /:make/:model)
// add query params (params from the querystring, e.g. /reviews?page=2)
Expand All @@ -178,23 +183,30 @@ Controller.prototype.buildInitialViewData = function (req) {
// add id component from the request
if (req.params.id) data.id = decodeURIComponent(req.params.id)

// allow JSON view using ?json=true
let json =
config.get('allowJsonView') &&
urlData.query.json &&
urlData.query.json.toString() === 'true'
// allow debug view using ?debug
data.debugView = false

if (
config.get('allowDebugView') &&
typeof urlData.query.debug !== 'undefined'
) {
data.debugView = urlData.query.debug || true
}

// Legacy ?json=true
if (config.get('allowDebugView') && urlData.query.json) {
data.debugView = 'json'
}

data.title = this.page.name
data.global = config.has('global') ? config.get('global') : {} // global values from config
data.debug = config.get('debug')
data.json = json || false

if (config.get('security.csrf')) {
data.csrfToken = req.csrfToken()
}

delete data.query.json
delete data.params.json
delete data.query.debug
delete data.params.debug

return data
}
Expand All @@ -206,48 +218,43 @@ Controller.prototype.process = function process (req, res, next) {
debug('%s %s', req.method, req.url)
help.timer.start(req.method.toLowerCase())

const statusCode = res.statusCode || 200
let data = this.buildInitialViewData(req)
const view = new View(req.url, this.page, data.json)

let done = data.json
? Send.json(statusCode, res, next)
: Send.html(res, req, next, statusCode, this.page.contentType)
const statusCode = res.statusCode || 200
const view = new View(req.url, this.page)

let done = Send.html(req, res, next, statusCode, this.page.contentType)

this.loadData(req, res, data, (err, data, dsResponse) => {
this.loadData(req, res, data, (err, loadedData, dsResponse) => {
if (err) {
if (err.statusCode && err.statusCode === 404) return next()
return done(err)
}

// return 404 if requiredDatasources contain no data
if (!this.requiredDataPresent(data)) {
if (!this.requiredDataPresent(loadedData)) {
return next()
}

// If we received a response back from the datasource, and
// not just the data, send the whole response back
if (dsResponse) {
if (dsResponse.statusCode === 202) {
done = Send.json(dsResponse.statusCode, res, next)
return done(null, data)
}
if (dsResponse && dsResponse.statusCode === 202) {
done = Send.json(dsResponse.statusCode, res, next)
return done(null, loadedData)
}

help.timer.stop(req.method.toLowerCase())
if (data) data.stats = help.timer.getStats()

if (data) data.version = help.getVersion()

view.setData(data)

if (data.json) {
return done(null, data)
}
view.setData(loadedData)

view.render((err, result) => {
view.render((err, result, unprocessed) => {
if (err) return next(err)
return done(null, result)

if (data.debugView) {
return DebugView(req, res, next, view, this)(null, result, unprocessed)
} else {
return done(null, result)
}
})
})
}
Expand Down Expand Up @@ -293,21 +300,20 @@ Controller.prototype.loadEventData = function (events, req, res, data, done) {
// add a random value to the data obj so we can check if an
// event has sent back the obj - in which case we assign it back
// to itself
let checkValue = crypto
.createHash('md5')
.update(new Date().toString())
.digest('hex')

data.checkValue = checkValue
data.timestamp = new Date().getTime()

event.run(req, res, data, (err, result) => {
help.timer.stop('event: ' + event.name)

if (err) return reject(err)

// if we get data back with the same checkValue property,
// if we get data back with the same timestamp property,
// reassign it to our global data object to avoid circular JSON
if (result && result.checkValue && result.checkValue === checkValue) {
if (
result &&
result.timestamp &&
result.timestamp === data.timestamp
) {
data = result
} else if (result) {
// add the result to our global data object
Expand Down Expand Up @@ -401,29 +407,16 @@ Controller.prototype.loadData = function (req, res, data, done) {
* for this datasource
* @returns err, {Object} result, {Object} dsResponse
*/
// ds.provider.load(requestUrl, function (err, result, dsResponse) {
ds.provider.load(req.url, (err, result, dsResponse) => {
if (err) return done(err)

help.timer.stop('datasource: ' + ds.name)

if (ds.provider.destroy) {
ds.provider.destroy()
}

ds.provider = null

if (dsResponse) return done(null, result, dsResponse)

// TODO: simplify this, doesn't require a try/catch
if (result) {
try {
data[ds.schema.datasource.key] = result
} catch (e) {
console.log('Provider Load Error:', ds.name, req.url)
console.log(e)
}
}
if (result) data[ds.schema.datasource.key] = result

cb()
})
Expand Down
19 changes: 12 additions & 7 deletions dadi/lib/controller/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,15 @@ Router.prototype.loadRewrites = function (options, done) {
let freshRules = []
ds.provider.load(null, (err, response) => {
if (err) {
console.log('Error loading data in Router Rewrite module')
console.log(err)
log.error(
{ module: 'router' },
'Error loading rewrite datasource "' +
ds.name +
'" in Router Rewrite module'
)
return cb(null)
}

// if (response) {
// response = JSON.parse(response)
// }

if (response.results) {
let idx = 0

Expand Down Expand Up @@ -417,7 +417,12 @@ module.exports = function (server, options) {

ds.provider.load(req.url, function (err, data) {
if (err) {
console.log('Error loading data in Router Rewrite module')
log.error(
{ module: 'router' },
'Error loading datasource "' +
ds.name +
'" in Router Rewrite module'
)
return next(err)
}

Expand Down
7 changes: 0 additions & 7 deletions dadi/lib/datasource/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ const Datasource = function (page, datasource, options) {
this.page = page
this.name = datasource
this.options = options || {}

Datasource.numInstances = (Datasource.numInstances || 0) + 1
// console.log('Datasource:', Datasource.numInstances, datasource)
}

Datasource.prototype.init = function (callback) {
Expand Down Expand Up @@ -136,10 +133,6 @@ Datasource.prototype.processRequest = function (datasource, req) {
delete datasourceParams.cache
}

// if (req.headers && req.headers.referer) {
// this.schema.datasource.referer = encodeURIComponent(req.headers.referer)
// }

if (this.page.passHeaders) {
this.requestHeaders = req.headers
}
Expand Down
14 changes: 2 additions & 12 deletions dadi/lib/datasource/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,11 @@ Preload.prototype.init = function (options) {
datasource.provider.load(null, (err, data) => {
if (err) console.log(err)

if (datasource.provider && datasource.provider.destroy) {
datasource.provider.destroy()
}

datasource.provider = null

// TODO: simplify this, doesn't require a try/catch
if (data) {
try {
const results = data
this.data[source] = results.results ? results.results : results
} catch (e) {
console.log('Preload Load Error:', datasource.name)
console.log(e)
}
const results = data
this.data[source] = results.results ? results.results : results
}
})
})
Expand Down
Loading

0 comments on commit 29977b8

Please sign in to comment.