Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / errorhandler / index.js
1 /*!
2  * errorhandler
3  * Copyright(c) 2010 Sencha Inc.
4  * Copyright(c) 2011 TJ Holowaychuk
5  * Copyright(c) 2014 Jonathan Ong
6  * Copyright(c) 2014-2015 Douglas Christopher Wilson
7  * MIT Licensed
8  */
9
10 'use strict'
11
12 /**
13  * Module dependencies.
14  * @private
15  */
16
17 var accepts = require('accepts')
18 var escapeHtml = require('escape-html');
19 var fs = require('fs');
20 var util = require('util')
21
22 /**
23  * Module variables.
24  * @private
25  */
26
27 var doubleSpaceGlobalRegExp = /  /g
28 var inspect = util.inspect
29 var newLineGlobalRegExp = /\n/g
30 var toString = Object.prototype.toString
31
32 /* istanbul ignore next */
33 var defer = typeof setImmediate === 'function'
34   ? setImmediate
35   : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
36
37 /**
38  * Error handler:
39  *
40  * Development error handler, providing stack traces
41  * and error message responses for requests accepting text, html,
42  * or json.
43  *
44  * Text:
45  *
46  *   By default, and when _text/plain_ is accepted a simple stack trace
47  *   or error message will be returned.
48  *
49  * JSON:
50  *
51  *   When _application/json_ is accepted, connect will respond with
52  *   an object in the form of `{ "error": error }`.
53  *
54  * HTML:
55  *
56  *   When accepted connect will output a nice html stack trace.
57  *
58  * @return {Function}
59  * @api public
60  */
61
62 exports = module.exports = function errorHandler(options) {
63   // get environment
64   var env = process.env.NODE_ENV || 'development'
65
66   // get options
67   var opts = options || {}
68
69   // get log option
70   var log = opts.log === undefined
71     ? env !== 'test'
72     : opts.log
73
74   if (typeof log !== 'function' && typeof log !== 'boolean') {
75     throw new TypeError('option log must be function or boolean')
76   }
77
78   // default logging using console.error
79   if (log === true) {
80     log = logerror
81   }
82
83   return function errorHandler(err, req, res, next){
84     // respect err.statusCode
85     if (err.statusCode) {
86       res.statusCode = err.statusCode
87     }
88
89     // respect err.status
90     if (err.status) {
91       res.statusCode = err.status
92     }
93
94     // default status code to 500
95     if (res.statusCode < 400) {
96       res.statusCode = 500
97     }
98
99     // log the error
100     var str = stringify(err)
101     if (log) {
102       defer(log, err, str, req, res)
103     }
104
105     // cannot actually respond
106     if (res._header) {
107       return req.socket.destroy()
108     }
109
110     // negotiate
111     var accept = accepts(req)
112     var type = accept.type('html', 'json', 'text')
113
114     // Security header for content sniffing
115     res.setHeader('X-Content-Type-Options', 'nosniff')
116
117     // html
118     if (type === 'html') {
119       fs.readFile(__dirname + '/public/style.css', 'utf8', function(e, style){
120         if (e) return next(e);
121         fs.readFile(__dirname + '/public/error.html', 'utf8', function(e, html){
122           if (e) return next(e);
123           var isInspect = !err.stack && String(err) === toString.call(err)
124           var errorHtml = !isInspect
125             ? escapeHtmlBlock(str.split('\n', 1)[0] || 'Error')
126             : 'Error'
127           var stack = !isInspect
128             ? String(str).split('\n').slice(1)
129             : [str]
130           var stackHtml = stack
131             .map(function (v) { return '<li>' + escapeHtmlBlock(v) + '</li>' })
132             .join('')
133           var body = html
134             .replace('{style}', style)
135             .replace('{stack}', stackHtml)
136             .replace('{title}', escapeHtml(exports.title))
137             .replace('{statusCode}', res.statusCode)
138             .replace(/\{error\}/g, errorHtml)
139           res.setHeader('Content-Type', 'text/html; charset=utf-8')
140           res.end(body)
141         });
142       });
143     // json
144     } else if (type === 'json') {
145       var error = { message: err.message, stack: err.stack };
146       for (var prop in err) error[prop] = err[prop];
147       var json = JSON.stringify({ error: error });
148       res.setHeader('Content-Type', 'application/json; charset=utf-8')
149       res.end(json);
150     // plain text
151     } else {
152       res.setHeader('Content-Type', 'text/plain; charset=utf-8')
153       res.end(str)
154     }
155   };
156 };
157
158 /**
159  * Template title, framework authors may override this value.
160  */
161
162 exports.title = 'Connect';
163
164 /**
165  * Escape a block of HTML, preserving whitespace.
166  * @api private
167  */
168
169 function escapeHtmlBlock(str) {
170   return escapeHtml(str)
171   .replace(doubleSpaceGlobalRegExp, ' &nbsp;')
172   .replace(newLineGlobalRegExp, '<br>')
173 }
174
175 /**
176  * Stringify a value.
177  * @api private
178  */
179
180 function stringify(val) {
181   var stack = val.stack
182
183   if (stack) {
184     return String(stack)
185   }
186
187   var str = String(val)
188
189   return str === toString.call(val)
190     ? inspect(val)
191     : str
192 }
193
194 /**
195  * Log error to console.
196  * @api private
197  */
198
199 function logerror(err, str) {
200   console.error(str)
201 }