[Pkg-javascript-commits] [node-errorhandler] 01/04: Imported Upstream version 1.1.1

Leo Iannacone l3on-guest at moszumanska.debian.org
Fri Jul 4 10:53:43 UTC 2014


This is an automated email from the git hooks/post-receive script.

l3on-guest pushed a commit to branch master
in repository node-errorhandler.

commit 2343b47bbb8a3e84d6869ecb7ee679ba6cf397ef
Author: Leo Iannacone <l3on at ubuntu.com>
Date:   Fri Jul 4 12:48:21 2014 +0200

    Imported Upstream version 1.1.1
---
 History.md   | 17 ++++++++++++
 index.js     | 77 +++++++++++++++++++++++++-------------------------
 package.json |  8 ++++--
 test/test.js | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 149 insertions(+), 44 deletions(-)

diff --git a/History.md b/History.md
index de45645..44a060a 100644
--- a/History.md
+++ b/History.md
@@ -1,3 +1,20 @@
+1.1.1 / 2014-06-20
+==================
+
+  * deps: accepts@~1.0.4
+    - use `mime-types`
+
+1.1.0 / 2014-06-16
+==================
+
+  * Display error on console formatted like `throw`
+  * Escape HTML with `escape-html` module
+  * Escape HTML in stack trace
+  * Escape HTML in title
+  * Fix up edge cases with error sent in response
+  * Set `X-Content-Type-Options: nosniff` header
+  * Use accepts for negotiation
+
 1.0.2 / 2014-06-05
 ==================
 
diff --git a/index.js b/index.js
index 739dd30..16e044f 100644
--- a/index.js
+++ b/index.js
@@ -9,16 +9,9 @@
  * Module dependencies.
  */
 
