From e58943c3e620f05937656fdde032254ae3373f36 Mon Sep 17 00:00:00 2001 From: Waref Haque Date: Sun, 17 Jul 2016 16:24:49 -0400 Subject: redirect commit --- node_modules/finalhandler/index.js | 189 +++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 node_modules/finalhandler/index.js (limited to 'node_modules/finalhandler/index.js') diff --git a/node_modules/finalhandler/index.js b/node_modules/finalhandler/index.js new file mode 100644 index 0000000..884d802 --- /dev/null +++ b/node_modules/finalhandler/index.js @@ -0,0 +1,189 @@ +/*! + * finalhandler + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var debug = require('debug')('finalhandler') +var escapeHtml = require('escape-html') +var onFinished = require('on-finished') +var statuses = require('statuses') +var unpipe = require('unpipe') + +/** + * Module variables. + * @private + */ + +/* istanbul ignore next */ +var defer = typeof setImmediate === 'function' + ? setImmediate + : function (fn) { process.nextTick(fn.bind.apply(fn, arguments)) } +var isFinished = onFinished.isFinished + +/** + * Module exports. + * @public + */ + +module.exports = finalhandler + +/** + * Create a function to handle the final response. + * + * @param {Request} req + * @param {Response} res + * @param {Object} [options] + * @return {Function} + * @public + */ + +function finalhandler (req, res, options) { + var opts = options || {} + + // get environment + var env = opts.env || process.env.NODE_ENV || 'development' + + // get error callback + var onerror = opts.onerror + + return function (err) { + var headers = Object.create(null) + var status + + // ignore 404 on in-flight response + if (!err && res._header) { + debug('cannot 404 after headers sent') + return + } + + // unhandled error + if (err) { + // respect status code from error + status = getErrorStatusCode(err) || res.statusCode + + // default status code to 500 if outside valid range + if (typeof status !== 'number' || status < 400 || status > 599) { + status = 500 + } + + // respect err.headers + if (err.headers && (err.status === status || err.statusCode === status)) { + var keys = Object.keys(err.headers) + for (var i = 0; i < keys.length; i++) { + var key = keys[i] + headers[key] = err.headers[key] + } + } + + // production gets a basic error message + var msg = env === 'production' + ? statuses[status] + : err.stack || err.toString() + msg = escapeHtml(msg) + .replace(/\n/g, '
') + .replace(/\x20{2}/g, '  ') + '\n' + } else { + status = 404 + msg = 'Cannot ' + escapeHtml(req.method) + ' ' + escapeHtml(req.originalUrl || req.url) + '\n' + } + + debug('default %s', status) + + // schedule onerror callback + if (err && onerror) { + defer(onerror, err, req, res) + } + + // cannot actually respond + if (res._header) { + debug('cannot %d after headers sent', status) + req.socket.destroy() + return + } + + // send response + send(req, res, status, headers, msg) + } +} + +/** + * Get status code from Error object. + * + * @param {Error} err + * @return {number} + * @private + */ + +function getErrorStatusCode (err) { + // check err.status + if (typeof err.status === 'number' && err.status >= 400 && err.status < 600) { + return err.status + } + + // check err.statusCode + if (typeof err.statusCode === 'number' && err.statusCode >= 400 && err.statusCode < 600) { + return err.statusCode + } + + return undefined +} + +/** + * Send response. + * + * @param {IncomingMessage} req + * @param {OutgoingMessage} res + * @param {number} status + * @param {object} headers + * @param {string} body + * @private + */ + +function send (req, res, status, headers, body) { + function write () { + // response status + res.statusCode = status + res.statusMessage = statuses[status] + + // response headers + var keys = Object.keys(headers) + for (var i = 0; i < keys.length; i++) { + var key = keys[i] + res.setHeader(key, headers[key]) + } + + // security header for content sniffing + res.setHeader('X-Content-Type-Options', 'nosniff') + + // standard headers + res.setHeader('Content-Type', 'text/html; charset=utf-8') + res.setHeader('Content-Length', Buffer.byteLength(body, 'utf8')) + + if (req.method === 'HEAD') { + res.end() + return + } + + res.end(body, 'utf8') + } + + if (isFinished(req)) { + write() + return + } + + // unpipe everything from the request + unpipe(req) + + // flush the request + onFinished(req, write) + req.resume() +} -- cgit v1.2.3