-var fs;
-try {
-  fs = require('graceful-fs');
-} catch (_) {
-  fs = require('fs');
-}
-
-// environment
-
-var env = process.env.NODE_ENV || 'development';
+var accepts = require('accepts')
+var escapeHtml = require('escape-html');
+var fs = require('fs');
 
 /**
  * Error handler:
@@ -46,33 +39,58 @@ var env = process.env.NODE_ENV || 'development';
  */
 
 exports = module.exports = function errorHandler(){
+  // get environment
+  var env = process.env.NODE_ENV || 'development'
+
   return function errorHandler(err, req, res, next){
-    if (err.status) res.statusCode = err.status;
-    if (res.statusCode < 400) res.statusCode = 500;
-    if ('test' != env) console.error(err.stack);
-    if (res._header) return;
-    var accept = req.headers.accept || '';
+    // respect err.status
+    if (err.status) {
+      res.statusCode = err.status
+    }
+
+    // default status code to 500
+    if (res.statusCode < 400) {
+      res.statusCode = 500
+    }
+
+    // write error to console
+    if (env !== 'test') {
+      console.error(err.stack || String(err))
+    }
+
+    // cannot actually respond
+    if (res._header) {
+      return req.socket.destroy()
+    }
+
+    // negotiate
+    var accept = accepts(req)
+    var type = accept.types('html', 'json', 'text')
+
+    // Security header for content sniffing
+    res.setHeader('X-Content-Type-Options', 'nosniff')
+
     // html
-    if (~accept.indexOf('html')) {
+    if (type === 'html') {
       fs.readFile(__dirname + '/public/style.css', 'utf8', function(e, style){
         if (e) return next(e);
         fs.readFile(__dirname + '/public/error.html', 'utf8', function(e, html){
           if (e) return next(e);
           var stack = (err.stack || '')
             .split('\n').slice(1)
-            .map(function(v){ return '<li>' + v + '</li>'; }).join('');
+            .map(function(v){ return '<li>' + escapeHtml(v).replace(/  /g, '  ') + '</li>'; }).join('');
             html = html
               .replace('{style}', style)
               .replace('{stack}', stack)
-              .replace('{title}', exports.title)
+              .replace('{title}', escapeHtml(exports.title))
               .replace('{statusCode}', res.statusCode)
-              .replace(/\{error\}/g, escapeHTML(err.toString().replace(/\n/g, '<br/>')));
+              .replace(/\{error\}/g, escapeHtml(String(err)).replace(/  /g, '  ').replace(/\n/g, '<br>'));
             res.setHeader('Content-Type', 'text/html; charset=utf-8');
             res.end(html);
         });
       });
     // json
-    } else if (~accept.indexOf('json')) {
+    } else if (type === 'json') {
       var error = { message: err.message, stack: err.stack };
       for (var prop in err) error[prop] = err[prop];
       var json = JSON.stringify({ error: error });
@@ -81,7 +99,7 @@ exports = module.exports = function errorHandler(){
     // plain text
     } else {
       res.setHeader('Content-Type', 'text/plain');
-      res.end(err.stack);
+      res.end(err.stack || String(err));
     }
   };
 };
@@ -91,20 +109,3 @@ exports = module.exports = function errorHandler(){
  */
 
 exports.title = 'Connect';
-
-
-/**
- * Escape the given string of `html`.
- *
- * @param {String} html
- * @return {String}
- * @api private
- */
-
-function escapeHTML(html){
-  return String(html)
-    .replace(/&(?!\w+;)/g, '&')
-    .replace(/</g, '<')
-    .replace(/>/g, '>')
-    .replace(/"/g, '"');
-};
\ No newline at end of file
diff --git a/package.json b/package.json
index 3e4dc8c..01d7098 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,18 @@
 {
   "name": "errorhandler",
   "description": "connect's default error handler page",
-  "version": "1.0.2",
+  "version": "1.1.1",
   "author": "Jonathan Ong <me at jongleberry.com> (http://jongleberry.com)",
   "license": "MIT",
   "repository": "expressjs/errorhandler",
+  "dependencies": {
+    "accepts": "~1.0.4",
+    "escape-html": "1.0.1"
+  },
   "devDependencies": {
     "connect": "3",
     "istanbul": "0.2.10",
-    "mocha": ">= 1.17.0 < 2",
+    "mocha": "~1.20.1",
     "should": "~4.0.1",
     "supertest": "~0.13.0"
   },
diff --git a/test/test.js b/test/test.js
index 53bf936..083bc95 100644
--- a/test/test.js
+++ b/test/test.js
@@ -2,10 +2,11 @@
 process.env.NODE_ENV = 'test';
 
 var connect = require('connect');
+var errorHandler = require('..')
+var http = require('http')
 var request = require('supertest');
 var should = require('should');
-var http = require('http');
-var errorHandler = require('..');
+var util = require('util')
 
 describe('errorHandler()', function () {
   var app, error, server;
@@ -23,6 +24,14 @@ describe('errorHandler()', function () {
     error = null;
   });
 
+  it('should set nosniff header', function (done) {
+    error = new Error()
+    request(server)
+    .get('/')
+    .expect('X-Content-Type-Options', 'nosniff')
+    .expect(500, done)
+  })
+
   describe('status code', function () {
     it('should set the status code to 500 if a non error status code was given', function (done) {
       error = {status: 200};
@@ -49,7 +58,7 @@ describe('errorHandler()', function () {
 
   describe('response content type', function () {
     beforeEach(function () {
-        error = new Error('');
+        error = new Error('boom!');
     });
 
     it('should return a html response when html is accepted', function (done) {
@@ -60,6 +69,8 @@ describe('errorHandler()', function () {
         if (err) throw err;
         res.headers['content-type'].should.startWith('text/html');
         res.text.should.containEql('<title>');
+        res.text.should.containEql('Error: boom!');
+        res.text.should.containEql('    at');
         done();
       });
     });
@@ -84,6 +95,7 @@ describe('errorHandler()', function () {
     it('should return a plain text response when json or html is not accepted', function (done) {
       request(server)
       .get('/')
+      .set('Accept', 'bogus')
       .end(function (err, res) {
         if (err) throw err;
         res.headers['content-type'].should.startWith('text/plain');
@@ -113,4 +125,75 @@ describe('errorHandler()', function () {
       .expect(200, done);
     });
   });
-});
+
+  describe('write error to console.error', function () {
+    var app
+    var error = null
+    var log
+    var old
+    before(function () {
+      old = console.error
+      console.error = function () {
+        log = util.format.apply(null, arguments)
+      }
+      process.env.NODE_ENV = ''
+      app = connect()
+      app.use(function (req, res, next) {
+        next(error)
+      })
+      app.use(errorHandler())
+    })
+    beforeEach(function () {
+      error = null
+      log = undefined
+    })
+    after(function () {
+      console.error = old
+      process.env.NODE_ENV = 'test'
+    })
+
+    it('should write stack', function (done) {
+      error = new Error('boom!')
+      request(app)
+      .get('/')
+      .expect(500, function (err) {
+        if (err) return done(err)
+        log.should.startWith('Error: boom!\n    at')
+        done()
+      })
+    })
+
+    it('should stringify primitive', function (done) {
+      error = 'boom!'
+      request(app)
+      .get('/')
+      .expect(500, function (err) {
+        if (err) return done(err)
+        log.should.equal('boom!')
+        done()
+      })
+    })
+
+    it('should stringify plain object', function (done) {
+      error = {}
+      request(app)
+      .get('/')
+      .expect(500, function (err) {
+        if (err) return done(err)
+        log.should.equal('[object Object]')
+        done()
+      })
+    })
+
+    it('should stringify plain object with toString', function (done) {
+      error = {toString: function () { return 'boom!' }}
+      request(app)
+      .get('/')
+      .expect(500, function (err) {
+        if (err) return done(err)
+        log.should.equal('boom!')
+        done()
+      })
+    })
+  })
+})

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-errorhandler.git



More information about the Pkg-javascript-commits mailing list