From 51a5fd6a8880da32af98326ddde5b91129b7f751 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 21 Jan 2015 00:31:30 -0500 Subject: [PATCH 001/334] build: move to pillarjs org --- Readme.md | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Readme.md b/Readme.md index 5c03b96a..41ec3e71 100644 --- a/Readme.md +++ b/Readme.md @@ -182,10 +182,10 @@ var app = http.createServer(function(req, res){ [npm-image]: https://img.shields.io/npm/v/send.svg?style=flat [npm-url]: https://npmjs.org/package/send -[travis-image]: https://img.shields.io/travis/tj/send.svg?style=flat -[travis-url]: https://travis-ci.org/tj/send -[coveralls-image]: https://img.shields.io/coveralls/tj/send.svg?style=flat -[coveralls-url]: https://coveralls.io/r/tj/send?branch=master +[travis-image]: https://img.shields.io/travis/pillarjs/send/master.svg?style=flat +[travis-url]: https://travis-ci.org/pillarjs/send +[coveralls-image]: https://img.shields.io/coveralls/pillarjs/send/master.svg?style=flat +[coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master [downloads-image]: https://img.shields.io/npm/dm/send.svg?style=flat [downloads-url]: https://npmjs.org/package/send [gittip-image]: https://img.shields.io/gittip/dougwilson.svg?style=flat diff --git a/package.json b/package.json index 24553cf2..17681e94 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "Douglas Christopher Wilson " ], "license": "MIT", - "repository": "tj/send", + "repository": "pillarjs/send", "keywords": [ "static", "file", From 5087192e9168d2d4e72424e317d4c68937f3a86e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 21 Jan 2015 00:32:18 -0500 Subject: [PATCH 002/334] docs: Gittip is now Gratipay --- Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index 41ec3e71..aa816a40 100644 --- a/Readme.md +++ b/Readme.md @@ -4,7 +4,7 @@ [![NPM Downloads][downloads-image]][downloads-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] -[![Gittip][gittip-image]][gittip-url] +[![Gratipay][gratipay-image]][gratipay-url] Send is a library for streaming files from the file system as a http response supporting partial responses (Ranges), conditional-GET negotiation, high test @@ -188,5 +188,5 @@ var app = http.createServer(function(req, res){ [coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master [downloads-image]: https://img.shields.io/npm/dm/send.svg?style=flat [downloads-url]: https://npmjs.org/package/send -[gittip-image]: https://img.shields.io/gittip/dougwilson.svg?style=flat -[gittip-url]: https://www.gittip.com/dougwilson/ +[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg?style=flat +[gratipay-url]: https://www.gratipay.com/dougwilson/ From 8d39b525e5a76213581b346171bc395c7084a157 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 20 Jan 2015 20:20:58 -0500 Subject: [PATCH 003/334] build: add AppVeyor --- .travis.yml | 2 +- Readme.md | 7 +++++-- appveyor.yml | 18 ++++++++++++++++++ package.json | 4 ++-- 4 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 appveyor.yml diff --git a/.travis.yml b/.travis.yml index 1ff243c5..c4ebdf46 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,5 +7,5 @@ matrix: allow_failures: - node_js: "0.11" fast_finish: true -script: "npm run-script test-travis" +script: "npm run-script test-ci" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/Readme.md b/Readme.md index aa816a40..c21b3dff 100644 --- a/Readme.md +++ b/Readme.md @@ -2,7 +2,8 @@ [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] -[![Build Status][travis-image]][travis-url] +[![Linux Build][travis-image]][travis-url] +[![Windows Build][appveyor-image]][appveyor-url] [![Test Coverage][coveralls-image]][coveralls-url] [![Gratipay][gratipay-image]][gratipay-url] @@ -182,8 +183,10 @@ var app = http.createServer(function(req, res){ [npm-image]: https://img.shields.io/npm/v/send.svg?style=flat [npm-url]: https://npmjs.org/package/send -[travis-image]: https://img.shields.io/travis/pillarjs/send/master.svg?style=flat +[travis-image]: https://img.shields.io/travis/pillarjs/send/master.svg?label=linux&style=flat [travis-url]: https://travis-ci.org/pillarjs/send +[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/send/master.svg?label=windows&style=flat +[appveyor-url]: https://ci.appveyor.com/project/dougwilson/send [coveralls-image]: https://img.shields.io/coveralls/pillarjs/send/master.svg?style=flat [coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master [downloads-image]: https://img.shields.io/npm/dm/send.svg?style=flat diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..c813188a --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,18 @@ +environment: + matrix: + - nodejs_version: "0.8" + - nodejs_version: "0.10" + - nodejs_version: "0.11" +matrix: + allow_failures: + - nodejs_version: "0.11" + fast_finish: true +install: + - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) + - npm install +build: off +test_script: + - node --version + - npm --version + - npm run test-ci +version: "{build}" diff --git a/package.json b/package.json index 17681e94..0ec86b2c 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ }, "scripts": { "test": "mocha --check-leaks --reporter spec --bail", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot", - "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec" + "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot" } } From d80a4d420ab7773145d8881c59a26020601ce17e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 21 Jan 2015 00:53:48 -0500 Subject: [PATCH 004/334] build: change capitalization of history/readme --- History.md => HISTORY.md | 0 Readme.md => README.md | 0 package.json | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) rename History.md => HISTORY.md (100%) rename Readme.md => README.md (100%) diff --git a/History.md b/HISTORY.md similarity index 100% rename from History.md rename to HISTORY.md diff --git a/Readme.md b/README.md similarity index 100% rename from Readme.md rename to README.md diff --git a/package.json b/package.json index 0ec86b2c..e863a55d 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,9 @@ "supertest": "~0.15.0" }, "files": [ - "History.md", + "HISTORY.md", "LICENSE", + "README.md", "index.js" ], "engines": { From 0901911d94d55bcacba831d359351e31d585ff7d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 00:06:58 -0500 Subject: [PATCH 005/334] build: use faster AppVeyor Node.js switching --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c813188a..84109649 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ matrix: - nodejs_version: "0.11" fast_finish: true install: - - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) + - ps: Install-Product node $env:nodejs_version - npm install build: off test_script: From ba325a9d123dd3478043fc36f69020004105eb71 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 00:15:30 -0500 Subject: [PATCH 006/334] docs: update badges --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c21b3dff..35860609 100644 --- a/README.md +++ b/README.md @@ -181,15 +181,15 @@ var app = http.createServer(function(req, res){ [MIT](LICENSE) -[npm-image]: https://img.shields.io/npm/v/send.svg?style=flat +[npm-image]: https://img.shields.io/npm/v/send.svg [npm-url]: https://npmjs.org/package/send -[travis-image]: https://img.shields.io/travis/pillarjs/send/master.svg?label=linux&style=flat +[travis-image]: https://img.shields.io/travis/pillarjs/send/master.svg?label=linux [travis-url]: https://travis-ci.org/pillarjs/send -[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/send/master.svg?label=windows&style=flat +[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/send/master.svg?label=windows [appveyor-url]: https://ci.appveyor.com/project/dougwilson/send -[coveralls-image]: https://img.shields.io/coveralls/pillarjs/send/master.svg?style=flat +[coveralls-image]: https://img.shields.io/coveralls/pillarjs/send/master.svg [coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master -[downloads-image]: https://img.shields.io/npm/dm/send.svg?style=flat +[downloads-image]: https://img.shields.io/npm/dm/send.svg [downloads-url]: https://npmjs.org/package/send -[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg?style=flat +[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg [gratipay-url]: https://www.gratipay.com/dougwilson/ From ea94191c37e267676be341bcbe534ce0a276d886 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 00:15:52 -0500 Subject: [PATCH 007/334] build: support Node.js 0.12 --- .travis.yml | 6 +----- appveyor.yml | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index c4ebdf46..9702e677 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,6 @@ language: node_js node_js: - "0.8" - "0.10" - - "0.11" -matrix: - allow_failures: - - node_js: "0.11" - fast_finish: true + - "0.12" script: "npm run-script test-ci" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/appveyor.yml b/appveyor.yml index 84109649..5b9869d4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,11 +2,7 @@ environment: matrix: - nodejs_version: "0.8" - nodejs_version: "0.10" - - nodejs_version: "0.11" -matrix: - allow_failures: - - nodejs_version: "0.11" - fast_finish: true + - nodejs_version: "0.12" install: - ps: Install-Product node $env:nodejs_version - npm install From a9f1ad8e88701792fbd9f9cd78041edd7ac62e3b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 00:17:01 -0500 Subject: [PATCH 008/334] build: use Travis CI container infrastructure --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9702e677..b827ee98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,5 +3,6 @@ node_js: - "0.8" - "0.10" - "0.12" +sudo: false script: "npm run-script test-ci" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" From 5bdfcae5e0a74776ecb4fbf394d718192196c35a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 16:06:02 -0500 Subject: [PATCH 009/334] Always read the stat size from the file --- HISTORY.md | 5 +++++ LICENSE | 2 +- index.js | 17 +++++++++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 697a0280..f8ce854b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Always read the stat size from the file + 0.11.1 / 2015-01-20 =================== diff --git a/LICENSE b/LICENSE index 3b87e2db..e4d595b3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ (The MIT License) Copyright (c) 2012 TJ Holowaychuk -Copyright (c) 2014 Douglas Christopher Wilson +Copyright (c) 2014-2015 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/index.js b/index.js index f63081d3..9c96852d 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,9 @@ +/*! + * send + * Copyright(c) 2012 TJ Holowaychuk + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ /** * Module dependencies. @@ -537,9 +543,6 @@ SendStream.prototype.send = function(path, stat){ if (-2 != ranges && ranges.length === 1) { debug('range %j', ranges); - options.start = offset + ranges[0].start; - options.end = offset + ranges[0].end; - // Content-Range res.statusCode = 206; res.setHeader('Content-Range', 'bytes ' @@ -548,10 +551,16 @@ SendStream.prototype.send = function(path, stat){ + ranges[0].end + '/' + len); - len = options.end - options.start + 1; + + offset += ranges[0].start; + len = ranges[0].end - ranges[0].start + 1; } } + // read options + options.start = offset; + options.end = offset + len - 1; + // content-length res.setHeader('Content-Length', len); From 61614fed9e93427aed0d2a2ab6f16769e9449c0c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 16:35:23 -0500 Subject: [PATCH 010/334] deps: mime@1.3.4 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f8ce854b..1a14843e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Always read the stat size from the file + * deps: mime@1.3.4 0.11.1 / 2015-01-20 =================== diff --git a/package.json b/package.json index e863a55d..b74d164a 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "escape-html": "1.0.1", "etag": "~1.5.1", "fresh": "0.2.4", - "mime": "1.2.11", + "mime": "1.3.4", "ms": "0.7.0", "on-finished": "~2.2.0", "range-parser": "~1.0.2" From 5c0afa976a32d3c7d3838f85aa60bda4b170b3e6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 17:11:29 -0500 Subject: [PATCH 011/334] Fix mutating passed-in options --- HISTORY.md | 1 + index.js | 66 +++++++++++++++++++++++++++++------------------------- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 1a14843e..ec8e19e4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Always read the stat size from the file + * Fix mutating passed-in `options` * deps: mime@1.3.4 0.11.1 / 2015-01-20 diff --git a/index.js b/index.js index 9c96852d..c11d073d 100644 --- a/index.js +++ b/index.js @@ -62,7 +62,7 @@ var listenerCount = EventEmitter.listenerCount * * @param {Request} req * @param {String} path - * @param {Object} options + * @param {object} [options] * @return {SendStream} * @api public */ @@ -76,53 +76,53 @@ function send(req, path, options) { * * @param {Request} req * @param {String} path - * @param {Object} options + * @param {object} [options] * @api private */ function SendStream(req, path, options) { - var self = this; - options = options || {}; - this.req = req; - this.path = path; - this.options = options; + var opts = options || {} - this._etag = options.etag !== undefined - ? Boolean(options.etag) + this.options = opts + this.path = path + this.req = req + + this._etag = opts.etag !== undefined + ? Boolean(opts.etag) : true - this._dotfiles = options.dotfiles !== undefined - ? options.dotfiles + this._dotfiles = opts.dotfiles !== undefined + ? opts.dotfiles : 'ignore' if (['allow', 'deny', 'ignore'].indexOf(this._dotfiles) === -1) { throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"') } - this._hidden = Boolean(options.hidden) + this._hidden = Boolean(opts.hidden) - if ('hidden' in options) { + if (opts.hidden !== undefined) { deprecate('hidden: use dotfiles: \'' + (this._hidden ? 'allow' : 'ignore') + '\' instead') } // legacy support - if (!('dotfiles' in options)) { + if (opts.dotfiles === undefined) { this._dotfiles = undefined } - this._extensions = options.extensions !== undefined - ? normalizeList(options.extensions) + this._extensions = opts.extensions !== undefined + ? normalizeList(opts.extensions) : [] - this._index = options.index !== undefined - ? normalizeList(options.index) + this._index = opts.index !== undefined + ? normalizeList(opts.index) : ['index.html'] - this._lastModified = options.lastModified !== undefined - ? Boolean(options.lastModified) + this._lastModified = opts.lastModified !== undefined + ? Boolean(opts.lastModified) : true - this._maxage = options.maxAge || options.maxage + this._maxage = opts.maxAge || opts.maxage this._maxage = typeof this._maxage === 'string' ? ms(this._maxage) : Number(this._maxage) @@ -130,12 +130,12 @@ function SendStream(req, path, options) { ? Math.min(Math.max(0, this._maxage), maxMaxAge) : 0 - this._root = options.root - ? resolve(options.root) + this._root = opts.root + ? resolve(opts.root) : null - if (!this._root && options.from) { - this.from(options.from); + if (!this._root && opts.from) { + this.from(opts.from) } } @@ -488,8 +488,9 @@ SendStream.prototype.pipe = function(res){ */ SendStream.prototype.send = function(path, stat){ - var options = this.options; var len = stat.size; + var options = this.options + var opts = {} var res = this.res; var req = this.req; var ranges = req.headers.range; @@ -557,9 +558,14 @@ SendStream.prototype.send = function(path, stat){ } } - // read options - options.start = offset; - options.end = offset + len - 1; + // clone options + for (var prop in options) { + opts[prop] = options[prop] + } + + // set read options + opts.start = offset + opts.end = offset + len - 1 // content-length res.setHeader('Content-Length', len); @@ -567,7 +573,7 @@ SendStream.prototype.send = function(path, stat){ // HEAD support if ('HEAD' == req.method) return res.end(); - this.stream(path, options); + this.stream(path, opts) }; /** From 98d60d9949e25d81f2863ec75fd1d1264949f1f9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 16 Feb 2015 18:06:17 -0500 Subject: [PATCH 012/334] Release 0.12.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ec8e19e4..04a8cb69 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.12.0 / 2015-02-16 +=================== * Always read the stat size from the file * Fix mutating passed-in `options` diff --git a/package.json b/package.json index b74d164a..2b3546a0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.11.1", + "version": "0.12.0", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From 410954b11bd49bb187ab0a2eb98d94e0ca05f81a Mon Sep 17 00:00:00 2001 From: Shane Osbourne Date: Tue, 17 Feb 2015 10:34:25 +0000 Subject: [PATCH 013/334] Fix regression sending zero-length files fixes #73 --- HISTORY.md | 5 +++++ index.js | 2 +- test/fixtures/empty.txt | 0 test/send.js | 7 +++++++ 4 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/empty.txt diff --git a/HISTORY.md b/HISTORY.md index 04a8cb69..a26e5e6b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix regression sending zero-length files + 0.12.0 / 2015-02-16 =================== diff --git a/index.js b/index.js index c11d073d..e424edf7 100644 --- a/index.js +++ b/index.js @@ -565,7 +565,7 @@ SendStream.prototype.send = function(path, stat){ // set read options opts.start = offset - opts.end = offset + len - 1 + opts.end = Math.max(offset, offset + len - 1) // content-length res.setHeader('Content-Length', len); diff --git a/test/fixtures/empty.txt b/test/fixtures/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/test/send.js b/test/send.js index 0ed46820..bec19ee1 100644 --- a/test/send.js +++ b/test/send.js @@ -45,6 +45,13 @@ describe('send(file).pipe(res)', function(){ .expect(200, 'tobi', done) }) + it('should stream a zero-length file', function (done) { + request(app) + .get('/empty.txt') + .expect('Content-Length', '0') + .expect(200, '', done) + }) + it('should decode the given path as a URI', function(done){ request(app) .get('/some%20thing.txt') From 700757e7aa065b58fb101bd149bedb8239fac228 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 17 Feb 2015 12:32:41 -0500 Subject: [PATCH 014/334] Release 0.12.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index a26e5e6b..b3bf34ea 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.12.1 / 2015-02-17 +=================== * Fix regression sending zero-length files diff --git a/package.json b/package.json index 2b3546a0..277cdf87 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.12.0", + "version": "0.12.1", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From 1da41cb4e98c9cae69fae8f811542cae34cbc46a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Mar 2015 00:29:00 -0400 Subject: [PATCH 015/334] deps: istanbul@0.3.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 277cdf87..abb7f2dc 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "after": "0.8.1", - "istanbul": "0.3.5", + "istanbul": "0.3.7", "mocha": "~2.1.0", "supertest": "~0.15.0" }, From c7738c8aa63e49f2456fa5b3e95f18f87a1abf0a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Mar 2015 00:30:10 -0400 Subject: [PATCH 016/334] deps: debug@~2.1.3 --- HISTORY.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b3bf34ea..419a9b14 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,10 @@ +unreleased +========== + + * deps: debug@~2.1.3 + - Fix high intensity foreground color for bold + - deps: ms@0.7.0 + 0.12.1 / 2015-02-17 =================== diff --git a/package.json b/package.json index abb7f2dc..87d9f23d 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "server" ], "dependencies": { - "debug": "~2.1.1", + "debug": "~2.1.3", "depd": "~1.0.0", "destroy": "1.0.3", "escape-html": "1.0.1", From 573600e788443e6fffb7b81b780d65366ca4fb06 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Mar 2015 00:30:43 -0400 Subject: [PATCH 017/334] deps: mocha@~2.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 87d9f23d..ab6671df 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "devDependencies": { "after": "0.8.1", "istanbul": "0.3.7", - "mocha": "~2.1.0", + "mocha": "~2.2.1", "supertest": "~0.15.0" }, "files": [ From 3d08dd4f5fecf1c0942a688e3280ab1cc3ff417c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Mar 2015 00:31:46 -0400 Subject: [PATCH 018/334] build: support io.js 1.x --- .travis.yml | 2 ++ appveyor.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index b827ee98..04d85978 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,8 @@ node_js: - "0.8" - "0.10" - "0.12" + - "1.0" + - "1.5" sudo: false script: "npm run-script test-ci" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/appveyor.yml b/appveyor.yml index 5b9869d4..86e7df97 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,6 +3,8 @@ environment: - nodejs_version: "0.8" - nodejs_version: "0.10" - nodejs_version: "0.12" + - nodejs_version: "1.0" + - nodejs_version: "1.5" install: - ps: Install-Product node $env:nodejs_version - npm install From be0daf3084fdbbf266c1e5ea9ade94116229d5b3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Mar 2015 01:02:04 -0400 Subject: [PATCH 019/334] Throw errors early for invalid extensions or index options closes #75 --- HISTORY.md | 1 + index.js | 21 +++++++++++++++------ test/send.js | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 419a9b14..dde1c73d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Throw errors early for invalid `extensions` or `index` options * deps: debug@~2.1.3 - Fix high intensity foreground color for bold - deps: ms@0.7.0 diff --git a/index.js b/index.js index e424edf7..594ccc16 100644 --- a/index.js +++ b/index.js @@ -111,11 +111,11 @@ function SendStream(req, path, options) { } this._extensions = opts.extensions !== undefined - ? normalizeList(opts.extensions) + ? normalizeList(opts.extensions, 'extensions option') : [] this._index = opts.index !== undefined - ? normalizeList(opts.index) + ? normalizeList(opts.index, 'index option') : ['index.html'] this._lastModified = opts.lastModified !== undefined @@ -186,7 +186,7 @@ SendStream.prototype.hidden = deprecate.function(function hidden(val) { */ SendStream.prototype.index = deprecate.function(function index(paths) { - var index = !paths ? [] : normalizeList(paths); + var index = !paths ? [] : normalizeList(paths, 'paths argument'); debug('index %o', paths); this._index = index; return this; @@ -780,9 +780,18 @@ function decode(path) { * Normalize the index option into an array. * * @param {boolean|string|array} val - * @api private + * @param {string} name + * @private */ -function normalizeList(val){ - return [].concat(val || []) +function normalizeList(val, name) { + var list = [].concat(val || []) + + for (var i = 0; i < list.length; i++) { + if (typeof list[i] !== 'string') { + throw new TypeError(name + ' must be array of strings or false') + } + } + + return list } diff --git a/test/send.js b/test/send.js index bec19ee1..8ec3212b 100644 --- a/test/send.js +++ b/test/send.js @@ -732,6 +732,22 @@ describe('send(file, options)', function(){ }) describe('extensions', function () { + it('should reject numbers', function (done) { + var server = createServer({extensions: 42, root: fixtures}) + + request(server) + .get('/pets/') + .expect(500, /TypeError: extensions option/, done); + }) + + it('should reject true', function (done) { + var server = createServer({extensions: true, root: fixtures}) + + request(server) + .get('/pets/') + .expect(500, /TypeError: extensions option/, done); + }) + it('should be not be enabled by default', function (done) { var server = createServer({root: fixtures}); @@ -1025,6 +1041,22 @@ describe('send(file, options)', function(){ }) describe('index', function(){ + it('should reject numbers', function (done) { + var server = createServer({root: fixtures, index: 42}); + + request(server) + .get('/pets/') + .expect(500, /TypeError: index option/, done); + }) + + it('should reject true', function (done) { + var server = createServer({root: fixtures, index: true}); + + request(server) + .get('/pets/') + .expect(500, /TypeError: index option/, done); + }) + it('should default to index.html', function(done){ request(app) .get('/pets/') @@ -1222,7 +1254,7 @@ function createServer(opts) { send(req, req.url, opts).pipe(res) } catch (err) { res.statusCode = 500 - res.end(err.message) + res.end(String(err)) } }) } From c9a4bf66fa7add5976b2fdbbf3ea20d7f83673f8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 14 Mar 2015 01:18:16 -0400 Subject: [PATCH 020/334] Release 0.12.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index dde1c73d..1f20361d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.12.2 / 2015-03-13 +=================== * Throw errors early for invalid `extensions` or `index` options * deps: debug@~2.1.3 diff --git a/package.json b/package.json index ab6671df..43efe912 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.12.1", + "version": "0.12.2", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From 811eb315714e5e89f9935cb533a75d87a9722685 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 12 May 2015 23:43:42 -0400 Subject: [PATCH 021/334] build: io.js@1.8 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 04d85978..26d205a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ node_js: - "0.10" - "0.12" - "1.0" - - "1.5" + - "1.8" sudo: false script: "npm run-script test-ci" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/appveyor.yml b/appveyor.yml index 86e7df97..8b068c40 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,7 +4,7 @@ environment: - nodejs_version: "0.10" - nodejs_version: "0.12" - nodejs_version: "1.0" - - nodejs_version: "1.5" + - nodejs_version: "1.8" install: - ps: Install-Product node $env:nodejs_version - npm install From e5de04bfddd6f40246f7914c3648fae551ffdd91 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 12 May 2015 23:43:58 -0400 Subject: [PATCH 022/334] build: support io.js 2.x --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 26d205a9..22c6d032 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ node_js: - "0.12" - "1.0" - "1.8" + - "2.0" sudo: false script: "npm run-script test-ci" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/appveyor.yml b/appveyor.yml index 8b068c40..a114cd94 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,7 @@ environment: - nodejs_version: "0.12" - nodejs_version: "1.0" - nodejs_version: "1.8" + - nodejs_version: "2.0" install: - ps: Install-Product node $env:nodejs_version - npm install From c8735a572726caeea69a14a3646264f8e51ff4d7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 13 May 2015 01:05:04 -0400 Subject: [PATCH 023/334] deps: istanbul@0.3.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 43efe912..82861bb2 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "after": "0.8.1", - "istanbul": "0.3.7", + "istanbul": "0.3.9", "mocha": "~2.2.1", "supertest": "~0.15.0" }, From 6b8ed1c3c6ba3b83746bb939646cf39597a47672 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 13 May 2015 01:17:35 -0400 Subject: [PATCH 024/334] deps: debug@~2.2.0 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1f20361d..a2857a4d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: debug@~2.2.0 + - deps: ms@0.7.1 + 0.12.2 / 2015-03-13 =================== diff --git a/package.json b/package.json index 82861bb2..c7cd611b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "server" ], "dependencies": { - "debug": "~2.1.3", + "debug": "~2.2.0", "depd": "~1.0.0", "destroy": "1.0.3", "escape-html": "1.0.1", From 0a1f37ca41786943285cd36e64767cd462599778 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 13 May 2015 01:18:20 -0400 Subject: [PATCH 025/334] deps: ms@0.7.1 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index a2857a4d..cd3f68a9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,8 @@ unreleased * deps: debug@~2.2.0 - deps: ms@0.7.1 + * deps: ms@0.7.1 + - Prevent extraordinarily long inputs 0.12.2 / 2015-03-13 =================== diff --git a/package.json b/package.json index c7cd611b..3db090a4 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "etag": "~1.5.1", "fresh": "0.2.4", "mime": "1.3.4", - "ms": "0.7.0", + "ms": "0.7.1", "on-finished": "~2.2.0", "range-parser": "~1.0.2" }, From ad6bd605e26da28bf7491c1456b7f360897f0d28 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 13 May 2015 01:19:23 -0400 Subject: [PATCH 026/334] deps: depd@~1.0.1 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index cd3f68a9..fb1861d7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,7 @@ unreleased * deps: debug@~2.2.0 - deps: ms@0.7.1 + * deps: depd@~1.0.1 * deps: ms@0.7.1 - Prevent extraordinarily long inputs diff --git a/package.json b/package.json index 3db090a4..007d1fe2 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ ], "dependencies": { "debug": "~2.2.0", - "depd": "~1.0.0", + "depd": "~1.0.1", "destroy": "1.0.3", "escape-html": "1.0.1", "etag": "~1.5.1", From 7e76706cb1cd0934d0d1bbaf8197843a308d7507 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 13 May 2015 01:19:54 -0400 Subject: [PATCH 027/334] deps: on-finished@~2.2.1 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index fb1861d7..898f5939 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,6 +6,7 @@ unreleased * deps: depd@~1.0.1 * deps: ms@0.7.1 - Prevent extraordinarily long inputs + * deps: on-finished@~2.2.1 0.12.2 / 2015-03-13 =================== diff --git a/package.json b/package.json index 007d1fe2..c79154e3 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "fresh": "0.2.4", "mime": "1.3.4", "ms": "0.7.1", - "on-finished": "~2.2.0", + "on-finished": "~2.2.1", "range-parser": "~1.0.2" }, "devDependencies": { From 5f24023b5457763811aa7eeb49975953cd9bb32f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 13 May 2015 01:20:28 -0400 Subject: [PATCH 028/334] deps: mocha@2.2.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c79154e3..e5c6822b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "devDependencies": { "after": "0.8.1", "istanbul": "0.3.9", - "mocha": "~2.2.1", + "mocha": "2.2.4", "supertest": "~0.15.0" }, "files": [ From 413685d5c531d3ff6dc1dd08b69149e2f32274ad Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 13 May 2015 01:21:32 -0400 Subject: [PATCH 029/334] deps: etag@~1.6.0 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 898f5939..6318f35a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,6 +4,9 @@ unreleased * deps: debug@~2.2.0 - deps: ms@0.7.1 * deps: depd@~1.0.1 + * deps: etag@~1.6.0 + - Improve support for JXcore + - Support "fake" stats objects in environments without `fs` * deps: ms@0.7.1 - Prevent extraordinarily long inputs * deps: on-finished@~2.2.1 diff --git a/package.json b/package.json index e5c6822b..aa4d9b21 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "depd": "~1.0.1", "destroy": "1.0.3", "escape-html": "1.0.1", - "etag": "~1.5.1", + "etag": "~1.6.0", "fresh": "0.2.4", "mime": "1.3.4", "ms": "0.7.1", From db460d914de7114d267a55e2a2d60f869c8ddd33 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 13 May 2015 11:04:53 -0400 Subject: [PATCH 030/334] Release 0.12.3 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6318f35a..3871eedf 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.12.3 / 2015-05-13 +=================== * deps: debug@~2.2.0 - deps: ms@0.7.1 diff --git a/package.json b/package.json index aa4d9b21..5f6c9013 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.12.2", + "version": "0.12.3", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From 799dbba6e0b83d88d63626a0b9762481d41126c9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 01:22:41 -0400 Subject: [PATCH 031/334] build: io.js@2.1 --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 22c6d032..0500839c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ node_js: - "1.0" - "1.8" - "2.0" + - "2.1" sudo: false script: "npm run-script test-ci" after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/appveyor.yml b/appveyor.yml index a114cd94..6a102c94 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,6 +6,7 @@ environment: - nodejs_version: "1.0" - nodejs_version: "1.8" - nodejs_version: "2.0" + - nodejs_version: "2.1" install: - ps: Install-Product node $env:nodejs_version - npm install From 38cfc5416231a954c9c260a775c8f0857c48bd61 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 01:26:24 -0400 Subject: [PATCH 032/334] build: supertest@1.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f6c9013..03000852 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "after": "0.8.1", "istanbul": "0.3.9", "mocha": "2.2.4", - "supertest": "~0.15.0" + "supertest": "1.0.1" }, "files": [ "HISTORY.md", From 03a911f1560540a4937e3347e4af578b4001583f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 01:26:53 -0400 Subject: [PATCH 033/334] build: mocha@2.2.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03000852..e0844813 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "devDependencies": { "after": "0.8.1", "istanbul": "0.3.9", - "mocha": "2.2.4", + "mocha": "2.2.5", "supertest": "1.0.1" }, "files": [ From 2598ededb9fa68b863a8ded325a89c10ba651a1a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 01:27:29 -0400 Subject: [PATCH 034/334] deps: escape-html@1.0.2 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 3871eedf..d7d361be 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: escape-html@1.0.2 + 0.12.3 / 2015-05-13 =================== diff --git a/package.json b/package.json index e0844813..712c3eda 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "debug": "~2.2.0", "depd": "~1.0.1", "destroy": "1.0.3", - "escape-html": "1.0.1", + "escape-html": "1.0.2", "etag": "~1.6.0", "fresh": "0.2.4", "mime": "1.3.4", From c75683d9b44d35ad338336ab78f163494fc4ed33 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 01:29:21 -0400 Subject: [PATCH 035/334] deps: etag@~1.7.0 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index d7d361be..da86627f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,8 @@ unreleased ========== * deps: escape-html@1.0.2 + * deps: etag@~1.7.0 + - Improve stat performance by removing hashing 0.12.3 / 2015-05-13 =================== diff --git a/package.json b/package.json index 712c3eda..b7c9f603 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "depd": "~1.0.1", "destroy": "1.0.3", "escape-html": "1.0.2", - "etag": "~1.6.0", + "etag": "~1.7.0", "fresh": "0.2.4", "mime": "1.3.4", "ms": "0.7.1", From 68aa6178e0e1869c02b66525cfb48aa36d648e68 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 01:30:55 -0400 Subject: [PATCH 036/334] perf: enable strict mode --- HISTORY.md | 1 + index.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index da86627f..f67a8598 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,6 +4,7 @@ unreleased * deps: escape-html@1.0.2 * deps: etag@~1.7.0 - Improve stat performance by removing hashing + * perf: enable strict mode 0.12.3 / 2015-05-13 =================== diff --git a/index.js b/index.js index 594ccc16..37d67079 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,8 @@ * MIT Licensed */ +'use strict' + /** * Module dependencies. */ From 9217b665ef416d83163432214b195b51ed49e597 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 01:32:40 -0400 Subject: [PATCH 037/334] deps: fresh@0.3.0 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f67a8598..abdf4225 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,6 +4,8 @@ unreleased * deps: escape-html@1.0.2 * deps: etag@~1.7.0 - Improve stat performance by removing hashing + * deps: fresh@0.3.0 + - Add weak `ETag` matching support * perf: enable strict mode 0.12.3 / 2015-05-13 diff --git a/package.json b/package.json index b7c9f603..e80d9c5d 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "destroy": "1.0.3", "escape-html": "1.0.2", "etag": "~1.7.0", - "fresh": "0.2.4", + "fresh": "0.3.0", "mime": "1.3.4", "ms": "0.7.1", "on-finished": "~2.2.1", From b1d49568d66c0d03c540da0cd7eaaa786d22a080 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 01:33:27 -0400 Subject: [PATCH 038/334] deps: on-finished@~2.3.0 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index abdf4225..e63333b5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,6 +6,10 @@ unreleased - Improve stat performance by removing hashing * deps: fresh@0.3.0 - Add weak `ETag` matching support + * deps: on-finished@~2.3.0 + - Add defined behavior for HTTP `CONNECT` requests + - Add defined behavior for HTTP `Upgrade` requests + - deps: ee-first@1.1.1 * perf: enable strict mode 0.12.3 / 2015-05-13 diff --git a/package.json b/package.json index e80d9c5d..f09f91ed 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "fresh": "0.3.0", "mime": "1.3.4", "ms": "0.7.1", - "on-finished": "~2.2.1", + "on-finished": "~2.3.0", "range-parser": "~1.0.2" }, "devDependencies": { From 04cfea9764a0f38ef6e2aa56e5845eb949e90534 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 15 Jun 2015 21:01:31 -0400 Subject: [PATCH 039/334] Allow Node.js HTTP server to set Date response header --- HISTORY.md | 1 + index.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index e63333b5..39a01f97 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Allow Node.js HTTP server to set `Date` response header * deps: escape-html@1.0.2 * deps: etag@~1.7.0 - Improve stat performance by removing hashing diff --git a/index.js b/index.js index 37d67079..bcea5cc1 100644 --- a/index.js +++ b/index.js @@ -728,7 +728,6 @@ SendStream.prototype.setHeader = function setHeader(path, stat){ this.emit('headers', res, path, stat); if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes'); - if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString()); if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + Math.floor(this._maxage / 1000)); if (this._lastModified && !res.getHeader('Last-Modified')) { From 8703cf41a7a0546620266c07956561871d4e9932 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 Jun 2015 01:08:16 -0400 Subject: [PATCH 040/334] Use statuses instead of http module for status messages --- HISTORY.md | 1 + index.js | 14 ++++++++------ package.json | 3 ++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 39a01f97..d56da277 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Allow Node.js HTTP server to set `Date` response header + * Use `statuses` instead of `http` module for status messages * deps: escape-html@1.0.2 * deps: etag@~1.7.0 - Improve stat performance by removing hashing diff --git a/index.js b/index.js index bcea5cc1..c9ba39d8 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,7 @@ /** * Module dependencies. + * @private */ var debug = require('debug')('send') @@ -20,7 +21,6 @@ var escapeHtml = require('escape-html') , mime = require('mime') , fresh = require('fresh') , path = require('path') - , http = require('http') , fs = require('fs') , normalize = path.normalize , join = path.join @@ -28,6 +28,7 @@ var etag = require('etag') var EventEmitter = require('events').EventEmitter; var ms = require('ms'); var onFinished = require('on-finished') +var statuses = require('statuses') /** * Variables. @@ -236,15 +237,16 @@ SendStream.prototype.maxage = deprecate.function(function maxage(maxAge) { /** * Emit error with `status`. * - * @param {Number} status - * @api private + * @param {number} status + * @param {Error} [error] + * @private */ -SendStream.prototype.error = function(status, err){ +SendStream.prototype.error = function error(status, error) { var res = this.res; - var msg = http.STATUS_CODES[status]; + var msg = statuses[status]; - err = err || new Error(msg); + var err = error || new Error(msg); err.status = status; // emit if listeners instead of responding diff --git a/package.json b/package.json index f09f91ed..a46f4ff4 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "mime": "1.3.4", "ms": "0.7.1", "on-finished": "~2.3.0", - "range-parser": "~1.0.2" + "range-parser": "~1.0.2", + "statuses": "~1.2.1" }, "devDependencies": { "after": "0.8.1", From 67197b5a9bfc1d29e190f523ffc2c6c9d2e3e53f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 Jun 2015 10:21:40 -0400 Subject: [PATCH 041/334] Use http-errors for standard emitted errors --- HISTORY.md | 1 + index.js | 22 +++++++++++----------- package.json | 1 + test/send.js | 12 ++++++++++++ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d56da277..b5b95384 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Allow Node.js HTTP server to set `Date` response header + * Use `http-errors` for standard emitted errors * Use `statuses` instead of `http` module for status messages * deps: escape-html@1.0.2 * deps: etag@~1.7.0 diff --git a/index.js b/index.js index c9ba39d8..06b60880 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,7 @@ * @private */ +var createError = require('http-errors') var debug = require('debug')('send') var deprecate = require('depd')('send') var destroy = require('destroy') @@ -243,23 +244,22 @@ SendStream.prototype.maxage = deprecate.function(function maxage(maxAge) { */ SendStream.prototype.error = function error(status, error) { - var res = this.res; - var msg = statuses[status]; - - var err = error || new Error(msg); - err.status = status; - // emit if listeners instead of responding if (listenerCount(this, 'error') !== 0) { - return this.emit('error', err); + return this.emit('error', createError(error, status, { + expose: false + })) } + var res = this.res + var msg = statuses[status] + // wipe all existing headers - res._headers = undefined; + res._headers = undefined - res.statusCode = err.status; - res.end(msg); -}; + res.statusCode = status + res.end(msg) +} /** * Check if the pathname ends with "/". diff --git a/package.json b/package.json index a46f4ff4..68ecc1ae 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "escape-html": "1.0.2", "etag": "~1.7.0", "fresh": "0.3.0", + "http-errors": "~1.3.1", "mime": "1.3.4", "ms": "0.7.1", "on-finished": "~2.3.0", diff --git a/test/send.js b/test/send.js index 8ec3212b..130b0c5f 100644 --- a/test/send.js +++ b/test/send.js @@ -133,6 +133,18 @@ describe('send(file).pipe(res)', function(){ .expect(404, 'Not Found', done) }) + it('should emit ENOENT if the file does not exist', function (done) { + var app = http.createServer(function (req, res) { + send(req, req.url, {root: fixtures}) + .on('error', function (err) { res.end(err.statusCode + ' ' + err.code) }) + .pipe(res) + }) + + request(app) + .get('/meow') + .expect(200, '404 ENOENT', done) + }) + it('should 301 if the directory exists', function(done){ request(app) .get('/pets') From ef505e165efb564809fe62c45345f284a6dd9f52 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 Jun 2015 11:39:46 -0400 Subject: [PATCH 042/334] Send appropriate headers on default error response --- HISTORY.md | 1 + index.js | 6 +++++- test/send.js | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b5b95384..17595da5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Allow Node.js HTTP server to set `Date` response header + * Send appropriate headers on default error response * Use `http-errors` for standard emitted errors * Use `statuses` instead of `http` module for status messages * deps: escape-html@1.0.2 diff --git a/index.js b/index.js index 06b60880..a8686580 100644 --- a/index.js +++ b/index.js @@ -255,9 +255,13 @@ SendStream.prototype.error = function error(status, error) { var msg = statuses[status] // wipe all existing headers - res._headers = undefined + res._headers = null + // send basic response res.statusCode = status + res.setHeader('Content-Type', 'text/plain; charset=UTF-8') + res.setHeader('Content-Length', Buffer.byteLength(msg)) + res.setHeader('X-Content-Type-Options', 'nosniff') res.end(msg) } diff --git a/test/send.js b/test/send.js index 130b0c5f..6ad9254e 100644 --- a/test/send.js +++ b/test/send.js @@ -191,6 +191,7 @@ describe('send(file).pipe(res)', function(){ request(app) .get('/name.txt') + .expect('Content-Type', /plain/) .expect(404, done); }) From 20659ac72b17ee9463ba9a48a5063d437d83370a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 Jun 2015 19:29:34 -0400 Subject: [PATCH 043/334] perf: remove unnecessary array allocations --- HISTORY.md | 1 + index.js | 43 +++++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 17595da5..4e1badf4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -15,6 +15,7 @@ unreleased - Add defined behavior for HTTP `Upgrade` requests - deps: ee-first@1.1.1 * perf: enable strict mode + * perf: remove unnecessary array allocations 0.12.3 / 2015-05-13 =================== diff --git a/index.js b/index.js index a8686580..eb41fcb4 100644 --- a/index.js +++ b/index.js @@ -42,16 +42,12 @@ var toString = Object.prototype.toString var upPathRegexp = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/ /** - * Expose `send`. + * Module exports. + * @public */ -exports = module.exports = send; - -/** - * Expose mime module. - */ - -exports.mime = mime; +module.exports = send +module.exports.mime = mime /** * Shim EventEmitter.listenerCount for node.js < 0.10 @@ -64,11 +60,11 @@ var listenerCount = EventEmitter.listenerCount /** * Return a `SendStream` for `req` and `path`. * - * @param {Request} req - * @param {String} path + * @param {object} req + * @param {string} path * @param {object} [options] * @return {SendStream} - * @api public + * @public */ function send(req, path, options) { @@ -81,7 +77,7 @@ function send(req, path, options) { * @param {Request} req * @param {String} path * @param {object} [options] - * @api private + * @private */ function SendStream(req, path, options) { @@ -99,7 +95,7 @@ function SendStream(req, path, options) { ? opts.dotfiles : 'ignore' - if (['allow', 'deny', 'ignore'].indexOf(this._dotfiles) === -1) { + if (this._dotfiles !== 'ignore' && this._dotfiles !== 'allow' && this._dotfiles !== 'deny') { throw new TypeError('dotfiles option must be "allow", "deny", or "ignore"') } @@ -345,15 +341,22 @@ SendStream.prototype.isCachable = function(){ /** * Handle stat() error. * - * @param {Error} err - * @api private + * @param {Error} error + * @private */ -SendStream.prototype.onStatError = function(err){ - var notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR']; - if (~notfound.indexOf(err.code)) return this.error(404, err); - this.error(500, err); -}; +SendStream.prototype.onStatError = function onStatError(error) { + switch (error.code) { + case 'ENAMETOOLONG': + case 'ENOENT': + case 'ENOTDIR': + this.error(404, error) + break + default: + this.error(500, error) + break + } +} /** * Check if the cache is fresh. From a6d910e0def898e245ae0dd530a7af2410787470 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 Jun 2015 19:46:18 -0400 Subject: [PATCH 044/334] Fix incorrectly removing some headers on 304 response --- HISTORY.md | 1 + index.js | 19 +++++++++++-------- test/send.js | 32 ++++++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 4e1badf4..706566ed 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Allow Node.js HTTP server to set `Date` response header + * Fix incorrectly removing some headers on 304 response * Send appropriate headers on default error response * Use `http-errors` for standard emitted errors * Use `statuses` instead of `http` module for status messages diff --git a/index.js b/index.js index eb41fcb4..a60ce841 100644 --- a/index.js +++ b/index.js @@ -287,17 +287,20 @@ SendStream.prototype.isConditionalGET = function(){ /** * Strip content-* header fields. * - * @api private + * @private */ -SendStream.prototype.removeContentHeaderFields = function(){ - var res = this.res; - Object.keys(res._headers).forEach(function(field){ - if (0 == field.indexOf('content')) { - res.removeHeader(field); +SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields() { + var res = this.res + var headers = Object.keys(res._headers || {}) + + for (var i = 0; i < headers.length; i++) { + var header = headers[i] + if (header.substr(0, 8) === 'content-') { + res.removeHeader(header) } - }); -}; + } +} /** * Respond with 304 not modified. diff --git a/test/send.js b/test/send.js index 6ad9254e..4c7b382c 100644 --- a/test/send.js +++ b/test/send.js @@ -348,11 +348,7 @@ describe('send(file).pipe(res)', function(){ describe('when no "error" listeners are present', function(){ it('should respond to errors directly', function(done){ - var app = http.createServer(function(req, res){ - send(req, 'test/fixtures' + req.url).pipe(res); - }); - - request(app) + request(createServer({root: fixtures})) .get('/foobar') .expect(404, 'Not Found', done) }) @@ -367,8 +363,6 @@ describe('send(file).pipe(res)', function(){ request(app) .get('/name.txt') .set('If-None-Match', res.headers.etag) - .expect(shouldNotHaveHeader('Content-Length')) - .expect(shouldNotHaveHeader('Content-Type')) .expect(304, done) }) }) @@ -384,6 +378,27 @@ describe('send(file).pipe(res)', function(){ .expect(200, 'tobi', done) }) }) + + it('should remove Content headers', function (done) { + var app = createServer({root: fixtures}, function (req, res) { + res.setHeader('Content-Language', 'en-US') + res.setHeader('Contents', 'foo') + }) + + request(app) + .get('/name.txt') + .expect(200, function (err, res) { + if (err) return done(err) + request(app) + .get('/name.txt') + .set('If-None-Match', res.headers.etag) + .expect(shouldNotHaveHeader('Content-Language')) + .expect(shouldNotHaveHeader('Content-Length')) + .expect(shouldNotHaveHeader('Content-Type')) + .expect('Contents', 'foo') + .expect(304, done) + }) + }) }) describe('with Range request', function(){ @@ -1261,9 +1276,10 @@ describe('send(file, options)', function(){ }) }) -function createServer(opts) { +function createServer(opts, fn) { return http.createServer(function onRequest(req, res) { try { + fn && fn(req, res) send(req, req.url, opts).pipe(res) } catch (err) { res.statusCode = 500 From aefec8ea2d8583eccb764eda65b40256e38a4afd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 Jun 2015 20:37:50 -0400 Subject: [PATCH 045/334] Fix incorrectly removing Content-Location on 304 response --- HISTORY.md | 2 +- index.js | 2 +- test/send.js | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 706566ed..6241221d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,7 +2,7 @@ unreleased ========== * Allow Node.js HTTP server to set `Date` response header - * Fix incorrectly removing some headers on 304 response + * Fix incorrectly removing `Content-Location` on 304 response * Send appropriate headers on default error response * Use `http-errors` for standard emitted errors * Use `statuses` instead of `http` module for status messages diff --git a/index.js b/index.js index a60ce841..386c4b00 100644 --- a/index.js +++ b/index.js @@ -296,7 +296,7 @@ SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFie for (var i = 0; i < headers.length; i++) { var header = headers[i] - if (header.substr(0, 8) === 'content-') { + if (header.substr(0, 8) === 'content-' && header !== 'content-location') { res.removeHeader(header) } } diff --git a/test/send.js b/test/send.js index 4c7b382c..8d1691f6 100644 --- a/test/send.js +++ b/test/send.js @@ -382,6 +382,7 @@ describe('send(file).pipe(res)', function(){ it('should remove Content headers', function (done) { var app = createServer({root: fixtures}, function (req, res) { res.setHeader('Content-Language', 'en-US') + res.setHeader('Content-Location', 'http://localhost/name.txt') res.setHeader('Contents', 'foo') }) @@ -395,6 +396,7 @@ describe('send(file).pipe(res)', function(){ .expect(shouldNotHaveHeader('Content-Language')) .expect(shouldNotHaveHeader('Content-Length')) .expect(shouldNotHaveHeader('Content-Type')) + .expect('Content-Location', 'http://localhost/name.txt') .expect('Contents', 'foo') .expect(304, done) }) From 445ad274b4f6fcf90e4c6cbe0deb16fc81094867 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 Jun 2015 20:48:45 -0400 Subject: [PATCH 046/334] Improve the default redirect response headers --- HISTORY.md | 1 + index.js | 36 +++++++++++++++++++++++------------- test/send.js | 2 +- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6241221d..0fa76d7c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,7 @@ unreleased * Allow Node.js HTTP server to set `Date` response header * Fix incorrectly removing `Content-Location` on 304 response + * Improve the default redirect response headers * Send appropriate headers on default error response * Use `http-errors` for standard emitted errors * Use `statuses` instead of `http` module for status messages diff --git a/index.js b/index.js index 386c4b00..3510989e 100644 --- a/index.js +++ b/index.js @@ -390,25 +390,35 @@ SendStream.prototype.isRangeFresh = function isRangeFresh(){ }; /** - * Redirect to `path`. + * Redirect to path. * - * @param {String} path - * @api private + * @param {string} path + * @private */ -SendStream.prototype.redirect = function(path){ +SendStream.prototype.redirect = function redirect(path) { if (listenerCount(this, 'directory') !== 0) { - return this.emit('directory'); + this.emit('directory') + return } - if (this.hasTrailingSlash()) return this.error(403); - var res = this.res; - path += '/'; - res.statusCode = 301; - res.setHeader('Content-Type', 'text/html; charset=utf-8'); - res.setHeader('Location', path); - res.end('Redirecting to ' + escapeHtml(path) + '\n'); -}; + if (this.hasTrailingSlash()) { + this.error(403) + return + } + + var loc = path + '/' + var msg = 'Redirecting to ' + escapeHtml(loc) + '\n' + var res = this.res + + // redirect + res.statusCode = 301 + res.setHeader('Content-Type', 'text/html; charset=UTF-8') + res.setHeader('Content-Length', Buffer.byteLength(msg)) + res.setHeader('X-Content-Type-Options', 'nosniff') + res.setHeader('Location', loc) + res.end(msg) +} /** * Pipe to `res. diff --git a/test/send.js b/test/send.js index 8d1691f6..0548c912 100644 --- a/test/send.js +++ b/test/send.js @@ -341,7 +341,7 @@ describe('send(file).pipe(res)', function(){ request(server) .get('/pets') .expect('Location', '/pets/') - .expect('Content-Type', 'text/html; charset=utf-8') + .expect('Content-Type', /html/) .expect(301, 'Redirecting to /pets/\n', done) }) }) From 80cfa7f54ce87c75e92619d5bc510406bd69133a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 Jun 2015 21:15:35 -0400 Subject: [PATCH 047/334] Release 0.13.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 0fa76d7c..1fa40b52 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.13.0 / 2015-06-16 +=================== * Allow Node.js HTTP server to set `Date` response header * Fix incorrectly removing `Content-Location` on 304 response diff --git a/package.json b/package.json index 68ecc1ae..07eb51f7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.12.3", + "version": "0.13.0", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From db3d9cefc72e6f37d96a62aec68e7d50d9afdfd9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 24 Oct 2015 15:13:28 -0400 Subject: [PATCH 048/334] build: skip istanbul coverage on Node.js 0.8 --- .travis.yml | 11 +++++++++-- appveyor.yml | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0500839c..8fbf1c27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,12 @@ node_js: - "2.0" - "2.1" sudo: false -script: "npm run-script test-ci" -after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" +before_install: + # Setup Node.js version-specific dependencies + - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" +script: + # Run test script, depending on istanbul install + - "test ! -z $(npm -ps ls istanbul) || npm test" + - "test -z $(npm -ps ls istanbul) || npm run-script test-ci" +after_script: + - "test -e ./coverage/lcov.info && npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/appveyor.yml b/appveyor.yml index 6a102c94..e6f36527 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,10 +9,13 @@ environment: - nodejs_version: "2.1" install: - ps: Install-Product node $env:nodejs_version + - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul - npm install build: off test_script: - node --version - npm --version - - npm run test-ci + - set npm_test_command=test + - for /f %%l in ('npm -ps ls istanbul') do set npm_test_command=test-ci + - npm run %npm_test_command% version: "{build}" From 7bf108a6639555488dcf19ebc835595aa97924de Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 24 Oct 2015 15:15:59 -0400 Subject: [PATCH 049/334] build: io.js@2.5 --- .travis.yml | 1 + appveyor.yml | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8fbf1c27..03895b65 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ node_js: - "1.8" - "2.0" - "2.1" + - "2.5" sudo: false before_install: # Setup Node.js version-specific dependencies diff --git a/appveyor.yml b/appveyor.yml index e6f36527..b6935525 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,8 +5,7 @@ environment: - nodejs_version: "0.12" - nodejs_version: "1.0" - nodejs_version: "1.8" - - nodejs_version: "2.0" - - nodejs_version: "2.1" + - nodejs_version: "2.5" install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul From de61df0c0712026060539bfb03deb06c855337ad Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 00:10:30 -0500 Subject: [PATCH 050/334] build: reduce runtime versions to one per major --- .travis.yml | 3 --- appveyor.yml | 1 - 2 files changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 03895b65..48ab0b6b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,7 @@ node_js: - "0.8" - "0.10" - "0.12" - - "1.0" - "1.8" - - "2.0" - - "2.1" - "2.5" sudo: false before_install: diff --git a/appveyor.yml b/appveyor.yml index b6935525..db9da643 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,6 @@ environment: - nodejs_version: "0.8" - nodejs_version: "0.10" - nodejs_version: "0.12" - - nodejs_version: "1.0" - nodejs_version: "1.8" - nodejs_version: "2.5" install: From 22290f5eab783a9c8c86719d36e15dbbec8d5158 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 00:11:54 -0500 Subject: [PATCH 051/334] build: support io.js 3.x --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 48ab0b6b..70c99a40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ node_js: - "0.12" - "1.8" - "2.5" + - "3.3" sudo: false before_install: # Setup Node.js version-specific dependencies diff --git a/appveyor.yml b/appveyor.yml index db9da643..ee9a1d0b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,7 @@ environment: - nodejs_version: "0.12" - nodejs_version: "1.8" - nodejs_version: "2.5" + - nodejs_version: "3.3" install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul From 0d4549ce5508fb80e4453e83c6326817fef48957 Mon Sep 17 00:00:00 2001 From: Nook Scheel Date: Sat, 19 Sep 2015 13:10:03 +0300 Subject: [PATCH 052/334] build: support Node.js 4.x closes #81 --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 70c99a40..c38c1fea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" + - "4.1" sudo: false before_install: # Setup Node.js version-specific dependencies diff --git a/appveyor.yml b/appveyor.yml index ee9a1d0b..ed63bafe 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,6 +6,7 @@ environment: - nodejs_version: "1.8" - nodejs_version: "2.5" - nodejs_version: "3.3" + - nodejs_version: "4.1" install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul From 54d298bbc5ede813adc236c5215daa235daffd14 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 00:15:12 -0500 Subject: [PATCH 053/334] build: Node.js@4.2 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c38c1fea..89b6e3af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.1" + - "4.2" sudo: false before_install: # Setup Node.js version-specific dependencies diff --git a/appveyor.yml b/appveyor.yml index ed63bafe..01f8486a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: - nodejs_version: "1.8" - nodejs_version: "2.5" - nodejs_version: "3.3" - - nodejs_version: "4.1" + - nodejs_version: "4.2" install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul From 91523c22f7112261783734fab086d270f1f5386d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 00:24:00 -0500 Subject: [PATCH 054/334] build: istanbul@0.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07eb51f7..d293f0e0 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "devDependencies": { "after": "0.8.1", - "istanbul": "0.3.9", + "istanbul": "0.4.0", "mocha": "2.2.5", "supertest": "1.0.1" }, From 11e8200e0273fd1de80175d16bbd82cf223bde8c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 00:26:47 -0500 Subject: [PATCH 055/334] build: mocha@2.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d293f0e0..be09f8df 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "devDependencies": { "after": "0.8.1", "istanbul": "0.4.0", - "mocha": "2.2.5", + "mocha": "2.3.4", "supertest": "1.0.1" }, "files": [ From 8da8c413e0b9d29e5b52efb7d9b083755a741bd3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 00:31:22 -0500 Subject: [PATCH 056/334] build: supertest@1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be09f8df..48c01048 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "after": "0.8.1", "istanbul": "0.4.0", "mocha": "2.3.4", - "supertest": "1.0.1" + "supertest": "1.1.0" }, "files": [ "HISTORY.md", From 0aaffab3620de1cbe3e9b90fe8aee95f24456849 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 00:35:40 -0500 Subject: [PATCH 057/334] deps: escape-html@~1.0.3 --- HISTORY.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1fa40b52..5947917e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,11 @@ +unreleased +========== + + * deps: escape-html@~1.0.3 + - perf: enable strict mode + - perf: optimize string replacement + - perf: use faster string coercion + 0.13.0 / 2015-06-16 =================== diff --git a/package.json b/package.json index 48c01048..08854265 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "debug": "~2.2.0", "depd": "~1.0.1", "destroy": "1.0.3", - "escape-html": "1.0.2", + "escape-html": "~1.0.3", "etag": "~1.7.0", "fresh": "0.3.0", "http-errors": "~1.3.1", From 255789da34d97ea90b2ba74c5c956fa32a809c2e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 16:34:55 -0500 Subject: [PATCH 058/334] deps: range-parser@~1.0.3 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 5947917e..019137d2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,8 @@ unreleased - perf: enable strict mode - perf: optimize string replacement - perf: use faster string coercion + * deps: range-parser@~1.0.3 + - perf: enable strict mode 0.13.0 / 2015-06-16 =================== diff --git a/package.json b/package.json index 08854265..cca3b1ba 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "mime": "1.3.4", "ms": "0.7.1", "on-finished": "~2.3.0", - "range-parser": "~1.0.2", + "range-parser": "~1.0.3", "statuses": "~1.2.1" }, "devDependencies": { From 4069d3045ec5a748bac1b3aadb281df38f3b86f0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 21 Nov 2015 16:37:04 -0500 Subject: [PATCH 059/334] deps: depd@~1.1.0 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 019137d2..e8f1d23e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,9 @@ unreleased ========== + * deps: depd@~1.1.0 + - Support web browser loading + - perf: enable strict mode * deps: escape-html@~1.0.3 - perf: enable strict mode - perf: optimize string replacement diff --git a/package.json b/package.json index cca3b1ba..933cc9e9 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ ], "dependencies": { "debug": "~2.2.0", - "depd": "~1.0.1", + "depd": "~1.1.0", "destroy": "1.0.3", "escape-html": "~1.0.3", "etag": "~1.7.0", From fea7e13c6d15e5c51cef1e8c25120310c3c727d2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 11 Dec 2015 23:44:12 -0500 Subject: [PATCH 060/334] build: istanbul@0.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 933cc9e9..4902fe18 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "devDependencies": { "after": "0.8.1", - "istanbul": "0.4.0", + "istanbul": "0.4.1", "mocha": "2.3.4", "supertest": "1.1.0" }, From f84f3bc73ebdb6be8d93eaf1830be9393f51ec6b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 11 Dec 2015 23:45:18 -0500 Subject: [PATCH 061/334] tests: add tests for deny dotfile in sub directory --- test/fixtures/.mine/.hidden | 1 + test/fixtures/pets/.hidden | 1 + test/send.js | 12 ++++++++++++ 3 files changed, 14 insertions(+) create mode 100644 test/fixtures/.mine/.hidden create mode 100644 test/fixtures/pets/.hidden diff --git a/test/fixtures/.mine/.hidden b/test/fixtures/.mine/.hidden new file mode 100644 index 00000000..d97c5ead --- /dev/null +++ b/test/fixtures/.mine/.hidden @@ -0,0 +1 @@ +secret diff --git a/test/fixtures/pets/.hidden b/test/fixtures/pets/.hidden new file mode 100644 index 00000000..d97c5ead --- /dev/null +++ b/test/fixtures/pets/.hidden @@ -0,0 +1 @@ +secret diff --git a/test/send.js b/test/send.js index 0548c912..07c2746c 100644 --- a/test/send.js +++ b/test/send.js @@ -938,6 +938,18 @@ describe('send(file, options)', function(){ .expect(403, done) }) + it('should 403 for dotfile in directory', function (done) { + request(createServer({dotfiles: 'deny', root: fixtures})) + .get('/pets/.hidden') + .expect(403, done) + }) + + it('should 403 for dotfile in dotfile directory', function (done) { + request(createServer({dotfiles: 'deny', root: fixtures})) + .get('/.mine/.hidden') + .expect(403, done) + }) + it('should send files in root dotfile directory', function (done) { request(createServer({dotfiles: 'deny', root: path.join(fixtures, '.mine')})) .get('/name.txt') From f692d0b114b3bfa5d2e696a8303c99ffacff043b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 13 Dec 2015 12:09:20 -0400 Subject: [PATCH 062/334] build: support Node.js 5.x --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 89b6e3af..e1109132 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ node_js: - "2.5" - "3.3" - "4.2" + - "5.2" sudo: false before_install: # Setup Node.js version-specific dependencies diff --git a/appveyor.yml b/appveyor.yml index 01f8486a..d5bb36d7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,6 +7,7 @@ environment: - nodejs_version: "2.5" - nodejs_version: "3.3" - nodejs_version: "4.2" + - nodejs_version: "5.2" install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul From 44c39e5edce484ccc00a16f6706a5bb79b3f957a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Jan 2016 01:34:28 -0500 Subject: [PATCH 063/334] deps: destroy@~1.0.4 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index e8f1d23e..6517c1e5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,6 +4,8 @@ unreleased * deps: depd@~1.1.0 - Support web browser loading - perf: enable strict mode + * deps: destroy@~1.0.4 + - perf: enable strict mode * deps: escape-html@~1.0.3 - perf: enable strict mode - perf: optimize string replacement diff --git a/package.json b/package.json index 4902fe18..14722dab 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "debug": "~2.2.0", "depd": "~1.1.0", - "destroy": "1.0.3", + "destroy": "~1.0.4", "escape-html": "~1.0.3", "etag": "~1.7.0", "fresh": "0.3.0", From df09a2305c3d6a6773efe41ae4e756ed6522c3c0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Jan 2016 01:35:04 -0500 Subject: [PATCH 064/334] build: istanbul@0.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 14722dab..47efa301 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "devDependencies": { "after": "0.8.1", - "istanbul": "0.4.1", + "istanbul": "0.4.2", "mocha": "2.3.4", "supertest": "1.1.0" }, From dbce43fc7102c14b475c25cde918b726063cc991 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Jan 2016 02:39:34 -0500 Subject: [PATCH 065/334] Release 0.13.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6517c1e5..d3dca9c7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.13.1 / 2016-01-16 +=================== * deps: depd@~1.1.0 - Support web browser loading diff --git a/package.json b/package.json index 47efa301..26c9d4f6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.13.0", + "version": "0.13.1", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From 14604b4c8a09f57d1bac8e9a26da208e80961eec Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Jan 2016 15:59:24 -0500 Subject: [PATCH 066/334] build: Node.js@5.3 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e1109132..a697d12e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.2" - - "5.2" + - "5.3" sudo: false before_install: # Setup Node.js version-specific dependencies diff --git a/appveyor.yml b/appveyor.yml index d5bb36d7..e905d515 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ environment: - nodejs_version: "2.5" - nodejs_version: "3.3" - nodejs_version: "4.2" - - nodejs_version: "5.2" + - nodejs_version: "5.3" install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul From 2897c8a86ee5dce8af289409c808ca16ab26a480 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Jan 2016 16:29:43 -0500 Subject: [PATCH 067/334] docs: fix heading levels --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 35860609..a677b879 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ This can also be a string accepted by the Serve files relative to `path`. -### Events +#### Events The `SendStream` is an event emitter and will emit the following events: @@ -94,7 +94,7 @@ The `SendStream` is an event emitter and will emit the following events: - `stream` file streaming has started `(stream)` - `end` streaming has completed -### .pipe +#### .pipe The `pipe` method is used to pipe the response into the Node.js HTTP response object, typically `send(req, path, options).pipe(res)`. @@ -140,7 +140,7 @@ var app = http.createServer(function(req, res){ }).listen(3000); ``` -Serving from a root directory with custom error-handling: +### Serving from a root directory with custom error-handling ```js var http = require('http'); From 9460200d6b6b186bc58c7ab24bb7fef598f2d7d4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Jan 2016 16:33:07 -0500 Subject: [PATCH 068/334] docs: document configuring type lookup closes #97 --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index a677b879..06a972a6 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,15 @@ The `SendStream` is an event emitter and will emit the following events: The `pipe` method is used to pipe the response into the Node.js HTTP response object, typically `send(req, path, options).pipe(res)`. +### .mime + +The `mime` export is the global instance of of the +[`mime` npm module](https://www.npmjs.com/package/mime). + +This is used to configure the MIME types that are associated with file extensions +as well as other options for how to resolve the MIME type of a file (like the +default type to use for an unknown file extension). + ## Error-handling By default when no `error` listeners are present an automatic response will be @@ -140,6 +149,25 @@ var app = http.createServer(function(req, res){ }).listen(3000); ``` +### Custom file types + +```js +var http = require('http'); +var send = require('send'); + +// Default unknown types to text/plain +send.mime.default_type = 'text/plain'; + +// Add a custom type +send.mime.define({ + 'application/x-my-type': ['x-mt', 'x-mtt'] +}); + +var app = http.createServer(function(req, res){ + send(req, req.url).pipe(res); +}).listen(3000); +``` + ### Serving from a root directory with custom error-handling ```js From f84023772e09827be2fdc4ac5f3b1c8c18188f7f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Jan 2016 16:42:32 -0500 Subject: [PATCH 069/334] tests: add simple test for send.mime --- test/send.js | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/test/send.js b/test/send.js index 07c2746c..ae8d9507 100644 --- a/test/send.js +++ b/test/send.js @@ -31,12 +31,6 @@ var app = http.createServer(function(req, res){ .pipe(res); }); -describe('send.mime', function(){ - it('should be exposed', function(){ - assert(send.mime); - }) -}) - describe('send(file).pipe(res)', function(){ it('should stream the file contents', function(done){ request(app) @@ -1290,6 +1284,31 @@ describe('send(file, options)', function(){ }) }) +describe('send.mime', function () { + it('should be exposed', function () { + assert.ok(send.mime) + }) + + describe('.default_type', function () { + before(function () { + this.default_type = send.mime.default_type + }) + + afterEach(function () { + send.mime.default_type = this.default_type + }) + + it('should change the default type', function (done) { + send.mime.default_type = 'text/plain' + + request(createServer({root: fixtures})) + .get('/nums') + .expect('Content-Type', 'text/plain; charset=UTF-8') + .expect(200, done) + }) + }) +}) + function createServer(opts, fn) { return http.createServer(function onRequest(req, res) { try { From 31ceb6aaf530152c29a1855bf3f9dbd86533303e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 23 Jan 2016 16:52:29 -0500 Subject: [PATCH 070/334] Fix invalid Content-Type header when send.mime.default_type unset fixes #98 --- HISTORY.md | 5 +++++ index.js | 11 ++++++++++- test/send.js | 9 +++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index d3dca9c7..a1b81fc7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix invalid `Content-Type` header when `send.mime.default_type` unset + 0.13.1 / 2016-01-16 =================== diff --git a/index.js b/index.js index 3510989e..a4e5af85 100644 --- a/index.js +++ b/index.js @@ -726,11 +726,20 @@ SendStream.prototype.stream = function(path, options){ * @api private */ -SendStream.prototype.type = function(path){ +SendStream.prototype.type = function type(path) { var res = this.res; + if (res.getHeader('Content-Type')) return; + var type = mime.lookup(path); + + if (!type) { + debug('no content-type'); + return; + } + var charset = mime.charsets.lookup(type); + debug('content-type %s', type); res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')); }; diff --git a/test/send.js b/test/send.js index ae8d9507..94112868 100644 --- a/test/send.js +++ b/test/send.js @@ -1306,6 +1306,15 @@ describe('send.mime', function () { .expect('Content-Type', 'text/plain; charset=UTF-8') .expect(200, done) }) + + it('should not add Content-Type for undefined default', function (done) { + send.mime.default_type = undefined + + request(createServer({root: fixtures})) + .get('/nums') + .expect(shouldNotHaveHeader('Content-Type')) + .expect(200, done) + }) }) }) From 1384d786ccccb2cbf8c827a7cb1e7a31dd4052f6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Feb 2016 21:36:51 -0500 Subject: [PATCH 071/334] build: mocha@2.4.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 26c9d4f6..8ef6a1cf 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "devDependencies": { "after": "0.8.1", "istanbul": "0.4.2", - "mocha": "2.3.4", + "mocha": "2.4.5", "supertest": "1.1.0" }, "files": [ From a8f332500c52cf7d8367999ebe598feb7f75f8a1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Feb 2016 21:38:36 -0500 Subject: [PATCH 072/334] build: Node.js@4.3 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a697d12e..94e27bdf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.2" + - "4.3" - "5.3" sudo: false before_install: diff --git a/appveyor.yml b/appveyor.yml index e905d515..f4139168 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: - nodejs_version: "1.8" - nodejs_version: "2.5" - nodejs_version: "3.3" - - nodejs_version: "4.2" + - nodejs_version: "4.3" - nodejs_version: "5.3" install: - ps: Install-Product node $env:nodejs_version From 58b5f987aca67bd0fd49cd91ddd90138f2024201 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 9 Feb 2016 21:42:47 -0500 Subject: [PATCH 073/334] build: Node.js@5.6 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 94e27bdf..703cf412 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.3" - - "5.3" + - "5.6" sudo: false before_install: # Setup Node.js version-specific dependencies diff --git a/appveyor.yml b/appveyor.yml index f4139168..42892536 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ environment: - nodejs_version: "2.5" - nodejs_version: "3.3" - nodejs_version: "4.3" - - nodejs_version: "5.3" + - nodejs_version: "5.6" install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul From 496e6dbac4475cc8757210e073b5d6fb1523be45 Mon Sep 17 00:00:00 2001 From: mh-cbon Date: Thu, 3 Mar 2016 10:10:54 +0100 Subject: [PATCH 074/334] docs: add documentation for end & start options closes #103 closes #104 --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 06a972a6..d2415559 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,12 @@ The default value is _similar_ to `'ignore'`, with the exception that this default will not ignore the files within a directory that begins with a dot, for backward-compatibility. +##### end + +Byte offset at which the stream ends, defaults to the length of the file +minus 1. The end is inclusive in the stream, meaning `end: 3` will include +the 4th byte in the stream. + ##### etag Enable or disable etag generation, defaults to true. @@ -83,6 +89,11 @@ This can also be a string accepted by the Serve files relative to `path`. +##### start + +Byte offset at which the stream starts, defaults to 0. The start is inclusive, +meaning `start: 2` will include the 3rd byte in the stream. + #### Events The `SendStream` is an event emitter and will emit the following events: From 5a089701b1c49d96084716bdb5465edefa08c906 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 5 Mar 2016 23:22:12 -0500 Subject: [PATCH 075/334] Release 0.13.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index a1b81fc7..35aef469 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.13.2 / 2016-03-05 +=================== * Fix invalid `Content-Type` header when `send.mime.default_type` unset diff --git a/package.json b/package.json index 8ef6a1cf..66028671 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.13.1", + "version": "0.13.2", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From 9ce2d8380ce159d0f5f496a8c5803131cad1850e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 12 Apr 2016 19:56:32 -0400 Subject: [PATCH 076/334] build: Node.js@4.4 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 703cf412..273f4ef7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.3" + - "4.4" - "5.6" sudo: false before_install: diff --git a/appveyor.yml b/appveyor.yml index 42892536..d1722aa1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: - nodejs_version: "1.8" - nodejs_version: "2.5" - nodejs_version: "3.3" - - nodejs_version: "4.3" + - nodejs_version: "4.4" - nodejs_version: "5.6" install: - ps: Install-Product node $env:nodejs_version From 3568f428a55bf61e777adf13aef79b69c3fcfc4a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 12 Apr 2016 20:00:22 -0400 Subject: [PATCH 077/334] build: Node.js@5.10 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 273f4ef7..4fec0c0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.4" - - "5.6" + - "5.10" sudo: false before_install: # Setup Node.js version-specific dependencies diff --git a/appveyor.yml b/appveyor.yml index d1722aa1..91e3f7ef 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ environment: - nodejs_version: "2.5" - nodejs_version: "3.3" - nodejs_version: "4.4" - - nodejs_version: "5.6" + - nodejs_version: "5.10" install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul From b5ff0194f1311579a9f3265e3300e411d6553c1f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 12 Apr 2016 21:05:51 -0400 Subject: [PATCH 078/334] build: cache node_modules on CI --- .travis.yml | 7 +++++++ appveyor.yml | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4fec0c0d..d09293d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,16 @@ node_js: - "4.4" - "5.10" sudo: false +cache: + directories: + - node_modules before_install: # Setup Node.js version-specific dependencies - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" + + # Update Node.js modules + - "test ! -d node_modules || npm prune" + - "test ! -d node_modules || npm rebuild" script: # Run test script, depending on istanbul install - "test ! -z $(npm -ps ls istanbul) || npm test" diff --git a/appveyor.yml b/appveyor.yml index 91e3f7ef..3bcefb87 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,9 +8,13 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.4" - nodejs_version: "5.10" +cache: + - node_modules install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul + - if exist node_modules npm prune + - if exist node_modules npm rebuild - npm install build: off test_script: From 6de3c0f3056daf51c1b5e22ede7ea8c072133018 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 24 May 2016 14:44:26 -0400 Subject: [PATCH 079/334] build: istanbul@0.4.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 66028671..26f37c9c 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "devDependencies": { "after": "0.8.1", - "istanbul": "0.4.2", + "istanbul": "0.4.3", "mocha": "2.4.5", "supertest": "1.1.0" }, From 49c10405b0892fcb1cf43448dafb40fb10a732d2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 24 May 2016 14:45:22 -0400 Subject: [PATCH 080/334] build: mocha@2.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 26f37c9c..c0a97b72 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "devDependencies": { "after": "0.8.1", "istanbul": "0.4.3", - "mocha": "2.4.5", + "mocha": "2.5.2", "supertest": "1.1.0" }, "files": [ From 4a4e2d374449f1c45b736eeae3ffd17cee4c177d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 2 Jun 2016 22:09:43 -0400 Subject: [PATCH 081/334] build: Node.js@5.11 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d09293d7..23082f34 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.4" - - "5.10" + - "5.11" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 3bcefb87..60f61c95 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ environment: - nodejs_version: "2.5" - nodejs_version: "3.3" - nodejs_version: "4.4" - - nodejs_version: "5.10" + - nodejs_version: "5.11" cache: - node_modules install: From 0918ed03ab9316b6ea883a00e77c774dab9655fc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 2 Jun 2016 22:12:34 -0400 Subject: [PATCH 082/334] build: support Node.js 6.x --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 23082f34..4c12100c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ node_js: - "3.3" - "4.4" - "5.11" + - "6.2" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 60f61c95..2985afa7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,6 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.4" - nodejs_version: "5.11" + - nodejs_version: "6.2" cache: - node_modules install: From 3899a7cd45ddf59e217b461146bd784cdd46dc89 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 2 Jun 2016 22:36:02 -0400 Subject: [PATCH 083/334] deps: http-errors@~1.5.0 --- HISTORY.md | 11 +++++++++++ package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 35aef469..812295f2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,14 @@ +unreleased +========== + + * deps: http-errors@~1.5.0 + - Add `HttpError` export, for `err instanceof createError.HttpError` + - Support new code `421 Misdirected Request` + - Use `setprototypeof` module to replace `__proto__` setting + - deps: inherits@2.0.1 + - deps: statuses@'>= 1.3.0 < 2' + - perf: enable strict mode + 0.13.2 / 2016-03-05 =================== diff --git a/package.json b/package.json index c0a97b72..dffa523d 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "escape-html": "~1.0.3", "etag": "~1.7.0", "fresh": "0.3.0", - "http-errors": "~1.3.1", + "http-errors": "~1.5.0", "mime": "1.3.4", "ms": "0.7.1", "on-finished": "~2.3.0", From d7f728b7f46858a049033abeda6cc3f8de6abde8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 2 Jun 2016 22:41:54 -0400 Subject: [PATCH 084/334] deps: range-parser@~1.2.0 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 812295f2..c14c8f5a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -8,6 +8,9 @@ unreleased - deps: inherits@2.0.1 - deps: statuses@'>= 1.3.0 < 2' - perf: enable strict mode + * deps: range-parser@~1.2.0 + - Fix incorrectly returning -1 when there is at least one valid range + - perf: remove internal function 0.13.2 / 2016-03-05 =================== diff --git a/package.json b/package.json index dffa523d..8ff679c2 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "mime": "1.3.4", "ms": "0.7.1", "on-finished": "~2.3.0", - "range-parser": "~1.0.3", + "range-parser": "~1.2.0", "statuses": "~1.2.1" }, "devDependencies": { From a1f504a3cf7dad3cbe939fd1aa44237561ce00c1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 2 Jun 2016 22:48:00 -0400 Subject: [PATCH 085/334] deps: statuses@~1.3.0 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index c14c8f5a..6e135114 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -11,6 +11,9 @@ unreleased * deps: range-parser@~1.2.0 - Fix incorrectly returning -1 when there is at least one valid range - perf: remove internal function + * deps: statuses@~1.3.0 + - Add `421 Misdirected Request` + - perf: enable strict mode 0.13.2 / 2016-03-05 =================== diff --git a/package.json b/package.json index 8ff679c2..2b7ea5a8 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "ms": "0.7.1", "on-finished": "~2.3.0", "range-parser": "~1.2.0", - "statuses": "~1.2.1" + "statuses": "~1.3.0" }, "devDependencies": { "after": "0.8.1", From 8de9d9f1fad5fc8103280ea78db4d0eca7580a10 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 2 Jun 2016 22:58:12 -0400 Subject: [PATCH 086/334] build: mocha@2.5.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b7ea5a8..f5ba534a 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "devDependencies": { "after": "0.8.1", "istanbul": "0.4.3", - "mocha": "2.5.2", + "mocha": "2.5.3", "supertest": "1.1.0" }, "files": [ From c47fbe996fbb10d6338d78c1548e29b1026e714f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 3 Jun 2016 13:35:46 -0400 Subject: [PATCH 087/334] lint: remove unused variables --- index.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index a4e5af85..48cf34da 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,6 @@ var extname = path.extname var maxMaxAge = 60 * 60 * 24 * 365 * 1000; // 1 year var resolve = path.resolve var sep = path.sep -var toString = Object.prototype.toString var upPathRegexp = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/ /** @@ -429,9 +428,8 @@ SendStream.prototype.redirect = function redirect(path) { */ SendStream.prototype.pipe = function(res){ - var self = this - , args = arguments - , root = this._root; + // root path + var root = this._root // references this.res = res; @@ -686,7 +684,6 @@ SendStream.prototype.stream = function(path, options){ var finished = false; var self = this; var res = this.res; - var req = this.req; // pipe var stream = fs.createReadStream(path, options); From a435ade62ff4a737b83c90bcc993712a565d3df1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 3 Jun 2016 13:49:57 -0400 Subject: [PATCH 088/334] build: update copyright --- LICENSE | 2 +- index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index e4d595b3..4aa69e83 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ (The MIT License) Copyright (c) 2012 TJ Holowaychuk -Copyright (c) 2014-2015 Douglas Christopher Wilson +Copyright (c) 2014-2016 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/index.js b/index.js index 48cf34da..113ba186 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ /*! * send * Copyright(c) 2012 TJ Holowaychuk - * Copyright(c) 2014-2015 Douglas Christopher Wilson + * Copyright(c) 2014-2016 Douglas Christopher Wilson * MIT Licensed */ From 27ec91786529fa0eb386dee2a94f0deb93fff614 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 3 Jun 2016 14:38:14 -0400 Subject: [PATCH 089/334] Attempt to combine multiple ranges into single range --- HISTORY.md | 1 + index.js | 5 ++++- test/send.js | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6e135114..e5172ac3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Attempt to combine multiple ranges into single range * deps: http-errors@~1.5.0 - Add `HttpError` export, for `err instanceof createError.HttpError` - Support new code `421 Misdirected Request` diff --git a/index.js b/index.js index 113ba186..84605599 100644 --- a/index.js +++ b/index.js @@ -547,7 +547,10 @@ SendStream.prototype.send = function(path, stat){ // Range support if (ranges) { - ranges = parseRange(len, ranges); + // parse + ranges = parseRange(len, ranges, { + combine: true + }) // If-Range support if (!this.isRangeFresh()) { diff --git a/test/send.js b/test/send.js index 94112868..09fe6649 100644 --- a/test/send.js +++ b/test/send.js @@ -491,8 +491,17 @@ describe('send(file).pipe(res)', function(){ request(app) .get('/nums') .set('Range', 'bytes=1-1,3-') + .expect(shouldNotHaveHeader('Content-Range')) .expect(200, '123456789', done); }) + + it('should respond with 206 is all ranges can be combined', function (done) { + request(app) + .get('/nums') + .set('Range', 'bytes=1-2,3-5') + .expect('Content-Range', 'bytes 1-5/9') + .expect(206, '23456', done) + }) }) describe('when if-range present', function(){ From f585681a346e99388a5261ecb9e9cda1b366b75c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 3 Jun 2016 14:52:27 -0400 Subject: [PATCH 090/334] Ignore non-byte Range headers --- HISTORY.md | 1 + index.js | 3 ++- test/send.js | 9 ++++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e5172ac3..f031eeb1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Attempt to combine multiple ranges into single range + * Ignore non-byte `Range` headers * deps: http-errors@~1.5.0 - Add `HttpError` export, for `err instanceof createError.HttpError` - Support new code `421 Misdirected Request` diff --git a/index.js b/index.js index 84605599..4bcbb5f5 100644 --- a/index.js +++ b/index.js @@ -34,6 +34,7 @@ var statuses = require('statuses') /** * Variables. */ +var bytesRangeRegexp = /^ *bytes=/ var extname = path.extname var maxMaxAge = 60 * 60 * 24 * 365 * 1000; // 1 year var resolve = path.resolve @@ -546,7 +547,7 @@ SendStream.prototype.send = function(path, stat){ } // Range support - if (ranges) { + if (bytesRangeRegexp.test(ranges)) { // parse ranges = parseRange(len, ranges, { combine: true diff --git a/test/send.js b/test/send.js index 09fe6649..640d5bfc 100644 --- a/test/send.js +++ b/test/send.js @@ -404,7 +404,14 @@ describe('send(file).pipe(res)', function(){ .set('Range', 'bytes=0-4') .expect(206, '12345', done); }) - + + it('should ignore non-byte ranges', function (done) { + request(app) + .get('/nums') + .set('Range', 'items=0-4') + .expect(200, '123456789', done) + }) + it('should be inclusive', function(done){ request(app) .get('/nums') From 487f12367e05767dc8bd4f7e246478950aa8e7b6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 3 Jun 2016 16:51:22 -0400 Subject: [PATCH 091/334] Fix Content-Range header in 416 responses when using start/end options --- HISTORY.md | 1 + index.js | 2 +- test/send.js | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f031eeb1..cda39ef5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Attempt to combine multiple ranges into single range + * Fix `Content-Range` header in 416 responses when using `start`/`end` options * Ignore non-byte `Range` headers * deps: http-errors@~1.5.0 - Add `HttpError` export, for `err instanceof createError.HttpError` diff --git a/index.js b/index.js index 4bcbb5f5..47d1a870 100644 --- a/index.js +++ b/index.js @@ -562,7 +562,7 @@ SendStream.prototype.send = function(path, stat){ // unsatisfiable if (-1 == ranges) { debug('range unsatisfiable'); - res.setHeader('Content-Range', 'bytes */' + stat.size); + res.setHeader('Content-Range', 'bytes */' + len); return this.error(416); } diff --git a/test/send.js b/test/send.js index 640d5bfc..39650873 100644 --- a/test/send.js +++ b/test/send.js @@ -608,6 +608,24 @@ describe('send(file).pipe(res)', function(){ .set('Range', 'bytes=-2') .expect(206, '23', done) }) + + it('should support start/end with unsatisfiable Range request', function (done) { + var app = http.createServer(function (req, res) { + var i = parseInt(req.url.slice(1)) + send(req, 'test/fixtures/nums', { start:i*3, end:i*3+2 }) + .on('error', function (err) { + res.statusCode = err.status + res.end(http.STATUS_CODES[err.status]) + }) + .pipe(res) + }) + + request(app) + .get('/0') + .set('Range', 'bytes=5-9') + .expect('Content-Range', 'bytes */3') + .expect(416, done) + }) }) describe('.etag()', function(){ From b01bcb28ba9d26d038543fd98f8dfb0d83525dbe Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 3 Jun 2016 20:26:52 -0400 Subject: [PATCH 092/334] Correctly inherit from Stream class --- HISTORY.md | 1 + index.js | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index cda39ef5..70622194 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Attempt to combine multiple ranges into single range + * Correctly inherit from `Stream` class * Fix `Content-Range` header in 416 responses when using `start`/`end` options * Ignore non-byte `Range` headers * deps: http-errors@~1.5.0 diff --git a/index.js b/index.js index 47d1a870..91741ebf 100644 --- a/index.js +++ b/index.js @@ -30,6 +30,7 @@ var EventEmitter = require('events').EventEmitter; var ms = require('ms'); var onFinished = require('on-finished') var statuses = require('statuses') +var util = require('util') /** * Variables. @@ -81,6 +82,8 @@ function send(req, path, options) { */ function SendStream(req, path, options) { + Stream.call(this) + var opts = options || {} this.options = opts @@ -140,10 +143,10 @@ function SendStream(req, path, options) { } /** - * Inherits from `Stream.prototype`. + * Inherits from `Stream`. */ -SendStream.prototype.__proto__ = Stream.prototype; +util.inherits(SendStream, Stream) /** * Enable or disable etag generation. From 5e932ef0bc36b92cd4d2419bcae69bfe9969fcb3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Jun 2016 00:59:38 -0400 Subject: [PATCH 093/334] Fix Content-Range header missing from default 416 responses --- HISTORY.md | 1 + index.js | 69 +++++++++++++++++++++++++++++++++++++++++++--------- test/send.js | 55 ++++++++++++----------------------------- 3 files changed, 74 insertions(+), 51 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 70622194..e5b906e6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,6 +4,7 @@ unreleased * Attempt to combine multiple ranges into single range * Correctly inherit from `Stream` class * Fix `Content-Range` header in 416 responses when using `start`/`end` options + * Fix `Content-Range` header missing from default 416 responses * Ignore non-byte `Range` headers * deps: http-errors@~1.5.0 - Add `HttpError` export, for `err instanceof createError.HttpError` diff --git a/index.js b/index.js index 91741ebf..9c600329 100644 --- a/index.js +++ b/index.js @@ -253,8 +253,13 @@ SendStream.prototype.error = function error(status, error) { var res = this.res var msg = statuses[status] - // wipe all existing headers - res._headers = null + // clear existing headers + clearHeaders(res) + + // add error headers + if (error && error.headers) { + setHeaders(res, error.headers) + } // send basic response res.statusCode = status @@ -565,8 +570,14 @@ SendStream.prototype.send = function(path, stat){ // unsatisfiable if (-1 == ranges) { debug('range unsatisfiable'); - res.setHeader('Content-Range', 'bytes */' + len); - return this.error(416); + + // Content-Range + res.setHeader('Content-Range', contentRange('bytes', len)) + + // 416 Requested Range Not Satisfiable + return this.error(416, { + headers: {'Content-Range': res.getHeader('Content-Range')} + }) } // valid (syntactically invalid/multiple ranges are treated as a regular response) @@ -574,13 +585,8 @@ SendStream.prototype.send = function(path, stat){ debug('range %j', ranges); // Content-Range - res.statusCode = 206; - res.setHeader('Content-Range', 'bytes ' - + ranges[0].start - + '-' - + ranges[0].end - + '/' - + len); + res.statusCode = 206 + res.setHeader('Content-Range', contentRange('bytes', len, ranges[0])) offset += ranges[0].start; len = ranges[0].end - ranges[0].start + 1; @@ -778,6 +784,18 @@ SendStream.prototype.setHeader = function setHeader(path, stat){ } }; +/** + * Clear all headers from a response. + * + * @param {object} res + * @private + */ + +function clearHeaders (res) { + res._headers = {} + res._headerNames = {} +} + /** * Determine if path parts contain a dotfile. * @@ -794,6 +812,18 @@ function containsDotFile(parts) { return false } +/** + * Create a Content-Range header. + * + * @param {string} type + * @param {number} size + * @param {array} [range] + */ + +function contentRange (type, size, range) { + return type + ' ' + (range ? range.start + '-' + range.end : '*') + '/' + size +} + /** * decodeURIComponent. * @@ -831,3 +861,20 @@ function normalizeList(val, name) { return list } + +/** + * Set an object of headers on a response. + * + * @param {object} res + * @param {object} headers + * @private + */ + +function setHeaders (res, headers) { + var keys = Object.keys(headers) + + for (var i = 0; i < keys.length; i++) { + var key = keys[i] + res.setHeader(key, headers[key]) + } +} diff --git a/test/send.js b/test/send.js index 39650873..668c1586 100644 --- a/test/send.js +++ b/test/send.js @@ -419,12 +419,12 @@ describe('send(file).pipe(res)', function(){ .expect(206, '1', done); }) - it('should set Content-Range', function(done){ + it('should set Content-Range', function (done) { request(app) .get('/nums') .set('Range', 'bytes=2-5') .expect('Content-Range', 'bytes 2-5/9') - .expect(206, done); + .expect(206, done) }) it('should support -n', function(done){ @@ -575,53 +575,28 @@ describe('send(file).pipe(res)', function(){ }) describe('when "options" is specified', function(){ - it('should support start/end', function(done){ - var app = http.createServer(function(req, res){ - var i = parseInt(req.url.slice(1)); - send(req, 'test/fixtures/nums', { start:i*3, end:i*3+2 }).pipe(res); - }); - - request(app) - .get('/1') - .expect(200, '456', done); + it('should support start/end', function (done) { + request(createServer({root: fixtures, start: 3, end: 5})) + .get('/nums') + .expect(200, '456', done) }) - it('should adjust too large end', function(done){ - var app = http.createServer(function(req, res){ - var i = parseInt(req.url.slice(1)); - send(req, 'test/fixtures/nums', { start:i*3, end:90 }).pipe(res); - }); - - request(app) - .get('/1') - .expect(200, '456789', done); + it('should adjust too large end', function (done) { + request(createServer({root: fixtures, start: 3, end: 90})) + .get('/nums') + .expect(200, '456789', done) }) - it('should support start/end with Range request', function(done){ - var app = http.createServer(function(req, res){ - var i = parseInt(req.url.slice(1)); - send(req, 'test/fixtures/nums', { start:i*3, end:i*3+2 }).pipe(res); - }); - - request(app) - .get('/0') + it('should support start/end with Range request', function (done) { + request(createServer({root: fixtures, start: 0, end: 2})) + .get('/nums') .set('Range', 'bytes=-2') .expect(206, '23', done) }) it('should support start/end with unsatisfiable Range request', function (done) { - var app = http.createServer(function (req, res) { - var i = parseInt(req.url.slice(1)) - send(req, 'test/fixtures/nums', { start:i*3, end:i*3+2 }) - .on('error', function (err) { - res.statusCode = err.status - res.end(http.STATUS_CODES[err.status]) - }) - .pipe(res) - }) - - request(app) - .get('/0') + request(createServer({root: fixtures, start: 0, end: 2})) + .get('/nums') .set('Range', 'bytes=5-9') .expect('Content-Range', 'bytes */3') .expect(416, done) From 8b9950364f8462e4df672ec3f45b9a02a1113f66 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 5 Jun 2016 19:30:25 -0400 Subject: [PATCH 094/334] perf: remove argument reassignment --- HISTORY.md | 1 + index.js | 50 ++++++++++++++++++++++++-------------------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e5b906e6..4a5bff57 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -19,6 +19,7 @@ unreleased * deps: statuses@~1.3.0 - Add `421 Misdirected Request` - perf: enable strict mode + * perf: remove argument reassignment 0.13.2 / 2016-03-05 =================== diff --git a/index.js b/index.js index 9c600329..c0f500fb 100644 --- a/index.js +++ b/index.js @@ -156,12 +156,11 @@ util.inherits(SendStream, Stream) * @api public */ -SendStream.prototype.etag = deprecate.function(function etag(val) { - val = Boolean(val); - debug('etag %s', val); - this._etag = val; - return this; -}, 'send.etag: pass etag as option'); +SendStream.prototype.etag = deprecate.function(function etag (val) { + this._etag = Boolean(val) + debug('etag %s', this._etag) + return this +}, 'send.etag: pass etag as option') /** * Enable or disable "hidden" (dot) files. @@ -171,13 +170,12 @@ SendStream.prototype.etag = deprecate.function(function etag(val) { * @api public */ -SendStream.prototype.hidden = deprecate.function(function hidden(val) { - val = Boolean(val); - debug('hidden %s', val); - this._hidden = val; +SendStream.prototype.hidden = deprecate.function(function hidden (val) { + this._hidden = Boolean(val) this._dotfiles = undefined - return this; -}, 'send.hidden: use dotfiles option'); + debug('hidden %s', this._hidden) + return this +}, 'send.hidden: use dotfiles option') /** * Set index `paths`, set to a falsy @@ -203,11 +201,11 @@ SendStream.prototype.index = deprecate.function(function index(paths) { * @api public */ -SendStream.prototype.root = function(path){ - path = String(path); - this._root = resolve(path) - return this; -}; +SendStream.prototype.root = function root (path) { + this._root = resolve(String(path)) + debug('root %s', this._root) + return this +} SendStream.prototype.from = deprecate.function(SendStream.prototype.root, 'send.from: pass root as option'); @@ -223,16 +221,16 @@ SendStream.prototype.root = deprecate.function(SendStream.prototype.root, * @api public */ -SendStream.prototype.maxage = deprecate.function(function maxage(maxAge) { - maxAge = typeof maxAge === 'string' +SendStream.prototype.maxage = deprecate.function(function maxage (maxAge) { + this._maxage = typeof maxAge === 'string' ? ms(maxAge) - : Number(maxAge); - if (isNaN(maxAge)) maxAge = 0; - if (Infinity == maxAge) maxAge = 60 * 60 * 24 * 365 * 1000; - debug('max-age %d', maxAge); - this._maxage = maxAge; - return this; -}, 'send.maxage: pass maxAge as option'); + : Number(maxAge) + this._maxage = !isNaN(this._maxage) + ? Math.min(Math.max(0, this._maxage), maxMaxAge) + : 0 + debug('max-age %d', this._maxage) + return this +}, 'send.maxage: pass maxAge as option') /** * Emit error with `status`. From 9a06ba9532d99aa3285081c0caf75155b114ee08 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 5 Jun 2016 20:56:14 -0400 Subject: [PATCH 095/334] lint: change variable names for constants --- index.js | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index c0f500fb..547690a0 100644 --- a/index.js +++ b/index.js @@ -23,8 +23,6 @@ var escapeHtml = require('escape-html') , fresh = require('fresh') , path = require('path') , fs = require('fs') - , normalize = path.normalize - , join = path.join var etag = require('etag') var EventEmitter = require('events').EventEmitter; var ms = require('ms'); @@ -33,14 +31,36 @@ var statuses = require('statuses') var util = require('util') /** - * Variables. + * Path function references. + * @private */ -var bytesRangeRegexp = /^ *bytes=/ + var extname = path.extname -var maxMaxAge = 60 * 60 * 24 * 365 * 1000; // 1 year +var join = path.join +var normalize = path.normalize var resolve = path.resolve var sep = path.sep -var upPathRegexp = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/ + +/** + * Regular expression for identifying a bytes Range header. + * @private + */ + +var BYTES_RANGE_REGEXP = /^ *bytes=/ + +/** + * Maximum value allowed for the max age. + * @private + */ + +var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000 // 1 year + +/** + * Regular expression to match a path with a directory up component. + * @private + */ + +var UP_PATH_REGEXP = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/ /** * Module exports. @@ -130,7 +150,7 @@ function SendStream(req, path, options) { ? ms(this._maxage) : Number(this._maxage) this._maxage = !isNaN(this._maxage) - ? Math.min(Math.max(0, this._maxage), maxMaxAge) + ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) : 0 this._root = opts.root @@ -226,7 +246,7 @@ SendStream.prototype.maxage = deprecate.function(function maxage (maxAge) { ? ms(maxAge) : Number(maxAge) this._maxage = !isNaN(this._maxage) - ? Math.min(Math.max(0, this._maxage), maxMaxAge) + ? Math.min(Math.max(0, this._maxage), MAX_MAXAGE) : 0 debug('max-age %d', this._maxage) return this @@ -451,7 +471,7 @@ SendStream.prototype.pipe = function(res){ var parts if (root !== null) { // malicious path - if (upPathRegexp.test(normalize('.' + sep + path))) { + if (UP_PATH_REGEXP.test(normalize('.' + sep + path))) { debug('malicious path "%s"', path) return this.error(403) } @@ -464,7 +484,7 @@ SendStream.prototype.pipe = function(res){ parts = path.substr(root.length).split(sep) } else { // ".." is malicious without "root" - if (upPathRegexp.test(path)) { + if (UP_PATH_REGEXP.test(path)) { debug('malicious path "%s"', path) return this.error(403) } @@ -553,7 +573,7 @@ SendStream.prototype.send = function(path, stat){ } // Range support - if (bytesRangeRegexp.test(ranges)) { + if (BYTES_RANGE_REGEXP.test(ranges)) { // parse ranges = parseRange(len, ranges, { combine: true From 22747dfcdcf9fc111f043aa4acd41ecea55adcf4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 5 Jun 2016 21:14:17 -0400 Subject: [PATCH 096/334] tests: use createServer helper in tests where possible --- test/send.js | 247 ++++++++++++++------------------------------------- 1 file changed, 66 insertions(+), 181 deletions(-) diff --git a/test/send.js b/test/send.js index 668c1586..624dcc69 100644 --- a/test/send.js +++ b/test/send.js @@ -322,17 +322,9 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('when no "directory" listeners are present', function(){ - var server - before(function(){ - server = http.createServer(function(req, res){ - send(req, req.url, {root: 'test/fixtures'}) - .pipe(res) - }) - }) - - it('should respond with an HTML redirect', function(done){ - request(server) + describe('when no "directory" listeners are present', function () { + it('should respond with an HTML redirect', function (done) { + request(createServer({root: fixtures})) .get('/pets') .expect('Location', '/pets/') .expect('Content-Type', /html/) @@ -749,15 +741,10 @@ describe('send(file).pipe(res)', function(){ }) }) -describe('send(file, options)', function(){ - describe('etag', function(){ - it('should support disabling etags', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {etag: false, root: fixtures}) - .pipe(res); - }); - - request(app) +describe('send(file, options)', function () { + describe('etag', function () { + it('should support disabling etags', function (done) { + request(createServer({etag: false, root: fixtures})) .get('/nums') .expect(shouldNotHaveHeader('ETag')) .expect(200, done) @@ -766,73 +753,55 @@ describe('send(file, options)', function(){ describe('extensions', function () { it('should reject numbers', function (done) { - var server = createServer({extensions: 42, root: fixtures}) - - request(server) + request(createServer({extensions: 42, root: fixtures})) .get('/pets/') - .expect(500, /TypeError: extensions option/, done); + .expect(500, /TypeError: extensions option/, done) }) it('should reject true', function (done) { - var server = createServer({extensions: true, root: fixtures}) - - request(server) + request(createServer({extensions: true, root: fixtures})) .get('/pets/') - .expect(500, /TypeError: extensions option/, done); + .expect(500, /TypeError: extensions option/, done) }) it('should be not be enabled by default', function (done) { - var server = createServer({root: fixtures}); - - request(server) + request(createServer({root: fixtures})) .get('/tobi') .expect(404, done) }) it('should be configurable', function (done) { - var server = createServer({extensions: 'txt', root: fixtures}) - - request(server) + request(createServer({extensions: 'txt', root: fixtures})) .get('/name') .expect(200, 'tobi', done) }) it('should support disabling extensions', function (done) { - var server = createServer({extensions: false, root: fixtures}) - - request(server) + request(createServer({extensions: false, root: fixtures})) .get('/name') .expect(404, done) }) it('should support fallbacks', function (done) { - var server = createServer({extensions: ['htm', 'html', 'txt'], root: fixtures}) - - request(server) + request(createServer({extensions: ['htm', 'html', 'txt'], root: fixtures})) .get('/name') .expect(200, '

tobi

', done) }) it('should 404 if nothing found', function (done) { - var server = createServer({extensions: ['htm', 'html', 'txt'], root: fixtures}) - - request(server) + request(createServer({extensions: ['htm', 'html', 'txt'], root: fixtures})) .get('/bob') .expect(404, done) }) it('should skip directories', function (done) { - var server = createServer({extensions: ['file', 'dir'], root: fixtures}) - - request(server) + request(createServer({extensions: ['file', 'dir'], root: fixtures})) .get('/name') .expect(404, done) }) it('should not search if file has extension', function (done) { - var server = createServer({extensions: 'html', root: fixtures}) - - request(server) + request(createServer({extensions: 'html', root: fixtures})) .get('/thing.html') .expect(404, done) }) @@ -840,26 +809,16 @@ describe('send(file, options)', function(){ describe('lastModified', function () { it('should support disabling last-modified', function (done) { - var app = http.createServer(function(req, res){ - send(req, req.url, {lastModified: false, root: fixtures}) - .pipe(res) - }) - - request(app) + request(createServer({lastModified: false, root: fixtures})) .get('/nums') .expect(shouldNotHaveHeader('Last-Modified')) .expect(200, done) }) }) - describe('from', function(){ - it('should set with deprecated from', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {from: __dirname + '/fixtures'}) - .pipe(res) - }); - - request(app) + describe('from', function () { + it('should set with deprecated from', function (done) { + request(createServer({from: __dirname + '/fixtures'})) .get('/pets/../name.txt') .expect(200, 'tobi', done) }) @@ -1032,144 +991,90 @@ describe('send(file, options)', function(){ .expect(404, 'Not Found', done) }) - it('should default support sending hidden files', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {hidden: true, root: fixtures}) - .pipe(res); - }); - - request(app) + it('should default support sending hidden files', function (done) { + request(createServer({hidden: true, root: fixtures})) .get('/.hidden') .expect(200, /secret/, done) }) }) - describe('maxAge', function(){ - it('should default to 0', function(done){ - request(app) + describe('maxAge', function () { + it('should default to 0', function (done) { + request(createServer({root: fixtures})) .get('/name.txt') .expect('Cache-Control', 'public, max-age=0', done) }) - it('should floor to integer', function(done){ - var app = http.createServer(function(req, res){ - send(req, 'test/fixtures/name.txt', {maxAge: 123956}) - .pipe(res); - }); - - request(app) + it('should floor to integer', function (done) { + request(createServer({maxAge: 123956, root: fixtures})) .get('/name.txt') .expect('Cache-Control', 'public, max-age=123', done) }) - it('should accept string', function(done){ - var app = http.createServer(function(req, res){ - send(req, 'test/fixtures/name.txt', {maxAge: '30d'}) - .pipe(res); - }); - - request(app) + it('should accept string', function (done) { + request(createServer({maxAge: '30d', root: fixtures})) .get('/name.txt') .expect('Cache-Control', 'public, max-age=2592000', done) }) - it('should max at 1 year', function(done){ - var app = http.createServer(function(req, res){ - send(req, 'test/fixtures/name.txt', {maxAge: Infinity}) - .pipe(res); - }); - - request(app) + it('should max at 1 year', function (done) { + request(createServer({maxAge: Infinity, root: fixtures})) .get('/name.txt') .expect('Cache-Control', 'public, max-age=31536000', done) }) }) - describe('index', function(){ + describe('index', function () { it('should reject numbers', function (done) { - var server = createServer({root: fixtures, index: 42}); - - request(server) + request(createServer({root: fixtures, index: 42})) .get('/pets/') - .expect(500, /TypeError: index option/, done); + .expect(500, /TypeError: index option/, done) }) it('should reject true', function (done) { - var server = createServer({root: fixtures, index: true}); - - request(server) + request(createServer({root: fixtures, index: true})) .get('/pets/') - .expect(500, /TypeError: index option/, done); + .expect(500, /TypeError: index option/, done) }) - it('should default to index.html', function(done){ - request(app) + it('should default to index.html', function (done) { + request(createServer({root: fixtures})) .get('/pets/') .expect(fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) }) - it('should be configurable', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: fixtures, index: 'tobi.html'}) - .pipe(res); - }); - - request(app) + it('should be configurable', function (done) { + request(createServer({root: fixtures, index: 'tobi.html'})) .get('/') - .expect(200, '

tobi

', done); + .expect(200, '

tobi

', done) }) - it('should support disabling', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: fixtures, index: false}) - .pipe(res); - }); - - request(app) + it('should support disabling', function (done) { + request(createServer({root: fixtures, index: false})) .get('/pets/') - .expect(403, done); + .expect(403, done) }) - it('should support fallbacks', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: fixtures, index: ['default.htm', 'index.html']}) - .pipe(res); - }); - - request(app) + it('should support fallbacks', function (done) { + request(createServer({root: fixtures, index: ['default.htm', 'index.html']})) .get('/pets/') .expect(200, fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) }) - it('should 404 if no index file found (file)', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: fixtures, index: 'default.htm'}) - .pipe(res); - }); - - request(app) + it('should 404 if no index file found (file)', function (done) { + request(createServer({root: fixtures, index: 'default.htm'})) .get('/pets/') .expect(404, done) }) - it('should 404 if no index file found (dir)', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: fixtures, index: 'pets'}) - .pipe(res); - }); - - request(app) + it('should 404 if no index file found (dir)', function (done) { + request(createServer({root: fixtures, index: 'pets'})) .get('/') .expect(404, done) }) - it('should not follow directories', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: fixtures, index: ['pets', 'name.txt']}) - .pipe(res); - }); - - request(app) + it('should not follow directories', function (done) { + request(createServer({root: fixtures, index: ['pets', 'name.txt']})) .get('/') .expect(200, 'tobi', done) }) @@ -1187,15 +1092,10 @@ describe('send(file, options)', function(){ }) }) - describe('root', function(){ - describe('when given', function(){ - it('should join root', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: __dirname + '/fixtures'}) - .pipe(res); - }); - - request(app) + describe('root', function () { + describe('when given', function () { + it('should join root', function (done) { + request(createServer({root: fixtures})) .get('/pets/../name.txt') .expect(200, 'tobi', done) }) @@ -1222,13 +1122,8 @@ describe('send(file, options)', function(){ .expect(301, /Redirecting to/, done) }) - it('should restrict paths to within root', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: __dirname + '/fixtures'}) - .pipe(res); - }); - - request(app) + it('should restrict paths to within root', function (done) { + request(createServer({root: fixtures})) .get('/pets/../../send.js') .expect(403, done) }) @@ -1244,24 +1139,14 @@ describe('send(file, options)', function(){ .expect(403, done) }) - it('should not allow root transversal', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: __dirname + '/fixtures/name.d'}) - .pipe(res); - }); - - request(app) + it('should not allow root transversal', function (done) { + request(createServer({root: path.join(fixtures, 'name.d')})) .get('/../name.dir/name.txt') .expect(403, done) }) - it('should not allow root path disclosure', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: __dirname + '/fixtures'}) - .pipe(res); - }); - - request(app) + it('should not allow root path disclosure', function (done) { + request(createServer({root: fixtures})) .get('/pets/../../fixtures/name.txt') .expect(403, done) }) @@ -1327,8 +1212,8 @@ describe('send.mime', function () { }) }) -function createServer(opts, fn) { - return http.createServer(function onRequest(req, res) { +function createServer (opts, fn) { + return http.createServer(function onRequest (req, res) { try { fn && fn(req, res) send(req, req.url, opts).pipe(res) From 74245556fd270ac6cd11ccde9a5e6094d015bb8e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 6 Jun 2016 17:59:43 -0400 Subject: [PATCH 097/334] Add acceptRanges option --- HISTORY.md | 1 + README.md | 6 ++++++ index.js | 25 +++++++++++++++++-------- test/send.js | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 4a5bff57..591ceb3f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Add `acceptRanges` option * Attempt to combine multiple ranges into single range * Correctly inherit from `Stream` class * Fix `Content-Range` header in 416 responses when using `start`/`end` options diff --git a/README.md b/README.md index d2415559..bd81b10b 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,12 @@ not the actual file-system path). #### Options +##### acceptRanges + +Enable or disable accepting ranged requests, defaults to true. +Disabling this will not send `Accept-Ranges` and ignore the contents +of the `Range` request header. + ##### dotfiles Set how "dotfiles" are treated when encountered. A dotfile is a file diff --git a/index.js b/index.js index 547690a0..77fd489c 100644 --- a/index.js +++ b/index.js @@ -110,6 +110,10 @@ function SendStream(req, path, options) { this.path = path this.req = req + this._acceptRanges = opts.acceptRanges !== undefined + ? Boolean(opts.acceptRanges) + : true + this._etag = opts.etag !== undefined ? Boolean(opts.etag) : true @@ -573,7 +577,7 @@ SendStream.prototype.send = function(path, stat){ } // Range support - if (BYTES_RANGE_REGEXP.test(ranges)) { + if (this._acceptRanges && BYTES_RANGE_REGEXP.test(ranges)) { // parse ranges = parseRange(len, ranges, { combine: true @@ -581,13 +585,13 @@ SendStream.prototype.send = function(path, stat){ // If-Range support if (!this.isRangeFresh()) { - debug('range stale'); - ranges = -2; + debug('range stale') + ranges = -2 } // unsatisfiable if (-1 == ranges) { - debug('range unsatisfiable'); + debug('range unsatisfiable') // Content-Range res.setHeader('Content-Range', contentRange('bytes', len)) @@ -600,14 +604,15 @@ SendStream.prototype.send = function(path, stat){ // valid (syntactically invalid/multiple ranges are treated as a regular response) if (-2 != ranges && ranges.length === 1) { - debug('range %j', ranges); + debug('range %j', ranges) // Content-Range res.statusCode = 206 res.setHeader('Content-Range', contentRange('bytes', len, ranges[0])) - offset += ranges[0].start; - len = ranges[0].end - ranges[0].start + 1; + // adjust for requested range + offset += ranges[0].start + len = ranges[0].end - ranges[0].start + 1 } } @@ -786,7 +791,11 @@ SendStream.prototype.setHeader = function setHeader(path, stat){ this.emit('headers', res, path, stat); - if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes'); + if (this._acceptRanges && !res.getHeader('Accept-Ranges')) { + debug('accept ranges') + res.setHeader('Accept-Ranges', 'bytes') + } + if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + Math.floor(this._maxage / 1000)); if (this._lastModified && !res.getHeader('Last-Modified')) { diff --git a/test/send.js b/test/send.js index 624dcc69..68f162a4 100644 --- a/test/send.js +++ b/test/send.js @@ -742,6 +742,24 @@ describe('send(file).pipe(res)', function(){ }) describe('send(file, options)', function () { + describe('acceptRanges', function () { + it('should support disabling accept-ranges', function (done) { + request(createServer({acceptRanges: false, root: fixtures})) + .get('/nums') + .expect(shouldNotHaveHeader('Accept-Ranges')) + .expect(200, done) + }) + + it('should ignore requested range', function (done) { + request(createServer({acceptRanges: false, root: fixtures})) + .get('/nums') + .set('Range', 'bytes=0-2') + .expect(shouldNotHaveHeader('Accept-Ranges')) + .expect(shouldNotHaveHeader('Content-Range')) + .expect(200, '123456789', done) + }) + }) + describe('etag', function () { it('should support disabling etags', function (done) { request(createServer({etag: false, root: fixtures})) From 2554b1d0613c04d844f6d826838d8fcc0eceea8c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 6 Jun 2016 18:12:10 -0400 Subject: [PATCH 098/334] Add cacheControl option closes #110 --- HISTORY.md | 1 + README.md | 5 +++++ index.js | 10 +++++++++- test/send.js | 16 ++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 591ceb3f..e33a4ff6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Add `acceptRanges` option + * Add `cacheControl` option * Attempt to combine multiple ranges into single range * Correctly inherit from `Stream` class * Fix `Content-Range` header in 416 responses when using `start`/`end` options diff --git a/README.md b/README.md index bd81b10b..c9aefd67 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,11 @@ Enable or disable accepting ranged requests, defaults to true. Disabling this will not send `Accept-Ranges` and ignore the contents of the `Range` request header. +##### cacheControl + +Enable or disable setting `Cache-Control` response header, defaults to +true. Disabling this will ignore the `maxAge` option. + ##### dotfiles Set how "dotfiles" are treated when encountered. A dotfile is a file diff --git a/index.js b/index.js index 77fd489c..5b2c89c8 100644 --- a/index.js +++ b/index.js @@ -114,6 +114,10 @@ function SendStream(req, path, options) { ? Boolean(opts.acceptRanges) : true + this._cacheControl = opts.cacheControl !== undefined + ? Boolean(opts.cacheControl) + : true + this._etag = opts.etag !== undefined ? Boolean(opts.etag) : true @@ -796,7 +800,11 @@ SendStream.prototype.setHeader = function setHeader(path, stat){ res.setHeader('Accept-Ranges', 'bytes') } - if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + Math.floor(this._maxage / 1000)); + if (this._cacheControl && !res.getHeader('Cache-Control')) { + var cacheControl = 'public, max-age=' + Math.floor(this._maxage / 1000) + debug('cache-control %s', cacheControl) + res.setHeader('Cache-Control', cacheControl) + } if (this._lastModified && !res.getHeader('Last-Modified')) { var modified = stat.mtime.toUTCString() diff --git a/test/send.js b/test/send.js index 68f162a4..13c63a90 100644 --- a/test/send.js +++ b/test/send.js @@ -760,6 +760,22 @@ describe('send(file, options)', function () { }) }) + describe('cacheControl', function () { + it('should support disabling cache-control', function (done) { + request(createServer({cacheControl: false, root: fixtures})) + .get('/nums') + .expect(shouldNotHaveHeader('Cache-Control')) + .expect(200, done) + }) + + it('should ignore maxAge option', function (done) { + request(createServer({cacheControl: false, maxAge: 1000, root: fixtures})) + .get('/nums') + .expect(shouldNotHaveHeader('Cache-Control')) + .expect(200, done) + }) + }) + describe('etag', function () { it('should support disabling etags', function (done) { request(createServer({etag: false, root: fixtures})) From 9bb9613537d71c460bd2e831ab92d60e3726537a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 6 Jun 2016 18:39:29 -0400 Subject: [PATCH 099/334] lint: use standard style --- .eslintignore | 2 + .eslintrc | 3 + .travis.yml | 3 +- appveyor.yml | 1 + index.js | 316 ++++++++++++++++++----------------- package.json | 5 + test/.eslintrc | 5 + test/send.js | 442 ++++++++++++++++++++++++------------------------- 8 files changed, 404 insertions(+), 373 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 test/.eslintrc diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..62562b74 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +coverage +node_modules diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..e3578aad --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "standard" +} diff --git a/.travis.yml b/.travis.yml index 4c12100c..29cc058d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ cache: - node_modules before_install: # Setup Node.js version-specific dependencies - - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" + - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev eslint eslint-config-standard eslint-plugin-promise eslint-plugin-standard istanbul" # Update Node.js modules - "test ! -d node_modules || npm prune" @@ -24,5 +24,6 @@ script: # Run test script, depending on istanbul install - "test ! -z $(npm -ps ls istanbul) || npm test" - "test -z $(npm -ps ls istanbul) || npm run-script test-ci" + - "test -z $(npm -ps ls eslint ) || npm run-script lint" after_script: - "test -e ./coverage/lcov.info && npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" diff --git a/appveyor.yml b/appveyor.yml index 2985afa7..fc3c9ab5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,7 @@ cache: install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul + - npm rm --save-dev eslint eslint-config-standard eslint-plugin-promise eslint-plugin-standard - if exist node_modules npm prune - if exist node_modules npm rebuild - npm install diff --git a/index.js b/index.js index 5b2c89c8..34ed8924 100644 --- a/index.js +++ b/index.js @@ -17,17 +17,17 @@ var debug = require('debug')('send') var deprecate = require('depd')('send') var destroy = require('destroy') var escapeHtml = require('escape-html') - , parseRange = require('range-parser') - , Stream = require('stream') - , mime = require('mime') - , fresh = require('fresh') - , path = require('path') - , fs = require('fs') var etag = require('etag') -var EventEmitter = require('events').EventEmitter; -var ms = require('ms'); +var EventEmitter = require('events').EventEmitter +var fresh = require('fresh') +var fs = require('fs') +var mime = require('mime') +var ms = require('ms') var onFinished = require('on-finished') +var parseRange = require('range-parser') +var path = require('path') var statuses = require('statuses') +var Stream = require('stream') var util = require('util') /** @@ -75,8 +75,8 @@ module.exports.mime = mime */ /* istanbul ignore next */ -var listenerCount = EventEmitter.listenerCount - || function(emitter, type){ return emitter.listeners(type).length; }; +var listenerCount = EventEmitter.listenerCount || + function (emitter, type) { return emitter.listeners(type).length } /** * Return a `SendStream` for `req` and `path`. @@ -88,8 +88,8 @@ var listenerCount = EventEmitter.listenerCount * @public */ -function send(req, path, options) { - return new SendStream(req, path, options); +function send (req, path, options) { + return new SendStream(req, path, options) } /** @@ -101,7 +101,7 @@ function send(req, path, options) { * @private */ -function SendStream(req, path, options) { +function SendStream (req, path, options) { Stream.call(this) var opts = options || {} @@ -214,12 +214,12 @@ SendStream.prototype.hidden = deprecate.function(function hidden (val) { * @api public */ -SendStream.prototype.index = deprecate.function(function index(paths) { - var index = !paths ? [] : normalizeList(paths, 'paths argument'); - debug('index %o', paths); - this._index = index; - return this; -}, 'send.index: pass index as option'); +SendStream.prototype.index = deprecate.function(function index (paths) { + var index = !paths ? [] : normalizeList(paths, 'paths argument') + debug('index %o', paths) + this._index = index + return this +}, 'send.index: pass index as option') /** * Set root `path`. @@ -236,10 +236,10 @@ SendStream.prototype.root = function root (path) { } SendStream.prototype.from = deprecate.function(SendStream.prototype.root, - 'send.from: pass root as option'); + 'send.from: pass root as option') SendStream.prototype.root = deprecate.function(SendStream.prototype.root, - 'send.root: pass root as option'); + 'send.root: pass root as option') /** * Set max-age to `maxAge`. @@ -268,7 +268,7 @@ SendStream.prototype.maxage = deprecate.function(function maxage (maxAge) { * @private */ -SendStream.prototype.error = function error(status, error) { +SendStream.prototype.error = function error (status, error) { // emit if listeners instead of responding if (listenerCount(this, 'error') !== 0) { return this.emit('error', createError(error, status, { @@ -302,9 +302,9 @@ SendStream.prototype.error = function error(status, error) { * @api private */ -SendStream.prototype.hasTrailingSlash = function(){ - return '/' == this.path[this.path.length - 1]; -}; +SendStream.prototype.hasTrailingSlash = function hasTrailingSlash () { + return this.path[this.path.length - 1] === '/' +} /** * Check if this is a conditional GET request. @@ -313,10 +313,10 @@ SendStream.prototype.hasTrailingSlash = function(){ * @api private */ -SendStream.prototype.isConditionalGET = function(){ - return this.req.headers['if-none-match'] - || this.req.headers['if-modified-since']; -}; +SendStream.prototype.isConditionalGET = function isConditionalGET () { + return this.req.headers['if-none-match'] || + this.req.headers['if-modified-since'] +} /** * Strip content-* header fields. @@ -324,7 +324,7 @@ SendStream.prototype.isConditionalGET = function(){ * @private */ -SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields() { +SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields () { var res = this.res var headers = Object.keys(res._headers || {}) @@ -342,13 +342,13 @@ SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFie * @api private */ -SendStream.prototype.notModified = function(){ - var res = this.res; - debug('not modified'); - this.removeContentHeaderFields(); - res.statusCode = 304; - res.end(); -}; +SendStream.prototype.notModified = function notModified () { + var res = this.res + debug('not modified') + this.removeContentHeaderFields() + res.statusCode = 304 + res.end() +} /** * Raise error that headers already sent. @@ -356,11 +356,11 @@ SendStream.prototype.notModified = function(){ * @api private */ -SendStream.prototype.headersAlreadySent = function headersAlreadySent(){ - var err = new Error('Can\'t set headers after they are sent.'); - debug('headers already sent'); - this.error(500, err); -}; +SendStream.prototype.headersAlreadySent = function headersAlreadySent () { + var err = new Error('Can\'t set headers after they are sent.') + debug('headers already sent') + this.error(500, err) +} /** * Check if the request is cacheable, aka @@ -370,10 +370,11 @@ SendStream.prototype.headersAlreadySent = function headersAlreadySent(){ * @api private */ -SendStream.prototype.isCachable = function(){ - var res = this.res; - return (res.statusCode >= 200 && res.statusCode < 300) || 304 == res.statusCode; -}; +SendStream.prototype.isCachable = function isCachable () { + var statusCode = this.res.statusCode + return (statusCode >= 200 && statusCode < 300) || + statusCode === 304 +} /** * Handle stat() error. @@ -382,7 +383,7 @@ SendStream.prototype.isCachable = function(){ * @private */ -SendStream.prototype.onStatError = function onStatError(error) { +SendStream.prototype.onStatError = function onStatError (error) { switch (error.code) { case 'ENAMETOOLONG': case 'ENOENT': @@ -402,9 +403,9 @@ SendStream.prototype.onStatError = function onStatError(error) { * @api private */ -SendStream.prototype.isFresh = function(){ - return fresh(this.req.headers, this.res._headers); -}; +SendStream.prototype.isFresh = function isFresh () { + return fresh(this.req.headers, this.res._headers) +} /** * Check if the range is fresh. @@ -413,15 +414,17 @@ SendStream.prototype.isFresh = function(){ * @api private */ -SendStream.prototype.isRangeFresh = function isRangeFresh(){ - var ifRange = this.req.headers['if-range']; +SendStream.prototype.isRangeFresh = function isRangeFresh () { + var ifRange = this.req.headers['if-range'] - if (!ifRange) return true; + if (!ifRange) { + return true + } return ~ifRange.indexOf('"') ? ~ifRange.indexOf(this.res._headers['etag']) - : Date.parse(this.res._headers['last-modified']) <= Date.parse(ifRange); -}; + : Date.parse(this.res._headers['last-modified']) <= Date.parse(ifRange) +} /** * Redirect to path. @@ -430,7 +433,7 @@ SendStream.prototype.isRangeFresh = function isRangeFresh(){ * @private */ -SendStream.prototype.redirect = function redirect(path) { +SendStream.prototype.redirect = function redirect (path) { if (listenerCount(this, 'directory') !== 0) { this.emit('directory') return @@ -462,26 +465,33 @@ SendStream.prototype.redirect = function redirect(path) { * @api public */ -SendStream.prototype.pipe = function(res){ +SendStream.prototype.pipe = function pipe (res) { // root path var root = this._root // references - this.res = res; + this.res = res // decode the path var path = decode(this.path) - if (path === -1) return this.error(400) + if (path === -1) { + this.error(400) + return res + } // null byte(s) - if (~path.indexOf('\0')) return this.error(400); + if (~path.indexOf('\0')) { + this.error(400) + return res + } var parts if (root !== null) { // malicious path if (UP_PATH_REGEXP.test(normalize('.' + sep + path))) { debug('malicious path "%s"', path) - return this.error(403) + this.error(403) + return res } // join / normalize from optional root dir @@ -494,7 +504,8 @@ SendStream.prototype.pipe = function(res){ // ".." is malicious without "root" if (UP_PATH_REGEXP.test(path)) { debug('malicious path "%s"', path) - return this.error(403) + this.error(403) + return res } // explode path parts @@ -520,22 +531,24 @@ SendStream.prototype.pipe = function(res){ case 'allow': break case 'deny': - return this.error(403) + this.error(403) + return res case 'ignore': default: - return this.error(404) + this.error(404) + return res } } // index file support if (this._index.length && this.path[this.path.length - 1] === '/') { - this.sendIndex(path); - return res; + this.sendIndex(path) + return res } - this.sendFile(path); - return res; -}; + this.sendFile(path) + return res +} /** * Transfer `path`. @@ -544,40 +557,40 @@ SendStream.prototype.pipe = function(res){ * @api public */ -SendStream.prototype.send = function(path, stat){ - var len = stat.size; +SendStream.prototype.send = function send (path, stat) { + var len = stat.size var options = this.options var opts = {} - var res = this.res; - var req = this.req; - var ranges = req.headers.range; - var offset = options.start || 0; + var res = this.res + var req = this.req + var ranges = req.headers.range + var offset = options.start || 0 if (res._header) { // impossible to send now - return this.headersAlreadySent(); + this.headersAlreadySent() + return } debug('pipe "%s"', path) // set header fields - this.setHeader(path, stat); + this.setHeader(path, stat) // set content-type - this.type(path); + this.type(path) // conditional GET support - if (this.isConditionalGET() - && this.isCachable() - && this.isFresh()) { - return this.notModified(); + if (this.isConditionalGET() && this.isCachable() && this.isFresh()) { + this.notModified() + return } // adjust len to start/end options - len = Math.max(0, len - offset); + len = Math.max(0, len - offset) if (options.end !== undefined) { - var bytes = options.end - offset + 1; - if (len > bytes) len = bytes; + var bytes = options.end - offset + 1 + if (len > bytes) len = bytes } // Range support @@ -594,7 +607,7 @@ SendStream.prototype.send = function(path, stat){ } // unsatisfiable - if (-1 == ranges) { + if (ranges === -1) { debug('range unsatisfiable') // Content-Range @@ -607,7 +620,7 @@ SendStream.prototype.send = function(path, stat){ } // valid (syntactically invalid/multiple ranges are treated as a regular response) - if (-2 != ranges && ranges.length === 1) { + if (ranges !== -2 && ranges.length === 1) { debug('range %j', ranges) // Content-Range @@ -630,13 +643,16 @@ SendStream.prototype.send = function(path, stat){ opts.end = Math.max(offset, offset + len - 1) // content-length - res.setHeader('Content-Length', len); + res.setHeader('Content-Length', len) // HEAD support - if ('HEAD' == req.method) return res.end(); + if (req.method === 'HEAD') { + res.end() + return + } this.stream(path, opts) -}; +} /** * Transfer file for `path`. @@ -644,15 +660,13 @@ SendStream.prototype.send = function(path, stat){ * @param {String} path * @api private */ -SendStream.prototype.sendFile = function sendFile(path) { +SendStream.prototype.sendFile = function sendFile (path) { var i = 0 var self = this - debug('stat "%s"', path); - fs.stat(path, function onstat(err, stat) { - if (err && err.code === 'ENOENT' - && !extname(path) - && path[path.length - 1] !== sep) { + debug('stat "%s"', path) + fs.stat(path, function onstat (err, stat) { + if (err && err.code === 'ENOENT' && !extname(path) && path[path.length - 1] !== sep) { // not found, check extensions return next(err) } @@ -662,7 +676,7 @@ SendStream.prototype.sendFile = function sendFile(path) { self.send(path, stat) }) - function next(err) { + function next (err) { if (self._extensions.length <= i) { return err ? self.onStatError(err) @@ -687,29 +701,29 @@ SendStream.prototype.sendFile = function sendFile(path) { * @param {String} path * @api private */ -SendStream.prototype.sendIndex = function sendIndex(path){ - var i = -1; - var self = this; +SendStream.prototype.sendIndex = function sendIndex (path) { + var i = -1 + var self = this - function next(err){ + function next (err) { if (++i >= self._index.length) { - if (err) return self.onStatError(err); - return self.error(404); + if (err) return self.onStatError(err) + return self.error(404) } - var p = join(path, self._index[i]); + var p = join(path, self._index[i]) - debug('stat "%s"', p); - fs.stat(p, function(err, stat){ - if (err) return next(err); - if (stat.isDirectory()) return next(); - self.emit('file', p, stat); - self.send(p, stat); - }); + debug('stat "%s"', p) + fs.stat(p, function (err, stat) { + if (err) return next(err) + if (stat.isDirectory()) return next() + self.emit('file', p, stat) + self.send(p, stat) + }) } - next(); -}; + next() +} /** * Stream `path` to the response. @@ -719,41 +733,41 @@ SendStream.prototype.sendIndex = function sendIndex(path){ * @api private */ -SendStream.prototype.stream = function(path, options){ +SendStream.prototype.stream = function stream (path, options) { // TODO: this is all lame, refactor meeee - var finished = false; - var self = this; - var res = this.res; + var finished = false + var self = this + var res = this.res // pipe - var stream = fs.createReadStream(path, options); - this.emit('stream', stream); - stream.pipe(res); + var stream = fs.createReadStream(path, options) + this.emit('stream', stream) + stream.pipe(res) // response finished, done with the fd - onFinished(res, function onfinished(){ - finished = true; - destroy(stream); - }); + onFinished(res, function onfinished () { + finished = true + destroy(stream) + }) // error handling code-smell - stream.on('error', function onerror(err){ + stream.on('error', function onerror (err) { // request already finished - if (finished) return; + if (finished) return // clean up stream - finished = true; - destroy(stream); + finished = true + destroy(stream) // error - self.onStatError(err); - }); + self.onStatError(err) + }) // end - stream.on('end', function onend(){ - self.emit('end'); - }); -}; + stream.on('end', function onend () { + self.emit('end') + }) +} /** * Set content-type based on `path` @@ -763,23 +777,23 @@ SendStream.prototype.stream = function(path, options){ * @api private */ -SendStream.prototype.type = function type(path) { - var res = this.res; +SendStream.prototype.type = function type (path) { + var res = this.res - if (res.getHeader('Content-Type')) return; + if (res.getHeader('Content-Type')) return - var type = mime.lookup(path); + var type = mime.lookup(path) if (!type) { - debug('no content-type'); - return; + debug('no content-type') + return } - var charset = mime.charsets.lookup(type); + var charset = mime.charsets.lookup(type) - debug('content-type %s', type); - res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')); -}; + debug('content-type %s', type) + res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : '')) +} /** * Set response header fields, most @@ -790,10 +804,10 @@ SendStream.prototype.type = function type(path) { * @api private */ -SendStream.prototype.setHeader = function setHeader(path, stat){ - var res = this.res; +SendStream.prototype.setHeader = function setHeader (path, stat) { + var res = this.res - this.emit('headers', res, path, stat); + this.emit('headers', res, path, stat) if (this._acceptRanges && !res.getHeader('Accept-Ranges')) { debug('accept ranges') @@ -817,7 +831,7 @@ SendStream.prototype.setHeader = function setHeader(path, stat){ debug('etag %s', val) res.setHeader('ETag', val) } -}; +} /** * Clear all headers from a response. @@ -837,7 +851,7 @@ function clearHeaders (res) { * @api private */ -function containsDotFile(parts) { +function containsDotFile (parts) { for (var i = 0; i < parts.length; i++) { if (parts[i][0] === '.') { return true @@ -869,7 +883,7 @@ function contentRange (type, size, range) { * @api private */ -function decode(path) { +function decode (path) { try { return decodeURIComponent(path) } catch (err) { @@ -885,7 +899,7 @@ function decode(path) { * @private */ -function normalizeList(val, name) { +function normalizeList (val, name) { var list = [].concat(val || []) for (var i = 0; i < list.length; i++) { diff --git a/package.json b/package.json index f5ba534a..6f9f36a5 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,10 @@ }, "devDependencies": { "after": "0.8.1", + "eslint": "2.11.1", + "eslint-config-standard": "5.3.1", + "eslint-plugin-promise": "1.3.1", + "eslint-plugin-standard": "1.3.2", "istanbul": "0.4.3", "mocha": "2.5.3", "supertest": "1.1.0" @@ -43,6 +47,7 @@ "node": ">= 0.8.0" }, "scripts": { + "lint": "eslint **/*.js", "test": "mocha --check-leaks --reporter spec --bail", "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot" diff --git a/test/.eslintrc b/test/.eslintrc new file mode 100644 index 00000000..7eeefc33 --- /dev/null +++ b/test/.eslintrc @@ -0,0 +1,5 @@ +{ + "env": { + "mocha": true + } +} diff --git a/test/send.js b/test/send.js index 13c63a90..b5820be3 100644 --- a/test/send.js +++ b/test/send.js @@ -1,38 +1,38 @@ -process.env.NO_DEPRECATION = 'send'; - -var after = require('after'); -var assert = require('assert'); -var fs = require('fs'); -var http = require('http'); -var path = require('path'); -var request = require('supertest'); +process.env.NO_DEPRECATION = 'send' + +var after = require('after') +var assert = require('assert') +var fs = require('fs') +var http = require('http') +var path = require('path') +var request = require('supertest') var send = require('..') // test server -var dateRegExp = /^\w{3}, \d+ \w+ \d+ \d+:\d+:\d+ \w+$/; -var fixtures = path.join(__dirname, 'fixtures'); -var app = http.createServer(function(req, res){ - function error(err) { - res.statusCode = err.status; - res.end(http.STATUS_CODES[err.status]); +var dateRegExp = /^\w{3}, \d+ \w+ \d+ \d+:\d+:\d+ \w+$/ +var fixtures = path.join(__dirname, 'fixtures') +var app = http.createServer(function (req, res) { + function error (err) { + res.statusCode = err.status + res.end(http.STATUS_CODES[err.status]) } - function redirect() { - res.statusCode = 301; - res.setHeader('Location', req.url + '/'); - res.end('Redirecting to ' + req.url + '/'); + function redirect () { + res.statusCode = 301 + res.setHeader('Location', req.url + '/') + res.end('Redirecting to ' + req.url + '/') } send(req, req.url, {root: fixtures}) .on('error', error) .on('directory', redirect) - .pipe(res); -}); + .pipe(res) +}) -describe('send(file).pipe(res)', function(){ - it('should stream the file contents', function(done){ +describe('send(file).pipe(res)', function () { + it('should stream the file contents', function (done) { request(app) .get('/name.txt') .expect('Content-Length', '4') @@ -46,82 +46,82 @@ describe('send(file).pipe(res)', function(){ .expect(200, '', done) }) - it('should decode the given path as a URI', function(done){ + it('should decode the given path as a URI', function (done) { request(app) .get('/some%20thing.txt') .expect(200, 'hey', done) }) - it('should serve files with dots in name', function(done){ + it('should serve files with dots in name', function (done) { request(app) .get('/do..ts.txt') .expect(200, '...', done) }) - it('should treat a malformed URI as a bad request', function(done){ + it('should treat a malformed URI as a bad request', function (done) { request(app) .get('/some%99thing.txt') .expect(400, 'Bad Request', done) }) - it('should 400 on NULL bytes', function(done){ + it('should 400 on NULL bytes', function (done) { request(app) .get('/some%00thing.txt') .expect(400, 'Bad Request', done) }) - it('should treat an ENAMETOOLONG as a 404', function(done){ - var path = Array(100).join('foobar'); + it('should treat an ENAMETOOLONG as a 404', function (done) { + var path = Array(100).join('foobar') request(app) .get('/' + path) - .expect(404, done); + .expect(404, done) }) - it('should handle headers already sent error', function(done){ - var app = http.createServer(function(req, res){ - res.write('0'); + it('should handle headers already sent error', function (done) { + var app = http.createServer(function (req, res) { + res.write('0') send(req, req.url, {root: fixtures}) - .on('error', function(err){ res.end(' - ' + err.message) }) - .pipe(res); - }); + .on('error', function (err) { res.end(' - ' + err.message) }) + .pipe(res) + }) request(app) .get('/nums') - .expect(200, '0 - Can\'t set headers after they are sent.', done); + .expect(200, '0 - Can\'t set headers after they are sent.', done) }) - it('should support HEAD', function(done){ + it('should support HEAD', function (done) { request(app) .head('/name.txt') .expect('Content-Length', '4') .expect(200, '', done) }) - it('should add an ETag header field', function(done){ + it('should add an ETag header field', function (done) { request(app) .get('/name.txt') .expect('etag', /^W\/"[^"]+"$/) - .end(done); + .end(done) }) - it('should add a Date header field', function(done){ + it('should add a Date header field', function (done) { request(app) .get('/name.txt') .expect('date', dateRegExp, done) }) - it('should add a Last-Modified header field', function(done){ + it('should add a Last-Modified header field', function (done) { request(app) .get('/name.txt') .expect('last-modified', dateRegExp, done) }) - it('should add a Accept-Ranges header field', function(done){ + it('should add a Accept-Ranges header field', function (done) { request(app) .get('/name.txt') .expect('Accept-Ranges', 'bytes', done) }) - it('should 404 if the file does not exist', function(done){ + it('should 404 if the file does not exist', function (done) { request(app) .get('/meow') .expect(404, 'Not Found', done) @@ -139,71 +139,71 @@ describe('send(file).pipe(res)', function(){ .expect(200, '404 ENOENT', done) }) - it('should 301 if the directory exists', function(done){ + it('should 301 if the directory exists', function (done) { request(app) .get('/pets') .expect('Location', '/pets/') .expect(301, 'Redirecting to /pets/', done) }) - it('should not override content-type', function(done){ - var app = http.createServer(function(req, res){ + it('should not override content-type', function (done) { + var app = http.createServer(function (req, res) { res.setHeader('Content-Type', 'application/x-custom') send(req, req.url, {root: fixtures}).pipe(res) - }); + }) request(app) .get('/nums') - .expect('Content-Type', 'application/x-custom', done); + .expect('Content-Type', 'application/x-custom', done) }) - it('should set Content-Type via mime map', function(done){ + it('should set Content-Type via mime map', function (done) { request(app) .get('/name.txt') .expect('Content-Type', 'text/plain; charset=UTF-8') - .expect(200, function(err){ + .expect(200, function (err) { if (err) return done(err) request(app) .get('/tobi.html') .expect('Content-Type', 'text/html; charset=UTF-8') .expect(200, done) - }); + }) }) - it('should 404 if file disappears after stat, before open', function(done){ - var app = http.createServer(function(req, res){ + it('should 404 if file disappears after stat, before open', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url, {root: 'test/fixtures'}) - .on('file', function(){ + .on('file', function () { // simulate file ENOENT after on open, after stat - var fn = this.send; - this.send = function(path, stat){ - path += '__xxx_no_exist'; - fn.call(this, path, stat); - }; + var fn = this.send + this.send = function (path, stat) { + path += '__xxx_no_exist' + fn.call(this, path, stat) + } }) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/name.txt') .expect('Content-Type', /plain/) - .expect(404, done); + .expect(404, done) }) - it('should 500 on file stream error', function(done){ - var app = http.createServer(function(req, res){ + it('should 500 on file stream error', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url, {root: 'test/fixtures'}) - .on('stream', function(stream){ + .on('stream', function (stream) { // simulate file error - process.nextTick(function(){ - stream.emit('error', new Error('boom!')); - }); + process.nextTick(function () { + stream.emit('error', new Error('boom!')) + }) }) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/name.txt') - .expect(500, done); + .expect(500, done) }) describe('"headers" event', function () { @@ -267,7 +267,7 @@ describe('send(file).pipe(res)', function(){ .pipe(res) }) - function onHeaders(res, filePath) { + function onHeaders (res, filePath) { assert.ok(filePath) assert.equal(path.normalize(filePath), path.normalize(path.join(fixtures, 'nums'))) cb() @@ -286,7 +286,7 @@ describe('send(file).pipe(res)', function(){ .pipe(res) }) - function onHeaders(res, path, stat) { + function onHeaders (res, path, stat) { assert.ok(stat) assert.ok('ctime' in stat) assert.ok('mtime' in stat) @@ -305,7 +305,7 @@ describe('send(file).pipe(res)', function(){ .pipe(res) }) - function onHeaders(res, path, stat) { + function onHeaders (res, path, stat) { res.setHeader('Cache-Control', 'no-cache') res.setHeader('Content-Type', 'text/x-custom') res.setHeader('ETag', 'W/"everything"') @@ -332,19 +332,19 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('when no "error" listeners are present', function(){ - it('should respond to errors directly', function(done){ + describe('when no "error" listeners are present', function () { + it('should respond to errors directly', function (done) { request(createServer({root: fixtures})) .get('/foobar') .expect(404, 'Not Found', done) }) }) - describe('with conditional-GET', function(){ - it('should respond with 304 on a match', function(done){ + describe('with conditional-GET', function () { + it('should respond with 304 on a match', function (done) { request(app) .get('/name.txt') - .expect(200, function(err, res){ + .expect(200, function (err, res) { if (err) return done(err) request(app) .get('/name.txt') @@ -353,10 +353,10 @@ describe('send(file).pipe(res)', function(){ }) }) - it('should respond with 200 otherwise', function(done){ + it('should respond with 200 otherwise', function (done) { request(app) .get('/name.txt') - .expect(200, function(err, res){ + .expect(200, function (err, res) { if (err) return done(err) request(app) .get('/name.txt') @@ -389,12 +389,12 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('with Range request', function(){ - it('should support byte ranges', function(done){ + describe('with Range request', function () { + it('should support byte ranges', function (done) { request(app) .get('/nums') .set('Range', 'bytes=0-4') - .expect(206, '12345', done); + .expect(206, '12345', done) }) it('should ignore non-byte ranges', function (done) { @@ -404,13 +404,13 @@ describe('send(file).pipe(res)', function(){ .expect(200, '123456789', done) }) - it('should be inclusive', function(done){ + it('should be inclusive', function (done) { request(app) .get('/nums') .set('Range', 'bytes=0-0') - .expect(206, '1', done); + .expect(206, '1', done) }) - + it('should set Content-Range', function (done) { request(app) .get('/nums') @@ -419,79 +419,79 @@ describe('send(file).pipe(res)', function(){ .expect(206, done) }) - it('should support -n', function(done){ + it('should support -n', function (done) { request(app) .get('/nums') .set('Range', 'bytes=-3') - .expect(206, '789', done); + .expect(206, '789', done) }) - - it('should support n-', function(done){ + + it('should support n-', function (done) { request(app) .get('/nums') .set('Range', 'bytes=3-') - .expect(206, '456789', done); + .expect(206, '456789', done) }) - it('should respond with 206 "Partial Content"', function(done){ + it('should respond with 206 "Partial Content"', function (done) { request(app) .get('/nums') .set('Range', 'bytes=0-4') - .expect(206, done); + .expect(206, done) }) - it('should set Content-Length to the # of octets transferred', function(done){ + it('should set Content-Length to the # of octets transferred', function (done) { request(app) .get('/nums') .set('Range', 'bytes=2-3') .expect('Content-Length', '2') - .expect(206, '34', done); + .expect(206, '34', done) }) - describe('when last-byte-pos of the range is greater the length', function(){ - it('is taken to be equal to one less than the length', function(done){ + describe('when last-byte-pos of the range is greater the length', function () { + it('is taken to be equal to one less than the length', function (done) { request(app) .get('/nums') .set('Range', 'bytes=2-50') .expect('Content-Range', 'bytes 2-8/9') - .expect(206, done); + .expect(206, done) }) - it('should adapt the Content-Length accordingly', function(done){ + it('should adapt the Content-Length accordingly', function (done) { request(app) .get('/nums') .set('Range', 'bytes=2-50') .expect('Content-Length', '7') - .expect(206, done); + .expect(206, done) }) }) - describe('when the first- byte-pos of the range is greater length', function(){ - it('should respond with 416', function(done){ + describe('when the first- byte-pos of the range is greater length', function () { + it('should respond with 416', function (done) { request(app) .get('/nums') .set('Range', 'bytes=9-50') .expect('Content-Range', 'bytes */9') - .expect(416, done); + .expect(416, done) }) }) - describe('when syntactically invalid', function(){ - it('should respond with 200 and the entire contents', function(done){ + describe('when syntactically invalid', function () { + it('should respond with 200 and the entire contents', function (done) { request(app) .get('/nums') .set('Range', 'asdf') - .expect(200, '123456789', done); + .expect(200, '123456789', done) }) }) - describe('when multiple ranges', function(){ - it('should respond with 200 and the entire contents', function(done){ + describe('when multiple ranges', function () { + it('should respond with 200 and the entire contents', function (done) { request(app) .get('/nums') .set('Range', 'bytes=1-1,3-') .expect(shouldNotHaveHeader('Content-Range')) - .expect(200, '123456789', done); + .expect(200, '123456789', done) }) it('should respond with 206 is all ranges can be combined', function (done) { @@ -503,70 +503,70 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('when if-range present', function(){ - it('should respond with parts when etag unchanged', function(done){ + describe('when if-range present', function () { + it('should respond with parts when etag unchanged', function (done) { request(app) .get('/nums') - .expect(200, function(err, res){ - if (err) return done(err); - var etag = res.headers.etag; + .expect(200, function (err, res) { + if (err) return done(err) + var etag = res.headers.etag request(app) .get('/nums') .set('If-Range', etag) .set('Range', 'bytes=0-0') - .expect(206, '1', done); + .expect(206, '1', done) }) }) - it('should respond with 200 when etag changed', function(done){ + it('should respond with 200 when etag changed', function (done) { request(app) .get('/nums') - .expect(200, function(err, res){ - if (err) return done(err); - var etag = res.headers.etag.replace(/"(.)/, '"0$1'); + .expect(200, function (err, res) { + if (err) return done(err) + var etag = res.headers.etag.replace(/"(.)/, '"0$1') request(app) .get('/nums') .set('If-Range', etag) .set('Range', 'bytes=0-0') - .expect(200, '123456789', done); + .expect(200, '123456789', done) }) }) - it('should respond with parts when modified unchanged', function(done){ + it('should respond with parts when modified unchanged', function (done) { request(app) .get('/nums') - .expect(200, function(err, res){ - if (err) return done(err); + .expect(200, function (err, res) { + if (err) return done(err) var modified = res.headers['last-modified'] request(app) .get('/nums') .set('If-Range', modified) .set('Range', 'bytes=0-0') - .expect(206, '1', done); + .expect(206, '1', done) }) }) - it('should respond with 200 when modified changed', function(done){ + it('should respond with 200 when modified changed', function (done) { request(app) .get('/nums') - .expect(200, function(err, res){ - if (err) return done(err); - var modified = Date.parse(res.headers['last-modified']) - 20000; + .expect(200, function (err, res) { + if (err) return done(err) + var modified = Date.parse(res.headers['last-modified']) - 20000 request(app) .get('/nums') .set('If-Range', new Date(modified).toUTCString()) .set('Range', 'bytes=0-0') - .expect(200, '123456789', done); + .expect(200, '123456789', done) }) }) }) }) - describe('when "options" is specified', function(){ + describe('when "options" is specified', function () { it('should support start/end', function (done) { request(createServer({root: fixtures, start: 3, end: 5})) .get('/nums') @@ -595,13 +595,13 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('.etag()', function(){ - it('should support disabling etags', function(done){ - var app = http.createServer(function(req, res){ + describe('.etag()', function () { + it('should support disabling etags', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) .etag(false) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/nums') @@ -610,13 +610,13 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('.from()', function(){ - it('should set with deprecated from', function(done){ - var app = http.createServer(function(req, res){ + describe('.from()', function () { + it('should set with deprecated from', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url) - .from(__dirname + '/fixtures') - .pipe(res); - }); + .from(fixtures) + .pipe(res) + }) request(app) .get('/pets/../name.txt') @@ -624,51 +624,51 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('.hidden()', function(){ - it('should default support sending hidden files', function(done){ - var app = http.createServer(function(req, res){ + describe('.hidden()', function () { + it('should default support sending hidden files', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) .hidden(true) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/.hidden') - .expect(200, /secret/, done); + .expect(200, /secret/, done) }) }) - describe('.index()', function(){ - it('should be configurable', function(done){ - var app = http.createServer(function(req, res){ + describe('.index()', function () { + it('should be configurable', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) .index('tobi.html') - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/') - .expect(200, '

tobi

', done); + .expect(200, '

tobi

', done) }) - it('should support disabling', function(done){ - var app = http.createServer(function(req, res){ + it('should support disabling', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) .index(false) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/pets/') - .expect(403, done); + .expect(403, done) }) - it('should support fallbacks', function(done){ - var app = http.createServer(function(req, res){ + it('should support fallbacks', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) .index(['default.htm', 'index.html']) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/pets/') @@ -676,49 +676,49 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('.maxage()', function(){ - it('should default to 0', function(done){ - var app = http.createServer(function(req, res){ + describe('.maxage()', function () { + it('should default to 0', function (done) { + var app = http.createServer(function (req, res) { send(req, 'test/fixtures/name.txt') .maxage(undefined) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/name.txt') .expect('Cache-Control', 'public, max-age=0', done) }) - it('should floor to integer', function(done){ - var app = http.createServer(function(req, res){ + it('should floor to integer', function (done) { + var app = http.createServer(function (req, res) { send(req, 'test/fixtures/name.txt') .maxage(1234) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/name.txt') .expect('Cache-Control', 'public, max-age=1', done) }) - it('should accept string', function(done){ - var app = http.createServer(function(req, res){ + it('should accept string', function (done) { + var app = http.createServer(function (req, res) { send(req, 'test/fixtures/name.txt') .maxage('30d') - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/name.txt') .expect('Cache-Control', 'public, max-age=2592000', done) }) - it('should max at 1 year', function(done){ - var app = http.createServer(function(req, res){ + it('should max at 1 year', function (done) { + var app = http.createServer(function (req, res) { send(req, 'test/fixtures/name.txt') .maxage(Infinity) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/name.txt') @@ -726,13 +726,13 @@ describe('send(file).pipe(res)', function(){ }) }) - describe('.root()', function(){ - it('should set root', function(done){ - var app = http.createServer(function(req, res){ + describe('.root()', function () { + it('should set root', function (done) { + var app = http.createServer(function (req, res) { send(req, req.url) - .root(__dirname + '/fixtures') - .pipe(res); - }); + .root(fixtures) + .pipe(res) + }) request(app) .get('/pets/../name.txt') @@ -852,7 +852,7 @@ describe('send(file, options)', function () { describe('from', function () { it('should set with deprecated from', function (done) { - request(createServer({from: __dirname + '/fixtures'})) + request(createServer({from: fixtures})) .get('/pets/../name.txt') .expect(200, 'tobi', done) }) @@ -953,7 +953,7 @@ describe('send(file, options)', function () { }) it('should 403 for dotfile without root', function (done) { - var server = http.createServer(function onRequest(req, res) { + var server = http.createServer(function onRequest (req, res) { send(req, fixtures + '/.mine' + req.url, {dotfiles: 'deny'}).pipe(res) }) @@ -1007,7 +1007,7 @@ describe('send(file, options)', function () { }) it('should 404 for dotfile without root', function (done) { - var server = http.createServer(function onRequest(req, res) { + var server = http.createServer(function onRequest (req, res) { send(req, fixtures + '/.mine' + req.url, {dotfiles: 'ignore'}).pipe(res) }) @@ -1018,8 +1018,8 @@ describe('send(file, options)', function () { }) }) - describe('hidden', function(){ - it('should default to false', function(done){ + describe('hidden', function () { + it('should default to false', function (done) { request(app) .get('/.hidden') .expect(404, 'Not Found', done) @@ -1114,11 +1114,11 @@ describe('send(file, options)', function () { }) it('should work without root', function (done) { - var server = http.createServer(function(req, res){ - var p = path.join(fixtures, 'pets').replace(/\\/g, '/') + '/'; + var server = http.createServer(function (req, res) { + var p = path.join(fixtures, 'pets').replace(/\\/g, '/') + '/' send(req, p, {index: ['index.html']}) - .pipe(res); - }); + .pipe(res) + }) request(server) .get('/') @@ -1134,22 +1134,22 @@ describe('send(file, options)', function () { .expect(200, 'tobi', done) }) - it('should work with trailing slash', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: __dirname + '/fixtures/'}) - .pipe(res); - }); + it('should work with trailing slash', function (done) { + var app = http.createServer(function (req, res) { + send(req, req.url, {root: fixtures + '/'}) + .pipe(res) + }) request(app) .get('/name.txt') .expect(200, 'tobi', done) }) - it('should work with empty path', function(done){ - var app = http.createServer(function(req, res){ - send(req, '', {root: __dirname + '/fixtures'}) - .pipe(res); - }); + it('should work with empty path', function (done) { + var app = http.createServer(function (req, res) { + send(req, '', {root: fixtures}) + .pipe(res) + }) request(app) .get('/name.txt') @@ -1162,11 +1162,11 @@ describe('send(file, options)', function () { .expect(403, done) }) - it('should allow .. in root', function(done){ - var app = http.createServer(function(req, res){ - send(req, req.url, {root: __dirname + '/fixtures/../fixtures'}) - .pipe(res); - }); + it('should allow .. in root', function (done) { + var app = http.createServer(function (req, res) { + send(req, req.url, {root: fixtures + '/../fixtures'}) + .pipe(res) + }) request(app) .get('/pets/../../send.js') @@ -1186,27 +1186,27 @@ describe('send(file, options)', function () { }) }) - describe('when missing', function(){ - it('should consider .. malicious', function(done){ - var app = http.createServer(function(req, res){ + describe('when missing', function () { + it('should consider .. malicious', function (done) { + var app = http.createServer(function (req, res) { send(req, fixtures + req.url) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/../send.js') .expect(403, done) }) - it('should still serve files with dots in name', function(done){ - var app = http.createServer(function(req, res){ + it('should still serve files with dots in name', function (done) { + var app = http.createServer(function (req, res) { send(req, fixtures + req.url) - .pipe(res); - }); + .pipe(res) + }) request(app) .get('/do..ts.txt') - .expect(200, '...', done); + .expect(200, '...', done) }) }) }) @@ -1258,7 +1258,7 @@ function createServer (opts, fn) { }) } -function shouldNotHaveHeader(header) { +function shouldNotHaveHeader (header) { return function (res) { assert.ok(!(header.toLowerCase() in res.headers), 'should not have header ' + header) } From 4b69813e46421a5884c986e9437ebd899abd2146 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 6 Jun 2016 19:02:42 -0400 Subject: [PATCH 100/334] Release 0.14.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e33a4ff6..07cbe0b2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.14.0 / 2016-06-06 +=================== * Add `acceptRanges` option * Add `cacheControl` option diff --git a/package.json b/package.json index 6f9f36a5..37d8b14d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.13.2", + "version": "0.14.0", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From a408e38c2dd8555661da63d6f5c145cf6349f51a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Jun 2016 22:32:03 -0400 Subject: [PATCH 101/334] tests: move the directory event tests together --- test/send.js | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/test/send.js b/test/send.js index b5820be3..8937790c 100644 --- a/test/send.js +++ b/test/send.js @@ -19,15 +19,8 @@ var app = http.createServer(function (req, res) { res.end(http.STATUS_CODES[err.status]) } - function redirect () { - res.statusCode = 301 - res.setHeader('Location', req.url + '/') - res.end('Redirecting to ' + req.url + '/') - } - send(req, req.url, {root: fixtures}) .on('error', error) - .on('directory', redirect) .pipe(res) }) @@ -139,13 +132,6 @@ describe('send(file).pipe(res)', function () { .expect(200, '404 ENOENT', done) }) - it('should 301 if the directory exists', function (done) { - request(app) - .get('/pets') - .expect('Location', '/pets/') - .expect(301, 'Redirecting to /pets/', done) - }) - it('should not override content-type', function (done) { var app = http.createServer(function (req, res) { res.setHeader('Content-Type', 'application/x-custom') @@ -322,7 +308,33 @@ describe('send(file).pipe(res)', function () { }) }) + describe('when "directory" listeners are present', function () { + it('should emit "directory" event sending directory', function (done) { + var server = http.createServer(function (req, res) { + send(req, req.url, {root: fixtures}) + .on('directory', onDirectory) + .pipe(res) + }) + + function onDirectory () { + this.res.statusCode = 400 + this.res.end('No directory for you') + } + + request(server) + .get('/pets') + .expect(400, 'No directory for you', done) + }) + }) + describe('when no "directory" listeners are present', function () { + it('should redirect directories to trailing slash', function (done) { + request(createServer({root: fixtures})) + .get('/pets') + .expect('Location', '/pets/') + .expect(301, done) + }) + it('should respond with an HTML redirect', function (done) { request(createServer({root: fixtures})) .get('/pets') From 153defafc428319e30312815d8b4007c27e33682 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Jun 2016 23:11:27 -0400 Subject: [PATCH 102/334] Fix redirect when path starts with multiple forward slashes --- HISTORY.md | 5 +++++ index.js | 20 +++++++++++++++++++- test/send.js | 7 +++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 07cbe0b2..2c71ed1b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix redirect when `path` starts with multiple forward slashes + 0.14.0 / 2016-06-06 =================== diff --git a/index.js b/index.js index 34ed8924..a3fa9e59 100644 --- a/index.js +++ b/index.js @@ -444,7 +444,7 @@ SendStream.prototype.redirect = function redirect (path) { return } - var loc = path + '/' + var loc = collapseLeadingSlashes(path + '/') var msg = 'Redirecting to ' + escapeHtml(loc) + '\n' var res = this.res @@ -845,6 +845,24 @@ function clearHeaders (res) { res._headerNames = {} } +/** + * Collapse all leading slashes into a single slash + * + * @param {string} str + * @private + */ +function collapseLeadingSlashes (str) { + for (var i = 0; i < str.length; i++) { + if (str[i] !== '/') { + break + } + } + + return i > 1 + ? '/' + str.substr(i) + : str +} + /** * Determine if path parts contain a dotfile. * diff --git a/test/send.js b/test/send.js index 8937790c..c4760811 100644 --- a/test/send.js +++ b/test/send.js @@ -342,6 +342,13 @@ describe('send(file).pipe(res)', function () { .expect('Content-Type', /html/) .expect(301, 'Redirecting to /pets/\n', done) }) + + it('should not redirect to protocol-relative locations', function (done) { + request(createServer({root: fixtures})) + .get('//pets') + .expect('Location', '/pets/') + .expect(301, done) + }) }) describe('when no "error" listeners are present', function () { From f28ee2cd40e1bdc456aa14ee07f2b9cd14db8173 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Jun 2016 23:16:20 -0400 Subject: [PATCH 103/334] docs: update examples to use standard style --- README.md | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c9aefd67..0c1dbf9d 100644 --- a/README.md +++ b/README.md @@ -163,58 +163,58 @@ $ npm test ### Small example ```js -var http = require('http'); -var send = require('send'); +var http = require('http') +var send = require('send') -var app = http.createServer(function(req, res){ - send(req, req.url).pipe(res); -}).listen(3000); +var app = http.createServer(function onRequest (req, res) { + send(req, req.url).pipe(res) +}).listen(3000) ``` ### Custom file types ```js -var http = require('http'); -var send = require('send'); +var http = require('http') +var send = require('send') // Default unknown types to text/plain -send.mime.default_type = 'text/plain'; +send.mime.default_type = 'text/plain' // Add a custom type send.mime.define({ 'application/x-my-type': ['x-mt', 'x-mtt'] -}); +}) -var app = http.createServer(function(req, res){ - send(req, req.url).pipe(res); -}).listen(3000); +var app = http.createServer(function onRequest (req, res) { + send(req, req.url).pipe(res) +}).listen(3000) ``` ### Serving from a root directory with custom error-handling ```js -var http = require('http'); -var send = require('send'); -var url = require('url'); +var http = require('http') +var send = require('send') +var url = require('url') -var app = http.createServer(function(req, res){ +var app = http.createServer(function onRequest (req, res) { // your custom error-handling logic: - function error(err) { - res.statusCode = err.status || 500; - res.end(err.message); + function error (err) { + res.statusCode = err.status || 500 + res.end(err.message) } // your custom headers - function headers(res, path, stat) { + function headers (res, path, stat) { // serve all files for download - res.setHeader('Content-Disposition', 'attachment'); + res.setHeader('Content-Disposition', 'attachment') } // your custom directory handling logic: - function redirect() { - res.statusCode = 301; - res.setHeader('Location', req.url + '/'); - res.end('Redirecting to ' + req.url + '/'); + function redirect () { + res.statusCode = 301 + res.setHeader('Location', req.url + '/') + res.end('Redirecting to ' + req.url + '/') } // transfer arbitrary files from within @@ -224,7 +224,7 @@ var app = http.createServer(function(req, res){ .on('directory', redirect) .on('headers', headers) .pipe(res); -}).listen(3000); +}).listen(3000) ``` ## License From 6428fb4159312c19f901011c5f27860c5e8e725d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Jun 2016 23:19:08 -0400 Subject: [PATCH 104/334] docs: update all examples to use url pathname --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0c1dbf9d..4167926a 100644 --- a/README.md +++ b/README.md @@ -164,10 +164,11 @@ $ npm test ```js var http = require('http') +var parseUrl = require('parseurl') var send = require('send') var app = http.createServer(function onRequest (req, res) { - send(req, req.url).pipe(res) + send(req, parseUrl(req).pathname).pipe(res) }).listen(3000) ``` @@ -175,6 +176,7 @@ var app = http.createServer(function onRequest (req, res) { ```js var http = require('http') +var parseUrl = require('parseurl') var send = require('send') // Default unknown types to text/plain @@ -186,7 +188,7 @@ send.mime.define({ }) var app = http.createServer(function onRequest (req, res) { - send(req, req.url).pipe(res) + send(req, parseUrl(req).pathname).pipe(res) }).listen(3000) ``` @@ -194,8 +196,8 @@ var app = http.createServer(function onRequest (req, res) { ```js var http = require('http') +var parseUrl = require('parseurl') var send = require('send') -var url = require('url') var app = http.createServer(function onRequest (req, res) { // your custom error-handling logic: @@ -219,7 +221,7 @@ var app = http.createServer(function onRequest (req, res) { // transfer arbitrary files from within // /www/example.com/public/* - send(req, url.parse(req.url).pathname, {root: '/www/example.com/public'}) + send(req, parseUrl(req).pathname, {root: '/www/example.com/public'}) .on('error', error) .on('directory', redirect) .on('headers', headers) From 8a44fe6f117ba947647ed16d8a6696cef9fdafb8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Jun 2016 00:25:35 -0400 Subject: [PATCH 105/334] Fix redirect error when path contains raw non-URL characters --- HISTORY.md | 1 + index.html | 0 index.js | 3 ++- package.json | 1 + "test/fixtures/snow \342\230\203/index.html" | 0 test/send.js | 13 +++++++++++++ 6 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 index.html create mode 100644 "test/fixtures/snow \342\230\203/index.html" diff --git a/HISTORY.md b/HISTORY.md index 2c71ed1b..10b60dfe 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix redirect error when `path` contains raw non-URL characters * Fix redirect when `path` starts with multiple forward slashes 0.14.0 / 2016-06-06 diff --git a/index.html b/index.html new file mode 100644 index 00000000..e69de29b diff --git a/index.js b/index.js index a3fa9e59..81ec0b3f 100644 --- a/index.js +++ b/index.js @@ -16,6 +16,7 @@ var createError = require('http-errors') var debug = require('debug')('send') var deprecate = require('depd')('send') var destroy = require('destroy') +var encodeUrl = require('encodeurl') var escapeHtml = require('escape-html') var etag = require('etag') var EventEmitter = require('events').EventEmitter @@ -444,7 +445,7 @@ SendStream.prototype.redirect = function redirect (path) { return } - var loc = collapseLeadingSlashes(path + '/') + var loc = encodeUrl(collapseLeadingSlashes(path + '/')) var msg = 'Redirecting to ' + escapeHtml(loc) + '\n' var res = this.res diff --git a/package.json b/package.json index 37d8b14d..c3240ce1 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "debug": "~2.2.0", "depd": "~1.1.0", "destroy": "~1.0.4", + "encodeurl": "~1.0.1", "escape-html": "~1.0.3", "etag": "~1.7.0", "fresh": "0.3.0", diff --git "a/test/fixtures/snow \342\230\203/index.html" "b/test/fixtures/snow \342\230\203/index.html" new file mode 100644 index 00000000..e69de29b diff --git a/test/send.js b/test/send.js index c4760811..da101aa9 100644 --- a/test/send.js +++ b/test/send.js @@ -349,6 +349,19 @@ describe('send(file).pipe(res)', function () { .expect('Location', '/pets/') .expect(301, done) }) + + it('should respond with an HTML redirect', function (done) { + var app = http.createServer(function (req, res) { + send(req, req.url.replace('/snow', '/snow ☃'), {root: 'test/fixtures'}) + .pipe(res) + }) + + request(app) + .get('/snow') + .expect('Location', '/snow%20%E2%98%83/') + .expect('Content-Type', /html/) + .expect(301, 'Redirecting to /snow%20%E2%98%83/\n', done) + }) }) describe('when no "error" listeners are present', function () { From d6dd3b91bbb73ad89f1398fa227b200db9bff037 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Jun 2016 00:29:47 -0400 Subject: [PATCH 106/334] Release 0.14.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 10b60dfe..f30e3453 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.14.1 / 2016-06-09 +=================== * Fix redirect error when `path` contains raw non-URL characters * Fix redirect when `path` starts with multiple forward slashes diff --git a/package.json b/package.json index c3240ce1..3a93e894 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.14.0", + "version": "0.14.1", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From ba198e84cf9db1510c936fd583c1a5e971029134 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 16 Sep 2016 20:05:47 +0200 Subject: [PATCH 107/334] build: istanbul@0.4.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a93e894..3e14ab30 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "eslint-config-standard": "5.3.1", "eslint-plugin-promise": "1.3.1", "eslint-plugin-standard": "1.3.2", - "istanbul": "0.4.3", + "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" }, From 1add5c5a466b43f4f0ccaeb5220738ca6ff5f866 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 16 Sep 2016 20:08:44 +0200 Subject: [PATCH 108/334] build: after@0.8.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3e14ab30..3588ea28 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "statuses": "~1.3.0" }, "devDependencies": { - "after": "0.8.1", + "after": "0.8.2", "eslint": "2.11.1", "eslint-config-standard": "5.3.1", "eslint-plugin-promise": "1.3.1", From 9957d67872b733bc89b2882663b90f25bbf9c60d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 16 Sep 2016 20:11:32 +0200 Subject: [PATCH 109/334] build: pass directory as argument to eslint --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3588ea28..c39ee915 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "node": ">= 0.8.0" }, "scripts": { - "lint": "eslint **/*.js", + "lint": "eslint .", "test": "mocha --check-leaks --reporter spec --bail", "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot" From 5bfc226456e6333eaa41298bd6980305a5057c01 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 16 Sep 2016 20:14:45 +0200 Subject: [PATCH 110/334] build: Node.js@4.5 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 29cc058d..afa84a7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.4" + - "4.5" - "5.11" - "6.2" sudo: false diff --git a/appveyor.yml b/appveyor.yml index fc3c9ab5..45edc090 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: - nodejs_version: "1.8" - nodejs_version: "2.5" - nodejs_version: "3.3" - - nodejs_version: "4.4" + - nodejs_version: "4.5" - nodejs_version: "5.11" - nodejs_version: "6.2" cache: From ad91e6eaa2121e10ca32cc1f1cf85c2c8c208bdc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 16 Sep 2016 20:15:59 +0200 Subject: [PATCH 111/334] build: Node.js@5.12 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index afa84a7d..f625c3d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ node_js: - "2.5" - "3.3" - "4.5" - - "5.11" + - "5.12" - "6.2" sudo: false cache: diff --git a/appveyor.yml b/appveyor.yml index 45edc090..58dce2e4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,7 +7,7 @@ environment: - nodejs_version: "2.5" - nodejs_version: "3.3" - nodejs_version: "4.5" - - nodejs_version: "5.11" + - nodejs_version: "5.12" - nodejs_version: "6.2" cache: - node_modules From c8ba4964338da425ed34ed2188a2931e11da5744 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 16 Sep 2016 20:18:22 +0200 Subject: [PATCH 112/334] build: Node.js@6.6 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f625c3d2..8d77024e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.5" - "5.12" - - "6.2" + - "6.6" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 58dce2e4..37881cf8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.5" - nodejs_version: "5.12" - - nodejs_version: "6.2" + - nodejs_version: "6.6" cache: - node_modules install: From 864b98ee21026c2542b9ae2485ee4b8619eb698e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 16 Sep 2016 20:20:32 +0200 Subject: [PATCH 113/334] docs: add preamble to install section --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4167926a..0453578c 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ Looking to serve up entire folders mapped to URLs? Try [serve-static](https://ww ## Installation +This is a [Node.js](https://nodejs.org/en/) module available through the +[npm registry](https://www.npmjs.com/). Installation is done using the +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): + ```bash $ npm install send ``` From 309dbd40ef8d6e16219e8b96d4beafc07ed684cf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Dec 2016 22:05:29 -0500 Subject: [PATCH 114/334] build: Node.js@4.7 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8d77024e..4b5fb3d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.5" + - "4.7" - "5.12" - "6.6" sudo: false diff --git a/appveyor.yml b/appveyor.yml index 37881cf8..453aa2bf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: - nodejs_version: "1.8" - nodejs_version: "2.5" - nodejs_version: "3.3" - - nodejs_version: "4.5" + - nodejs_version: "4.7" - nodejs_version: "5.12" - nodejs_version: "6.6" cache: From 61a2a85d5ff1ad2fda6597fb2141da908cd449d2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Dec 2016 22:09:05 -0500 Subject: [PATCH 115/334] build: Node.js@6.9 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4b5fb3d6..11a1157e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.7" - "5.12" - - "6.6" + - "6.9" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 453aa2bf..34313473 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.7" - nodejs_version: "5.12" - - nodejs_version: "6.6" + - nodejs_version: "6.9" cache: - node_modules install: From caa728db8052b8a910eeeaa1db5b33689c1b5750 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Dec 2016 22:23:44 -0500 Subject: [PATCH 116/334] deps: http-errors@~1.5.1 --- HISTORY.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f30e3453..1cb4ddf8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,11 @@ +unreleased +========== + + * deps: http-errors@~1.5.1 + - deps: inherits@2.0.3 + - deps: setprototypeof@1.0.2 + - deps: statuses@'>= 1.3.1 < 2' + 0.14.1 / 2016-06-09 =================== diff --git a/package.json b/package.json index c39ee915..2d339101 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "escape-html": "~1.0.3", "etag": "~1.7.0", "fresh": "0.3.0", - "http-errors": "~1.5.0", + "http-errors": "~1.5.1", "mime": "1.3.4", "ms": "0.7.1", "on-finished": "~2.3.0", From bdcf8155924335a7f4b2d09ee2091b7a075e29d6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 14 Dec 2016 22:26:09 -0500 Subject: [PATCH 117/334] deps: statuses@~1.3.1 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1cb4ddf8..668c80d6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,7 @@ unreleased - deps: inherits@2.0.3 - deps: setprototypeof@1.0.2 - deps: statuses@'>= 1.3.1 < 2' + * deps: statuses@~1.3.1 0.14.1 / 2016-06-09 =================== diff --git a/package.json b/package.json index 2d339101..96a69457 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "ms": "0.7.1", "on-finished": "~2.3.0", "range-parser": "~1.2.0", - "statuses": "~1.3.0" + "statuses": "~1.3.1" }, "devDependencies": { "after": "0.8.2", From bd4e847b8a78d1dc30a8d3ca84d3aef283cd15d5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 15 Dec 2016 00:06:51 -0500 Subject: [PATCH 118/334] deps: ms@0.7.2 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 668c80d6..d9110b1f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,7 @@ unreleased - deps: inherits@2.0.3 - deps: setprototypeof@1.0.2 - deps: statuses@'>= 1.3.1 < 2' + * deps: ms@0.7.2 * deps: statuses@~1.3.1 0.14.1 / 2016-06-09 diff --git a/package.json b/package.json index 96a69457..1b6fb280 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "fresh": "0.3.0", "http-errors": "~1.5.1", "mime": "1.3.4", - "ms": "0.7.1", + "ms": "0.7.2", "on-finished": "~2.3.0", "range-parser": "~1.2.0", "statuses": "~1.3.1" From 9da7ae1cac514da659aec3ae0e7c2171481c69be Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 6 Jan 2017 22:05:54 -0500 Subject: [PATCH 119/334] build: support Node.js 7.x --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 11a1157e..024727fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ node_js: - "4.7" - "5.12" - "6.9" + - "7.4" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 34313473..107453c2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,7 @@ environment: - nodejs_version: "4.7" - nodejs_version: "5.12" - nodejs_version: "6.9" + - nodejs_version: "7.4" cache: - node_modules install: From 0b2d5239ee46b0520d743205593bd21f365cbd97 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 7 Jan 2017 00:12:35 -0500 Subject: [PATCH 120/334] bulid: remove stray test file --- index.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 index.html diff --git a/index.html b/index.html deleted file mode 100644 index e69de29b..00000000 From f3397bc0170fb9f2d84c45e81981dff6e58e102d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 23 Jan 2017 10:10:01 -0500 Subject: [PATCH 121/334] Release 0.14.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d9110b1f..d8123cca 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.14.2 / 2017-01-23 +=================== * deps: http-errors@~1.5.1 - deps: inherits@2.0.3 diff --git a/package.json b/package.json index 1b6fb280..3c02217e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.14.1", + "version": "0.14.2", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson " From ba61019df534a93ec7011f16238544f7225e779e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 18 Feb 2017 23:21:13 -0500 Subject: [PATCH 122/334] eslint-config-standard@6.2.1 --- .travis.yml | 3 ++- index.js | 2 +- package.json | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 024727fe..143d23c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,8 @@ cache: - node_modules before_install: # Setup Node.js version-specific dependencies - - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev eslint eslint-config-standard eslint-plugin-promise eslint-plugin-standard istanbul" + - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" + - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint eslint-config-standard eslint-plugin-promise eslint-plugin-standard" # Update Node.js modules - "test ! -d node_modules || npm prune" diff --git a/index.js b/index.js index 81ec0b3f..0538867d 100644 --- a/index.js +++ b/index.js @@ -61,7 +61,7 @@ var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1000 // 1 year * @private */ -var UP_PATH_REGEXP = /(?:^|[\\\/])\.\.(?:[\\\/]|$)/ +var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/ /** * Module exports. diff --git a/package.json b/package.json index 3c02217e..b0f6e8d5 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,10 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "2.11.1", - "eslint-config-standard": "5.3.1", - "eslint-plugin-promise": "1.3.1", - "eslint-plugin-standard": "1.3.2", + "eslint": "3.15.0", + "eslint-config-standard": "6.2.1", + "eslint-plugin-promise": "3.4.2", + "eslint-plugin-standard": "2.0.1", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From e631b7e16ebbca58298d002d6c4a63ed92730cf6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 18 Feb 2017 23:38:29 -0500 Subject: [PATCH 123/334] build: Node.js@7.5 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 143d23c9..eec10fa7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.7" - "5.12" - "6.9" - - "7.4" + - "7.5" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 107453c2..00e0a726 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ environment: - nodejs_version: "4.7" - nodejs_version: "5.12" - nodejs_version: "6.9" - - nodejs_version: "7.4" + - nodejs_version: "7.5" cache: - node_modules install: From 4698f179ca31cc475cd78b55865ede0cb74d06fd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 19 Feb 2017 00:49:28 -0500 Subject: [PATCH 124/334] Send complete HTML document in redirect & error responses --- HISTORY.md | 5 +++++ index.js | 36 +++++++++++++++++++++++++++++------- test/send.js | 7 +++---- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d8123cca..19ea4084 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Send complete HTML document in redirect & error responses + 0.14.2 / 2017-01-23 =================== diff --git a/index.js b/index.js index 0538867d..ccb9ee5c 100644 --- a/index.js +++ b/index.js @@ -278,7 +278,8 @@ SendStream.prototype.error = function error (status, error) { } var res = this.res - var msg = statuses[status] + var msg = statuses[status] || String(status) + var doc = createHtmlDocument('Error', escapeHtml(msg)) // clear existing headers clearHeaders(res) @@ -290,10 +291,10 @@ SendStream.prototype.error = function error (status, error) { // send basic response res.statusCode = status - res.setHeader('Content-Type', 'text/plain; charset=UTF-8') - res.setHeader('Content-Length', Buffer.byteLength(msg)) + res.setHeader('Content-Type', 'text/html; charset=UTF-8') + res.setHeader('Content-Length', Buffer.byteLength(doc)) res.setHeader('X-Content-Type-Options', 'nosniff') - res.end(msg) + res.end(doc) } /** @@ -446,16 +447,17 @@ SendStream.prototype.redirect = function redirect (path) { } var loc = encodeUrl(collapseLeadingSlashes(path + '/')) - var msg = 'Redirecting to ' + escapeHtml(loc) + '\n' + var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + + escapeHtml(loc) + '') var res = this.res // redirect res.statusCode = 301 res.setHeader('Content-Type', 'text/html; charset=UTF-8') - res.setHeader('Content-Length', Buffer.byteLength(msg)) + res.setHeader('Content-Length', Buffer.byteLength(doc)) res.setHeader('X-Content-Type-Options', 'nosniff') res.setHeader('Location', loc) - res.end(msg) + res.end(doc) } /** @@ -892,6 +894,26 @@ function contentRange (type, size, range) { return type + ' ' + (range ? range.start + '-' + range.end : '*') + '/' + size } +/** + * Create a minimal HTML document. + * + * @param {string} title + * @param {string} body + * @private + */ + +function createHtmlDocument (title, body) { + return '\n' + + '\n' + + '\n' + + '\n' + + '' + title + '\n' + + '\n' + + '\n' + + '
' + body + '
\n' + + '\n' +} + /** * decodeURIComponent. * diff --git a/test/send.js b/test/send.js index da101aa9..ed9bb301 100644 --- a/test/send.js +++ b/test/send.js @@ -171,7 +171,6 @@ describe('send(file).pipe(res)', function () { request(app) .get('/name.txt') - .expect('Content-Type', /plain/) .expect(404, done) }) @@ -340,7 +339,7 @@ describe('send(file).pipe(res)', function () { .get('/pets') .expect('Location', '/pets/') .expect('Content-Type', /html/) - .expect(301, 'Redirecting to /pets/\n', done) + .expect(301, />Redirecting to \/pets\/<\/a>/snow%20%E2%98%83/\n', done) + .expect(301, />Redirecting to \/snow%20%E2%98%83\/<\/a>Not Found Date: Sun, 19 Feb 2017 00:53:34 -0500 Subject: [PATCH 125/334] Set default CSP header in redirect & error responses --- HISTORY.md | 1 + index.js | 2 ++ test/send.js | 15 +++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 19ea4084..04deb8e5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Send complete HTML document in redirect & error responses + * Set default CSP header in redirect & error responses 0.14.2 / 2017-01-23 =================== diff --git a/index.js b/index.js index ccb9ee5c..5cae12e7 100644 --- a/index.js +++ b/index.js @@ -293,6 +293,7 @@ SendStream.prototype.error = function error (status, error) { res.statusCode = status res.setHeader('Content-Type', 'text/html; charset=UTF-8') res.setHeader('Content-Length', Buffer.byteLength(doc)) + res.setHeader('Content-Security-Policy', "default-src 'self'") res.setHeader('X-Content-Type-Options', 'nosniff') res.end(doc) } @@ -455,6 +456,7 @@ SendStream.prototype.redirect = function redirect (path) { res.statusCode = 301 res.setHeader('Content-Type', 'text/html; charset=UTF-8') res.setHeader('Content-Length', Buffer.byteLength(doc)) + res.setHeader('Content-Security-Policy', "default-src 'self'") res.setHeader('X-Content-Type-Options', 'nosniff') res.setHeader('Location', loc) res.end(doc) diff --git a/test/send.js b/test/send.js index ed9bb301..e05efb6d 100644 --- a/test/send.js +++ b/test/send.js @@ -342,6 +342,14 @@ describe('send(file).pipe(res)', function () { .expect(301, />Redirecting to \/pets\/<\/a>Not Found Date: Sun, 19 Feb 2017 00:54:35 -0500 Subject: [PATCH 126/334] deps: debug@2.6.1 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 04deb8e5..8efa81f2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,12 @@ unreleased * Send complete HTML document in redirect & error responses * Set default CSP header in redirect & error responses + * deps: debug@2.6.1 + - Allow colors in workers + - Deprecated `DEBUG_FD` environment variable set to `3` or higher + - Fix error when running under React Native + - Use same color for same namespace + - deps: ms@0.7.2 0.14.2 / 2017-01-23 =================== diff --git a/package.json b/package.json index b0f6e8d5..f62d085b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "server" ], "dependencies": { - "debug": "~2.2.0", + "debug": "2.6.1", "depd": "~1.1.0", "destroy": "~1.0.4", "encodeurl": "~1.0.1", From 6c317079825141b27a047636ff130ad0df36bb9c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 19 Feb 2017 00:59:43 -0500 Subject: [PATCH 127/334] deps: http-errors@~1.6.0 --- HISTORY.md | 2 ++ index.js | 2 +- package.json | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 8efa81f2..fdfa2e2b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,8 @@ unreleased - Fix error when running under React Native - Use same color for same namespace - deps: ms@0.7.2 + * deps: http-errors@~1.6.0 + - Make `message` property enumerable for `HttpError`s 0.14.2 / 2017-01-23 =================== diff --git a/index.js b/index.js index 5cae12e7..67a0213b 100644 --- a/index.js +++ b/index.js @@ -272,7 +272,7 @@ SendStream.prototype.maxage = deprecate.function(function maxage (maxAge) { SendStream.prototype.error = function error (status, error) { // emit if listeners instead of responding if (listenerCount(this, 'error') !== 0) { - return this.emit('error', createError(error, status, { + return this.emit('error', createError(status, error, { expose: false })) } diff --git a/package.json b/package.json index f62d085b..7a2ff407 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "escape-html": "~1.0.3", "etag": "~1.7.0", "fresh": "0.3.0", - "http-errors": "~1.5.1", + "http-errors": "~1.6.0", "mime": "1.3.4", "ms": "0.7.2", "on-finished": "~2.3.0", From 5256f6241371eae857618bd0fef7d4a663b4f1aa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 19 Feb 2017 01:02:06 -0500 Subject: [PATCH 128/334] deps: etag@~1.8.0 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index fdfa2e2b..9b74d378 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,7 @@ unreleased - Fix error when running under React Native - Use same color for same namespace - deps: ms@0.7.2 + * deps: etag@~1.8.0 * deps: http-errors@~1.6.0 - Make `message` property enumerable for `HttpError`s diff --git a/package.json b/package.json index 7a2ff407..9bb42c6f 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "destroy": "~1.0.4", "encodeurl": "~1.0.1", "escape-html": "~1.0.3", - "etag": "~1.7.0", + "etag": "~1.8.0", "fresh": "0.3.0", "http-errors": "~1.6.0", "mime": "1.3.4", From 73fe3b6226c6f1bf824fbdfd736c446e3d42059d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 20 Feb 2017 16:22:15 -0500 Subject: [PATCH 129/334] build: test against Node.js 8.x nightly --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index eec10fa7..2a7b6ba4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,13 @@ node_js: - "5.12" - "6.9" - "7.5" +matrix: + include: + - node_js: "8.0" + env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" + allow_failures: + # Allow the nightly installs to fail + - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" sudo: false cache: directories: From fce9a1fb083ac6b5b077d17adf100488de238d4b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 20 Feb 2017 16:25:55 -0500 Subject: [PATCH 130/334] Remove usage of res._headers private field fixes #127 --- HISTORY.md | 2 ++ index.js | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9b74d378..e765058f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,8 @@ unreleased ========== + * Remove usage of `res._headers` private field + - Improves compatibility with Node.js 8 nightly * Send complete HTML document in redirect & error responses * Set default CSP header in redirect & error responses * deps: debug@2.6.1 diff --git a/index.js b/index.js index 67a0213b..2d0080b3 100644 --- a/index.js +++ b/index.js @@ -407,7 +407,10 @@ SendStream.prototype.onStatError = function onStatError (error) { */ SendStream.prototype.isFresh = function isFresh () { - return fresh(this.req.headers, this.res._headers) + return fresh(this.req.headers, { + 'etag': this.res.getHeader('ETag'), + 'last-modified': this.res.getHeader('Last-Modified') + }) } /** @@ -424,9 +427,15 @@ SendStream.prototype.isRangeFresh = function isRangeFresh () { return true } - return ~ifRange.indexOf('"') - ? ~ifRange.indexOf(this.res._headers['etag']) - : Date.parse(this.res._headers['last-modified']) <= Date.parse(ifRange) + // if-range as etag + if (ifRange.indexOf('"') !== -1) { + var etag = this.res.getHeader('ETag') + return Boolean(etag && ifRange.indexOf(etag) !== -1) + } + + // if-range as modified date + var lastModified = this.res.getHeader('Last-Modified') + return Boolean(lastModified && Date.parse(lastModified) <= Date.parse(ifRange)) } /** From 7ebcdeb998159465bd5b49ee804047d2d5edcc7a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 20 Feb 2017 22:25:22 -0500 Subject: [PATCH 131/334] deps: http-errors@~1.6.1 --- HISTORY.md | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e765058f..585b4e8b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -12,8 +12,9 @@ unreleased - Use same color for same namespace - deps: ms@0.7.2 * deps: etag@~1.8.0 - * deps: http-errors@~1.6.0 + * deps: http-errors@~1.6.1 - Make `message` property enumerable for `HttpError`s + - deps: setprototypeof@1.0.3 0.14.2 / 2017-01-23 =================== diff --git a/package.json b/package.json index 9bb42c6f..a8021d35 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.0", "fresh": "0.3.0", - "http-errors": "~1.6.0", + "http-errors": "~1.6.1", "mime": "1.3.4", "ms": "0.7.2", "on-finished": "~2.3.0", From 4e4c78eba9155eaf64f71f911a5fe177914d35ab Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 20 Feb 2017 22:26:43 -0500 Subject: [PATCH 132/334] build: eslint@3.16.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8021d35..30f8b225 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "3.15.0", + "eslint": "3.16.0", "eslint-config-standard": "6.2.1", "eslint-plugin-promise": "3.4.2", "eslint-plugin-standard": "2.0.1", From 4159462e398e509be364be5e8a0fb36410194393 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 20 Feb 2017 22:31:45 -0500 Subject: [PATCH 133/334] tests: add test for invalid If-Range header --- test/send.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/send.js b/test/send.js index e05efb6d..848170cf 100644 --- a/test/send.js +++ b/test/send.js @@ -609,6 +609,14 @@ describe('send(file).pipe(res)', function () { .expect(200, '123456789', done) }) }) + + it('should respond with 200 when invalid value', function (done) { + request(app) + .get('/nums') + .set('If-Range', 'foo') + .set('Range', 'bytes=0-0') + .expect(200, '123456789', done) + }) }) }) From f7f4c1c7b3e58c0ee74027656f626407122108fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Legan=C3=A9s=20Combarro?= Date: Sat, 13 Aug 2016 18:02:48 +0200 Subject: [PATCH 134/334] Add res and path arguments to "directory" event closes #115 --- HISTORY.md | 1 + README.md | 2 +- index.js | 9 +++++---- test/send.js | 24 ++++++++++++++++++++---- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 585b4e8b..9d25a710 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Add `res` and `path` arguments to `directory` event * Remove usage of `res._headers` private field - Improves compatibility with Node.js 8 nightly * Send complete HTML document in redirect & error responses diff --git a/README.md b/README.md index 0453578c..c298e9ae 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ meaning `start: 2` will include the 3rd byte in the stream. The `SendStream` is an event emitter and will emit the following events: - `error` an error occurred `(err)` - - `directory` a directory was requested + - `directory` a directory was requested `(res, path)` - `file` a file was requested `(path, stat)` - `headers` the headers are about to be set on a file `(res, path, stat)` - `stream` file streaming has started `(stream)` diff --git a/index.js b/index.js index 2d0080b3..b6272c43 100644 --- a/index.js +++ b/index.js @@ -446,8 +446,10 @@ SendStream.prototype.isRangeFresh = function isRangeFresh () { */ SendStream.prototype.redirect = function redirect (path) { + var res = this.res + if (listenerCount(this, 'directory') !== 0) { - this.emit('directory') + this.emit('directory', res, path) return } @@ -456,10 +458,9 @@ SendStream.prototype.redirect = function redirect (path) { return } - var loc = encodeUrl(collapseLeadingSlashes(path + '/')) + var loc = encodeUrl(collapseLeadingSlashes(this.path + '/')) var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + escapeHtml(loc) + '') - var res = this.res // redirect res.statusCode = 301 @@ -685,7 +686,7 @@ SendStream.prototype.sendFile = function sendFile (path) { return next(err) } if (err) return self.onStatError(err) - if (stat.isDirectory()) return self.redirect(self.path) + if (stat.isDirectory()) return self.redirect(path) self.emit('file', path, stat) self.send(path, stat) }) diff --git a/test/send.js b/test/send.js index 848170cf..d46d2d1b 100644 --- a/test/send.js +++ b/test/send.js @@ -308,22 +308,38 @@ describe('send(file).pipe(res)', function () { }) describe('when "directory" listeners are present', function () { - it('should emit "directory" event sending directory', function (done) { + it('should be called when sending directory', function (done) { var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) .on('directory', onDirectory) .pipe(res) }) - function onDirectory () { - this.res.statusCode = 400 - this.res.end('No directory for you') + function onDirectory (res) { + res.statusCode = 400 + res.end('No directory for you') } request(server) .get('/pets') .expect(400, 'No directory for you', done) }) + + it('should be called with path', function (done) { + var server = http.createServer(function (req, res) { + send(req, req.url, {root: fixtures}) + .on('directory', onDirectory) + .pipe(res) + }) + + function onDirectory (res, dirPath) { + res.end(path.normalize(dirPath)) + } + + request(server) + .get('/pets') + .expect(200, path.normalize(path.join(fixtures, 'pets')), done) + }) }) describe('when no "directory" listeners are present', function () { From a0f5b244657ea58fc1f38dbdee22f68ad1798320 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 21 Feb 2017 00:08:03 -0500 Subject: [PATCH 135/334] docs: remove trailing whitespace in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c298e9ae..acd51465 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ var app = http.createServer(function onRequest (req, res) { }).listen(3000) ``` -## License +## License [MIT](LICENSE) From 4d1e2f08ea2e48ad1fcac099cdcf996418cea0d2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 21 Feb 2017 23:48:41 -0500 Subject: [PATCH 136/334] deps: fresh@0.5.0 --- HISTORY.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 9d25a710..22df55e0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,6 +13,18 @@ unreleased - Use same color for same namespace - deps: ms@0.7.2 * deps: etag@~1.8.0 + * deps: fresh@0.5.0 + - Fix false detection of `no-cache` request directive + - Fix incorrect result when `If-None-Match` has both `*` and ETags + - Fix weak `ETag` matching to match spec + - perf: delay reading header values until needed + - perf: enable strict mode + - perf: hoist regular expressions + - perf: remove duplicate conditional + - perf: remove unnecessary boolean coercions + - perf: skip checking modified time if ETag check failed + - perf: skip parsing `If-None-Match` when no `ETag` header + - perf: use `Date.parse` instead of `new Date` * deps: http-errors@~1.6.1 - Make `message` property enumerable for `HttpError`s - deps: setprototypeof@1.0.3 diff --git a/package.json b/package.json index 30f8b225..7d61535a 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "encodeurl": "~1.0.1", "escape-html": "~1.0.3", "etag": "~1.8.0", - "fresh": "0.3.0", + "fresh": "0.5.0", "http-errors": "~1.6.1", "mime": "1.3.4", "ms": "0.7.2", From 4568381becb1543131494767b7f093624b0c272d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 22 Feb 2017 00:58:25 -0500 Subject: [PATCH 137/334] docs: add what conditional-GET means --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index acd51465..011cb1a5 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ [![Gratipay][gratipay-image]][gratipay-url] Send is a library for streaming files from the file system as a http response -supporting partial responses (Ranges), conditional-GET negotiation, high test -coverage, and granular events which may be leveraged to take appropriate actions -in your application or framework. +supporting partial responses (Ranges), conditional-GET negotiation (If-None-Match, +If-Modified-Since), high test coverage, and granular events which may be +leveraged to take appropriate actions in your application or framework. Looking to serve up entire folders mapped to URLs? Try [serve-static](https://www.npmjs.org/package/serve-static). From eb38e9bbb85935bdee6e9f9f10b0f7a3dfb00e72 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 22 Feb 2017 01:49:03 -0500 Subject: [PATCH 138/334] tests: expand the conditional-GET tests --- test/send.js | 82 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/test/send.js b/test/send.js index d46d2d1b..97cf4362 100644 --- a/test/send.js +++ b/test/send.js @@ -403,50 +403,80 @@ describe('send(file).pipe(res)', function () { }) describe('with conditional-GET', function () { - it('should respond with 304 on a match', function (done) { - request(app) + it('should remove Content headers with 304', function (done) { + var server = createServer({root: fixtures}, function (req, res) { + res.setHeader('Content-Language', 'en-US') + res.setHeader('Content-Location', 'http://localhost/name.txt') + res.setHeader('Contents', 'foo') + }) + + request(server) .get('/name.txt') .expect(200, function (err, res) { if (err) return done(err) - request(app) + request(server) .get('/name.txt') .set('If-None-Match', res.headers.etag) + .expect(shouldNotHaveHeader('Content-Language')) + .expect(shouldNotHaveHeader('Content-Length')) + .expect(shouldNotHaveHeader('Content-Type')) + .expect('Content-Location', 'http://localhost/name.txt') + .expect('Contents', 'foo') .expect(304, done) }) }) - it('should respond with 200 otherwise', function (done) { - request(app) - .get('/name.txt') - .expect(200, function (err, res) { - if (err) return done(err) + describe('where "If-Modified-Since" is set', function () { + it('should respond with 304 when unmodified', function (done) { request(app) .get('/name.txt') - .set('If-None-Match', '"123"') - .expect(200, 'tobi', done) + .expect(200, function (err, res) { + if (err) return done(err) + request(app) + .get('/name.txt') + .set('If-Modified-Since', res.headers['last-modified']) + .expect(304, done) + }) + }) + + it('should respond with 200 when modified', function (done) { + request(app) + .get('/name.txt') + .expect(200, function (err, res) { + if (err) return done(err) + var lmod = new Date(res.headers['last-modified']) + var date = new Date(lmod - 60000) + request(app) + .get('/name.txt') + .set('If-Modified-Since', date.toUTCString()) + .expect(200, 'tobi', done) + }) }) }) - it('should remove Content headers', function (done) { - var app = createServer({root: fixtures}, function (req, res) { - res.setHeader('Content-Language', 'en-US') - res.setHeader('Content-Location', 'http://localhost/name.txt') - res.setHeader('Contents', 'foo') + describe('where "If-None-Match" is set', function () { + it('should respond with 304 when ETag matched', function (done) { + request(app) + .get('/name.txt') + .expect(200, function (err, res) { + if (err) return done(err) + request(app) + .get('/name.txt') + .set('If-None-Match', res.headers.etag) + .expect(304, done) + }) }) - request(app) - .get('/name.txt') - .expect(200, function (err, res) { - if (err) return done(err) + it('should respond with 200 when ETag unmatched', function (done) { request(app) .get('/name.txt') - .set('If-None-Match', res.headers.etag) - .expect(shouldNotHaveHeader('Content-Language')) - .expect(shouldNotHaveHeader('Content-Length')) - .expect(shouldNotHaveHeader('Content-Type')) - .expect('Content-Location', 'http://localhost/name.txt') - .expect('Contents', 'foo') - .expect(304, done) + .expect(200, function (err, res) { + if (err) return done(err) + request(app) + .get('/name.txt') + .set('If-None-Match', '"123"') + .expect(200, 'tobi', done) + }) }) }) }) From 5c58a24eaaf3cb70cf2105aba6b4f60711a2ea2e Mon Sep 17 00:00:00 2001 From: James Wyatt Cready Date: Sun, 12 Feb 2017 17:57:59 -0500 Subject: [PATCH 139/334] Support "If-Match" and "If-Unmodified-Since" headers closes #130 closes #131 --- HISTORY.md | 1 + README.md | 7 +++--- index.js | 54 ++++++++++++++++++++++++++++++++++++++++---- test/send.js | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 22df55e0..21a2a5da 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Support `If-Match` and `If-Unmodified-Since` headers * Add `res` and `path` arguments to `directory` event * Remove usage of `res._headers` private field - Improves compatibility with Node.js 8 nightly diff --git a/README.md b/README.md index 011cb1a5..2e9f9f80 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,10 @@ [![Gratipay][gratipay-image]][gratipay-url] Send is a library for streaming files from the file system as a http response -supporting partial responses (Ranges), conditional-GET negotiation (If-None-Match, -If-Modified-Since), high test coverage, and granular events which may be -leveraged to take appropriate actions in your application or framework. +supporting partial responses (Ranges), conditional-GET negotiation (If-Match, +If-Unmodified-Since, If-None-Match, If-Modified-Since), high test coverage, +and granular events which may be leveraged to take appropriate actions in your +application or framework. Looking to serve up entire folders mapped to URLs? Try [serve-static](https://www.npmjs.org/package/serve-static). diff --git a/index.js b/index.js index b6272c43..feb5bd5f 100644 --- a/index.js +++ b/index.js @@ -49,6 +49,13 @@ var sep = path.sep var BYTES_RANGE_REGEXP = /^ *bytes=/ +/** + * Simple expression to split token list. + * @private + */ + +var TOKEN_LIST_REGEXP = / *, */ + /** * Maximum value allowed for the max age. * @private @@ -317,10 +324,42 @@ SendStream.prototype.hasTrailingSlash = function hasTrailingSlash () { */ SendStream.prototype.isConditionalGET = function isConditionalGET () { - return this.req.headers['if-none-match'] || + return this.req.headers['if-match'] || + this.req.headers['if-unmodified-since'] || + this.req.headers['if-none-match'] || this.req.headers['if-modified-since'] } +/** + * Check if the request preconditions failed. + * + * @return {boolean} + * @private + */ + +SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () { + var req = this.req + var res = this.res + + // if-match + var match = req.headers['if-match'] + if (match) { + var etag = res.getHeader('ETag') + return !etag || (match !== '*' && match.split(TOKEN_LIST_REGEXP).every(function (match) { + return match !== etag && match !== 'W/' + etag && 'W/' + match !== etag + })) + } + + // if-unmodified-since + var unmodifiedSince = Date.parse(req.headers['if-unmodified-since']) + if (!isNaN(unmodifiedSince)) { + var lastModified = Date.parse(res.getHeader('Last-Modified')) + return isNaN(lastModified) || lastModified > unmodifiedSince + } + + return false +} + /** * Strip content-* header fields. * @@ -596,9 +635,16 @@ SendStream.prototype.send = function send (path, stat) { this.type(path) // conditional GET support - if (this.isConditionalGET() && this.isCachable() && this.isFresh()) { - this.notModified() - return + if (this.isConditionalGET()) { + if (this.isPreconditionFailure()) { + this.error(412) + return + } + + if (this.isCachable() && this.isFresh()) { + this.notModified() + return + } } // adjust len to start/end options diff --git a/test/send.js b/test/send.js index 97cf4362..9046cce7 100644 --- a/test/send.js +++ b/test/send.js @@ -426,6 +426,34 @@ describe('send(file).pipe(res)', function () { }) }) + describe('where "If-Match" is set', function () { + it('should respond with 200 when "*"', function (done) { + request(app) + .get('/name.txt') + .set('If-Match', '*') + .expect(200, done) + }) + + it('should respond with 412 when ETag unmatched', function (done) { + request(app) + .get('/name.txt') + .set('If-Match', '"foo", "bar"') + .expect(412, done) + }) + + it('should respond with 200 when ETag matched', function (done) { + request(app) + .get('/name.txt') + .expect(200, function (err, res) { + if (err) return done(err) + request(app) + .get('/name.txt') + .set('If-Match', '"foo", "bar", ' + res.headers.etag) + .expect(200, done) + }) + }) + }) + describe('where "If-Modified-Since" is set', function () { it('should respond with 304 when unmodified', function (done) { request(app) @@ -479,6 +507,41 @@ describe('send(file).pipe(res)', function () { }) }) }) + + describe('where "If-Unmodified-Since" is set', function () { + it('should respond with 200 when unmodified', function (done) { + request(app) + .get('/name.txt') + .expect(200, function (err, res) { + if (err) return done(err) + request(app) + .get('/name.txt') + .set('If-Unmodified-Since', res.headers['last-modified']) + .expect(200, done) + }) + }) + + it('should respond with 412 when modified', function (done) { + request(app) + .get('/name.txt') + .expect(200, function (err, res) { + if (err) return done(err) + var lmod = new Date(res.headers['last-modified']) + var date = new Date(lmod - 60000).toUTCString() + request(app) + .get('/name.txt') + .set('If-Unmodified-Since', date) + .expect(412, done) + }) + }) + + it('should respond with 200 when invalid date', function (done) { + request(app) + .get('/name.txt') + .set('If-Unmodified-Since', 'foo') + .expect(200, done) + }) + }) }) describe('with Range request', function () { From 3cc48f98ba85303c3158ee106ef0f3fdbccc44ca Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Feb 2017 22:18:03 -0500 Subject: [PATCH 140/334] build: Node.js@4.8 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a7b6ba4..7527ccf9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.7" + - "4.8" - "5.12" - "6.9" - "7.5" diff --git a/appveyor.yml b/appveyor.yml index 00e0a726..5a5ca6bb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: - nodejs_version: "1.8" - nodejs_version: "2.5" - nodejs_version: "3.3" - - nodejs_version: "4.7" + - nodejs_version: "4.8" - nodejs_version: "5.12" - nodejs_version: "6.9" - nodejs_version: "7.5" From 64c56b8564f026afecf5290e5862b07cbeac6b27 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Feb 2017 22:18:26 -0500 Subject: [PATCH 141/334] build: Node.js@6.10 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7527ccf9..65394ace 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.8" - "5.12" - - "6.9" + - "6.10" - "7.5" matrix: include: diff --git a/appveyor.yml b/appveyor.yml index 5a5ca6bb..7681bbc0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.8" - nodejs_version: "5.12" - - nodejs_version: "6.9" + - nodejs_version: "6.10" - nodejs_version: "7.5" cache: - node_modules From 689ff8ca59dcf4bdcae8d1a5acc9cd0ecd71f75f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 23 Feb 2017 22:18:44 -0500 Subject: [PATCH 142/334] build: Node.js@7.6 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 65394ace..e7871e0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.8" - "5.12" - "6.10" - - "7.5" + - "7.6" matrix: include: - node_js: "8.0" diff --git a/appveyor.yml b/appveyor.yml index 7681bbc0..99a013fe 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ environment: - nodejs_version: "4.8" - nodejs_version: "5.12" - nodejs_version: "6.10" - - nodejs_version: "7.5" + - nodejs_version: "7.6" cache: - node_modules install: From 172be25b9fa2bacd5690a1eb416e531e93664b75 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 24 Feb 2017 20:03:45 -0500 Subject: [PATCH 143/334] tests: add test for error handler clear headers --- test/send.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/send.js b/test/send.js index 9046cce7..8efe9c51 100644 --- a/test/send.js +++ b/test/send.js @@ -400,6 +400,17 @@ describe('send(file).pipe(res)', function () { .expect('Content-Security-Policy', "default-src 'self'") .expect(404, done) }) + + it('should remove all previously-set headers', function (done) { + var server = createServer({root: fixtures}, function (req, res) { + res.setHeader('X-Foo', 'bar') + }) + + request(server) + .get('/foobar') + .expect(shouldNotHaveHeader('X-Foo')) + .expect(404, done) + }) }) describe('with conditional-GET', function () { From 1af34910a141b950dc20566dc774924a59b186d4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 24 Feb 2017 20:28:06 -0500 Subject: [PATCH 144/334] lint: use hasTrailingSlash() for index check --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index feb5bd5f..1e074560 100644 --- a/index.js +++ b/index.js @@ -595,7 +595,7 @@ SendStream.prototype.pipe = function pipe (res) { } // index file support - if (this._index.length && this.path[this.path.length - 1] === '/') { + if (this._index.length && this.hasTrailingSlash()) { this.sendIndex(path) return res } From bf8787d6f3588a487c0cbf90fe35173ce83fd3d0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 24 Feb 2017 20:48:57 -0500 Subject: [PATCH 145/334] Use res.getHeaderNames() when available --- HISTORY.md | 1 + index.js | 27 ++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 21a2a5da..31162f82 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,6 +7,7 @@ unreleased - Improves compatibility with Node.js 8 nightly * Send complete HTML document in redirect & error responses * Set default CSP header in redirect & error responses + * Use `res.getHeaderNames()` when available * deps: debug@2.6.1 - Allow colors in workers - Deprecated `DEBUG_FD` environment variable set to `3` or higher diff --git a/index.js b/index.js index 1e074560..b1e572b9 100644 --- a/index.js +++ b/index.js @@ -308,8 +308,8 @@ SendStream.prototype.error = function error (status, error) { /** * Check if the pathname ends with "/". * - * @return {Boolean} - * @api private + * @return {boolean} + * @private */ SendStream.prototype.hasTrailingSlash = function hasTrailingSlash () { @@ -368,7 +368,7 @@ SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () { SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields () { var res = this.res - var headers = Object.keys(res._headers || {}) + var headers = getHeaderNames(res) for (var i = 0; i < headers.length; i++) { var header = headers[i] @@ -902,8 +902,11 @@ SendStream.prototype.setHeader = function setHeader (path, stat) { */ function clearHeaders (res) { - res._headers = {} - res._headerNames = {} + var headers = getHeaderNames(res) + + for (var i = 0; i < headers.length; i++) { + res.removeHeader(headers[i]) + } } /** @@ -990,6 +993,20 @@ function decode (path) { } } +/** + * Get the header names on a respnse. + * + * @param {object} res + * @returns {array[string]} + * @private + */ + +function getHeaderNames (res) { + return typeof res.getHeaderNames !== 'function' + ? Object.keys(res._headers || {}) + : res.getHeaderNames() +} + /** * Normalize the index option into an array. * From d12be165fa5fc8db28fa4476d36dfd58a5c35956 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 24 Feb 2017 20:54:54 -0500 Subject: [PATCH 146/334] Use res.headersSent when available --- HISTORY.md | 1 + index.js | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 31162f82..878f867b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -8,6 +8,7 @@ unreleased * Send complete HTML document in redirect & error responses * Set default CSP header in redirect & error responses * Use `res.getHeaderNames()` when available + * Use `res.headersSent` when available * deps: debug@2.6.1 - Allow colors in workers - Deprecated `DEBUG_FD` environment variable set to `3` or higher diff --git a/index.js b/index.js index b1e572b9..de7e2ade 100644 --- a/index.js +++ b/index.js @@ -620,7 +620,7 @@ SendStream.prototype.send = function send (path, stat) { var ranges = req.headers.range var offset = options.start || 0 - if (res._header) { + if (headersSent(res)) { // impossible to send now this.headersAlreadySent() return @@ -1007,6 +1007,20 @@ function getHeaderNames (res) { : res.getHeaderNames() } +/** + * Determine if the response headers have been sent. + * + * @param {object} res + * @returns {boolean} + * @private + */ + +function headersSent (res) { + return typeof res.headersSent !== 'boolean' + ? Boolean(res._header) + : res.headersSent +} + /** * Normalize the index option into an array. * From 8914486f6e5eb7d4eeacc2130dba8ee21c8b9e57 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 25 Feb 2017 16:02:01 -0500 Subject: [PATCH 147/334] lint: use standard style in readme --- .travis.yml | 2 +- README.md | 22 +++++++++++++++------- appveyor.yml | 2 +- package.json | 3 ++- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7871e0c..d16ef431 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ cache: before_install: # Setup Node.js version-specific dependencies - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint eslint-config-standard eslint-plugin-promise eslint-plugin-standard" + - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint eslint-config-standard eslint-plugin-markdown eslint-plugin-promise eslint-plugin-standard" # Update Node.js modules - "test ! -d node_modules || npm prune" diff --git a/README.md b/README.md index 2e9f9f80..c24e26a0 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ $ npm install send ## API + + ```js var send = require('send') ``` @@ -172,9 +174,11 @@ var http = require('http') var parseUrl = require('parseurl') var send = require('send') -var app = http.createServer(function onRequest (req, res) { +var server = http.createServer(function onRequest (req, res) { send(req, parseUrl(req).pathname).pipe(res) -}).listen(3000) +}) + +server.listen(3000) ``` ### Custom file types @@ -192,9 +196,11 @@ send.mime.define({ 'application/x-my-type': ['x-mt', 'x-mtt'] }) -var app = http.createServer(function onRequest (req, res) { +var server = http.createServer(function onRequest (req, res) { send(req, parseUrl(req).pathname).pipe(res) -}).listen(3000) +}) + +server.listen(3000) ``` ### Serving from a root directory with custom error-handling @@ -204,7 +210,7 @@ var http = require('http') var parseUrl = require('parseurl') var send = require('send') -var app = http.createServer(function onRequest (req, res) { +var server = http.createServer(function onRequest (req, res) { // your custom error-handling logic: function error (err) { res.statusCode = err.status || 500 @@ -230,8 +236,10 @@ var app = http.createServer(function onRequest (req, res) { .on('error', error) .on('directory', redirect) .on('headers', headers) - .pipe(res); -}).listen(3000) + .pipe(res) +}) + +server.listen(3000) ``` ## License diff --git a/appveyor.yml b/appveyor.yml index 99a013fe..9bb6f1fa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,7 @@ cache: install: - ps: Install-Product node $env:nodejs_version - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul - - npm rm --save-dev eslint eslint-config-standard eslint-plugin-promise eslint-plugin-standard + - npm rm --save-dev eslint eslint-config-standard eslint-plugin-markdown eslint-plugin-promise eslint-plugin-standard - if exist node_modules npm prune - if exist node_modules npm rebuild - npm install diff --git a/package.json b/package.json index 7d61535a..7b7a9379 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "after": "0.8.2", "eslint": "3.16.0", "eslint-config-standard": "6.2.1", + "eslint-plugin-markdown": "1.0.0-beta.3", "eslint-plugin-promise": "3.4.2", "eslint-plugin-standard": "2.0.1", "istanbul": "0.4.5", @@ -48,7 +49,7 @@ "node": ">= 0.8.0" }, "scripts": { - "lint": "eslint .", + "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --check-leaks --reporter spec --bail", "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot" From da7df19862172b8bea6a8ae0d27ec2c99f96013f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 25 Feb 2017 16:20:29 -0500 Subject: [PATCH 148/334] docs: add custom directory index view example closes #89 closes #116 --- README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/README.md b/README.md index c24e26a0..0c8d11df 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,47 @@ var server = http.createServer(function onRequest (req, res) { server.listen(3000) ``` +### Custom directory index view + +This is a example of serving up a structure of directories with a +custom function to render a listing of a directory. + +```js +var http = require('http') +var fs = require('fs') +var parseUrl = require('parseurl') +var send = require('send') + +// Transfer arbitrary files from within /www/example.com/public/* +// with a custom handler for directory listing +var server = http.createServer(function onRequest (req, res) { + send(req, parseUrl(req).pathname, {index: false, root: '/www/example.com/public'}) + .once('directory', directory) + .pipe(res) +}) + +server.listen(3000) + +// Custom directory handler +function directory (res, path) { + var stream = this + + // redirect to trailing slash for consistent url + if (!stream.hasTrailingSlash()) { + return stream.redirect(path) + } + + // get directory list + fs.readdir(path, function onReaddir (err, list) { + if (err) return stream.error(err) + + // render an index for the directory + res.setHeader('Content-Type', 'text/plain; charset=UTF-8') + res.end(list.join('\n') + '\n') + }) +} +``` + ### Serving from a root directory with custom error-handling ```js From e887f9153ec168493f0d6c24c5c390a4b6246f29 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 25 Feb 2017 17:00:58 -0500 Subject: [PATCH 149/334] build: update package contributors --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7b7a9379..9cb76eb6 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "version": "0.14.2", "author": "TJ Holowaychuk ", "contributors": [ - "Douglas Christopher Wilson " + "Douglas Christopher Wilson ", + "James Wyatt Cready ", + "Jesús Leganés Combarro " ], "license": "MIT", "repository": "pillarjs/send", From 7196b1eb738b4e6fc075b3f48cdbec4f7659b22b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 25 Feb 2017 17:29:58 -0500 Subject: [PATCH 150/334] Release 0.15.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 878f867b..7ea68f88 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.15.0 / 2017-02-25 +=================== * Support `If-Match` and `If-Unmodified-Since` headers * Add `res` and `path` arguments to `directory` event diff --git a/package.json b/package.json index 9cb76eb6..2ffb8460 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.14.2", + "version": "0.15.0", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From 97951c32ec10ee93da301d89d9fd31f21ea7b9d9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Mar 2017 18:32:13 -0500 Subject: [PATCH 151/334] build: eslint-plugin-markdown@1.0.0-beta.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ffb8460..3de4036a 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "3.16.0", "eslint-config-standard": "6.2.1", - "eslint-plugin-markdown": "1.0.0-beta.3", + "eslint-plugin-markdown": "1.0.0-beta.4", "eslint-plugin-promise": "3.4.2", "eslint-plugin-standard": "2.0.1", "istanbul": "0.4.5", From 7c729a3fb1effd862092cbc7341852e543e02051 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Mar 2017 18:33:31 -0500 Subject: [PATCH 152/334] build: eslint-config-standard@7.0.0 --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 3de4036a..26154825 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,11 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "3.16.0", - "eslint-config-standard": "6.2.1", + "eslint": "3.17.0", + "eslint-config-standard": "7.0.0", "eslint-plugin-markdown": "1.0.0-beta.4", - "eslint-plugin-promise": "3.4.2", - "eslint-plugin-standard": "2.0.1", + "eslint-plugin-promise": "3.5.0", + "eslint-plugin-standard": "2.1.1", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From efdb43a4ea793159087680123a12c45da2ca7616 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Mar 2017 19:28:24 -0500 Subject: [PATCH 153/334] Fix issue when Date.parse does not return NaN --- HISTORY.md | 5 +++++ index.js | 21 ++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 7ea68f88..ca5fc354 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix issue when `Date.parse` does not return `NaN` on invalid date + 0.15.0 / 2017-02-25 =================== diff --git a/index.js b/index.js index de7e2ade..01210440 100644 --- a/index.js +++ b/index.js @@ -351,9 +351,9 @@ SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () { } // if-unmodified-since - var unmodifiedSince = Date.parse(req.headers['if-unmodified-since']) + var unmodifiedSince = parseHttpDate(req.headers['if-unmodified-since']) if (!isNaN(unmodifiedSince)) { - var lastModified = Date.parse(res.getHeader('Last-Modified')) + var lastModified = parseHttpDate(res.getHeader('Last-Modified')) return isNaN(lastModified) || lastModified > unmodifiedSince } @@ -474,7 +474,7 @@ SendStream.prototype.isRangeFresh = function isRangeFresh () { // if-range as modified date var lastModified = this.res.getHeader('Last-Modified') - return Boolean(lastModified && Date.parse(lastModified) <= Date.parse(ifRange)) + return Boolean(lastModified && parseHttpDate(lastModified) <= parseHttpDate(ifRange)) } /** @@ -1041,6 +1041,21 @@ function normalizeList (val, name) { return list } +/** + * Parse an HTTP Date into a number. + * + * @param {string} date + * @private + */ + +function parseHttpDate (date) { + var timestamp = date && Date.parse(date) + + return typeof timestamp === 'number' + ? timestamp + : NaN +} + /** * Set an object of headers on a response. * From c37d04b87accfc15aad2b3045b4521d1aebd8802 Mon Sep 17 00:00:00 2001 From: Alex Goretoy Date: Sun, 26 Feb 2017 10:14:54 -0800 Subject: [PATCH 154/334] Fix strict violation in broken environments fixes #80 closes #99 closes #124 closes #133 --- HISTORY.md | 1 + index.js | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ca5fc354..f3674c4d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Fix issue when `Date.parse` does not return `NaN` on invalid date + * Fix strict violation in broken environments 0.15.0 / 2017-02-25 =================== diff --git a/index.js b/index.js index 01210440..fd69de5a 100644 --- a/index.js +++ b/index.js @@ -272,14 +272,14 @@ SendStream.prototype.maxage = deprecate.function(function maxage (maxAge) { * Emit error with `status`. * * @param {number} status - * @param {Error} [error] + * @param {Error} [err] * @private */ -SendStream.prototype.error = function error (status, error) { +SendStream.prototype.error = function error (status, err) { // emit if listeners instead of responding if (listenerCount(this, 'error') !== 0) { - return this.emit('error', createError(status, error, { + return this.emit('error', createError(status, err, { expose: false })) } @@ -292,8 +292,8 @@ SendStream.prototype.error = function error (status, error) { clearHeaders(res) // add error headers - if (error && error.headers) { - setHeaders(res, error.headers) + if (err && err.headers) { + setHeaders(res, err.headers) } // send basic response From d2948c074a86591d47ae86116fd830ff681aa344 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Mar 2017 21:30:04 -0500 Subject: [PATCH 155/334] lint: remove unnecessary conditional --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index fd69de5a..37568412 100644 --- a/index.js +++ b/index.js @@ -474,7 +474,7 @@ SendStream.prototype.isRangeFresh = function isRangeFresh () { // if-range as modified date var lastModified = this.res.getHeader('Last-Modified') - return Boolean(lastModified && parseHttpDate(lastModified) <= parseHttpDate(ifRange)) + return parseHttpDate(lastModified) <= parseHttpDate(ifRange) } /** From ea1748a3b3e00dbcbb0629cf368ced575c6ab7d6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 4 Mar 2017 21:57:54 -0500 Subject: [PATCH 156/334] Release 0.15.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f3674c4d..1eacafa2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.15.1 / 2017-03-04 +=================== * Fix issue when `Date.parse` does not return `NaN` on invalid date * Fix strict violation in broken environments diff --git a/package.json b/package.json index 26154825..8bd72a71 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.15.0", + "version": "0.15.1", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From d751e078caf39cf3e73cd647152179a411f3dc7c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 3 Apr 2017 22:35:12 -0400 Subject: [PATCH 157/334] deps: ms@1.0.0 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1eacafa2..f4c0b930 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: ms@1.0.0 + 0.15.1 / 2017-03-04 =================== diff --git a/package.json b/package.json index 8bd72a71..b7efee98 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "fresh": "0.5.0", "http-errors": "~1.6.1", "mime": "1.3.4", - "ms": "0.7.2", + "ms": "1.0.0", "on-finished": "~2.3.0", "range-parser": "~1.2.0", "statuses": "~1.3.1" From a49a8a10bb5258f7dbcb12919155b41b0fde421f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 3 Apr 2017 22:39:04 -0400 Subject: [PATCH 158/334] build: Node.js@7.8 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d16ef431..31548836 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.8" - "5.12" - "6.10" - - "7.6" + - "7.8" matrix: include: - node_js: "8.0" diff --git a/appveyor.yml b/appveyor.yml index 9bb6f1fa..3118a8bf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ environment: - nodejs_version: "4.8" - nodejs_version: "5.12" - nodejs_version: "6.10" - - nodejs_version: "7.6" + - nodejs_version: "7.8" cache: - node_modules install: From 8c357a3d77e0bc39f67f33cb4a0a3d8e5eb3f09b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 3 Apr 2017 22:46:32 -0400 Subject: [PATCH 159/334] deps: debug@2.6.3 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f4c0b930..12b8f43e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,9 @@ unreleased ========== + * deps: debug@2.6.3 + - Fix `DEBUG_MAX_ARRAY_LENGTH` + - deps: ms@0.7.2 * deps: ms@1.0.0 0.15.1 / 2017-03-04 diff --git a/package.json b/package.json index b7efee98..581b6866 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "server" ], "dependencies": { - "debug": "2.6.1", + "debug": "2.6.3", "depd": "~1.1.0", "destroy": "~1.0.4", "encodeurl": "~1.0.1", From fbff6658a64977ceefe19f3d77ff15b72094ab5a Mon Sep 17 00:00:00 2001 From: Lucian Buzzo Date: Tue, 25 Apr 2017 15:41:40 +0100 Subject: [PATCH 160/334] deps: debug@2.6.4 closes #139 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 12b8f43e..06dde474 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,9 +1,9 @@ unreleased ========== - * deps: debug@2.6.3 + * deps: debug@2.6.4 - Fix `DEBUG_MAX_ARRAY_LENGTH` - - deps: ms@0.7.2 + - deps: ms@0.7.3 * deps: ms@1.0.0 0.15.1 / 2017-03-04 diff --git a/package.json b/package.json index 581b6866..737b1d87 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "server" ], "dependencies": { - "debug": "2.6.3", + "debug": "2.6.4", "depd": "~1.1.0", "destroy": "~1.0.4", "encodeurl": "~1.0.1", From 569d7660a3c64a192a928bbd869f1221011312af Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 26 Apr 2017 00:20:37 -0400 Subject: [PATCH 161/334] build: Node.js@7.9 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 31548836..440c7d9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.8" - "5.12" - "6.10" - - "7.8" + - "7.9" matrix: include: - node_js: "8.0" diff --git a/appveyor.yml b/appveyor.yml index 3118a8bf..9b384588 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ environment: - nodejs_version: "4.8" - nodejs_version: "5.12" - nodejs_version: "6.10" - - nodejs_version: "7.8" + - nodejs_version: "7.9" cache: - node_modules install: From de06518ed3b923ab5f8435a25e4268e847f5b2aa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 26 Apr 2017 00:37:23 -0400 Subject: [PATCH 162/334] build: eslint-config-standard@7.1.0 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 737b1d87..87dbef52 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,11 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "3.17.0", - "eslint-config-standard": "7.0.0", + "eslint": "3.19.0", + "eslint-config-standard": "7.1.0", "eslint-plugin-markdown": "1.0.0-beta.4", "eslint-plugin-promise": "3.5.0", - "eslint-plugin-standard": "2.1.1", + "eslint-plugin-standard": "2.3.1", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From 93b86b2cf38c986858cb389c560f483b74b07544 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 26 Apr 2017 00:40:08 -0400 Subject: [PATCH 163/334] Release 0.15.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 06dde474..931fc682 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.15.2 / 2017-04-26 +=================== * deps: debug@2.6.4 - Fix `DEBUG_MAX_ARRAY_LENGTH` diff --git a/package.json b/package.json index 87dbef52..44e358b2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.15.1", + "version": "0.15.2", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From d9270574673b3973127ad35b7f2e224fa1e53802 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 11 May 2017 21:28:08 -0400 Subject: [PATCH 164/334] deps: debug@2.6.6 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 931fc682..67df0658 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: debug@2.6.6 + 0.15.2 / 2017-04-26 =================== diff --git a/package.json b/package.json index 44e358b2..94019a52 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "server" ], "dependencies": { - "debug": "2.6.4", + "debug": "2.6.6", "depd": "~1.1.0", "destroy": "~1.0.4", "encodeurl": "~1.0.1", From c191ba99cc8de0719ad40fd2d73c748d7738c8bf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 May 2017 22:41:32 -0400 Subject: [PATCH 165/334] deps: ms@2.0.0 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 67df0658..7f40df75 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * deps: debug@2.6.6 + * deps: ms@2.0.0 0.15.2 / 2017-04-26 =================== diff --git a/package.json b/package.json index 94019a52..068dba5a 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "fresh": "0.5.0", "http-errors": "~1.6.1", "mime": "1.3.4", - "ms": "1.0.0", + "ms": "2.0.0", "on-finished": "~2.3.0", "range-parser": "~1.2.0", "statuses": "~1.3.1" From a5a523b87ffddf6c55ca5d23d2cbe0fa26b444ee Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 16 May 2017 22:42:16 -0400 Subject: [PATCH 166/334] build: eslint-plugin-markdown@1.0.0-beta.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 068dba5a..907f3406 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "3.19.0", "eslint-config-standard": "7.1.0", - "eslint-plugin-markdown": "1.0.0-beta.4", + "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-promise": "3.5.0", "eslint-plugin-standard": "2.3.1", "istanbul": "0.4.5", From 5fe5ec624695524c2abeadde73aee81df00cfe8b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 17 May 2017 00:36:33 -0400 Subject: [PATCH 167/334] deps: debug@2.6.7 --- HISTORY.md | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 7f40df75..0c9c98f5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,8 @@ unreleased ========== - * deps: debug@2.6.6 + * deps: debug@2.6.7 + - deps: ms@2.0.0 * deps: ms@2.0.0 0.15.2 / 2017-04-26 diff --git a/package.json b/package.json index 907f3406..c0312b57 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "server" ], "dependencies": { - "debug": "2.6.6", + "debug": "2.6.7", "depd": "~1.1.0", "destroy": "~1.0.4", "encodeurl": "~1.0.1", From a20f8f282bf392c610a07ec1fb042e33073dd3a2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 17 May 2017 00:48:05 -0400 Subject: [PATCH 168/334] Release 0.15.3 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 0c9c98f5..3297ba07 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.15.3 / 2017-05-16 +=================== * deps: debug@2.6.7 - deps: ms@2.0.0 diff --git a/package.json b/package.json index c0312b57..7298be2b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.15.2", + "version": "0.15.3", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From cbeac744eccbd46cc71f7f0240235230e7404dae Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 1 Jun 2017 22:56:11 -0400 Subject: [PATCH 169/334] build: Nodejs@7.10 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 440c7d9a..29723423 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ node_js: - "4.8" - "5.12" - "6.10" - - "7.9" + - "7.10" matrix: include: - node_js: "8.0" diff --git a/appveyor.yml b/appveyor.yml index 9b384588..80bc267f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ environment: - nodejs_version: "4.8" - nodejs_version: "5.12" - nodejs_version: "6.10" - - nodejs_version: "7.9" + - nodejs_version: "7.10" cache: - node_modules install: From 3bea3534a73223ff64f262fa2ba1c1ec9ae11d7b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 3 Jun 2017 00:20:35 -0400 Subject: [PATCH 170/334] deps: debug@2.6.8 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 3297ba07..2a56f75d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: debug@2.6.8 + 0.15.3 / 2017-05-16 =================== diff --git a/package.json b/package.json index 7298be2b..cdfed052 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "server" ], "dependencies": { - "debug": "2.6.7", + "debug": "2.6.8", "depd": "~1.1.0", "destroy": "~1.0.4", "encodeurl": "~1.0.1", From 1e45f6763928cebe5022fc20118eeec4085a9211 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 6 Aug 2017 01:04:40 -0400 Subject: [PATCH 171/334] build: support Node.js 8.x --- .travis.yml | 11 ++++------- appveyor.yml | 2 ++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 29723423..ea7d0072 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,18 +10,15 @@ node_js: - "5.12" - "6.10" - "7.10" -matrix: - include: - - node_js: "8.0" - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" - allow_failures: - # Allow the nightly installs to fail - - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" + - "8.1" sudo: false cache: directories: - node_modules before_install: + # Skip updating shrinkwrap / lock + - "npm config set shrinkwrap false" + # Setup Node.js version-specific dependencies - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint eslint-config-standard eslint-plugin-markdown eslint-plugin-promise eslint-plugin-standard" diff --git a/appveyor.yml b/appveyor.yml index 80bc267f..09d7ddbf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,10 +10,12 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.10" - nodejs_version: "7.10" + - nodejs_version: "8.1" cache: - node_modules install: - ps: Install-Product node $env:nodejs_version + - npm config set shrinkwrap false - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul - npm rm --save-dev eslint eslint-config-standard eslint-plugin-markdown eslint-plugin-promise eslint-plugin-standard - if exist node_modules npm prune From fb3e0069761681ec85752d9def779db9f7e107ee Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 6 Aug 2017 01:07:06 -0400 Subject: [PATCH 172/334] deps: depd@~1.1.1 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 2a56f75d..9ff22bdc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,8 @@ unreleased ========== * deps: debug@2.6.8 + * deps: depd@~1.1.1 + - Remove unnecessary `Buffer` loading 0.15.3 / 2017-05-16 =================== diff --git a/package.json b/package.json index cdfed052..63526fa7 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "dependencies": { "debug": "2.6.8", - "depd": "~1.1.0", + "depd": "~1.1.1", "destroy": "~1.0.4", "encodeurl": "~1.0.1", "escape-html": "~1.0.3", From aa380d240a703e8bbaba358cb58e423a67abc846 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 6 Aug 2017 01:08:19 -0400 Subject: [PATCH 173/334] deps: http-errors@~1.6.2 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 9ff22bdc..c4a8f32d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,6 +4,8 @@ unreleased * deps: debug@2.6.8 * deps: depd@~1.1.1 - Remove unnecessary `Buffer` loading + * deps: http-errors@~1.6.2 + - deps: depd@1.1.1 0.15.3 / 2017-05-16 =================== diff --git a/package.json b/package.json index 63526fa7..bb58e060 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.0", "fresh": "0.5.0", - "http-errors": "~1.6.1", + "http-errors": "~1.6.2", "mime": "1.3.4", "ms": "2.0.0", "on-finished": "~2.3.0", From bad2a468e4ff38c13ffb5a113ce74ba9a812f804 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 6 Aug 2017 01:16:54 -0400 Subject: [PATCH 174/334] Release 0.15.4 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index c4a8f32d..bd172a8d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.15.4 / 2017-08-05 +=================== * deps: debug@2.6.8 * deps: depd@~1.1.1 diff --git a/package.json b/package.json index bb58e060..47a3438a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.15.3", + "version": "0.15.4", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From 0eafb9a86a54c9049cfa687274992f8b7311cb22 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Sep 2017 19:09:36 -0400 Subject: [PATCH 175/334] build: Node.js@6.11 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ea7d0072..a28ecc37 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.8" - "5.12" - - "6.10" + - "6.11" - "7.10" - "8.1" sudo: false diff --git a/appveyor.yml b/appveyor.yml index 09d7ddbf..6c2d3a43 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.8" - nodejs_version: "5.12" - - nodejs_version: "6.10" + - nodejs_version: "6.11" - nodejs_version: "7.10" - nodejs_version: "8.1" cache: From 1daeb4cedde5b5c53fd9db4ed66d51869eecd655 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Sep 2017 19:20:44 -0400 Subject: [PATCH 176/334] build: Node.js@8.4 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a28ecc37..c595e547 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.11" - "7.10" - - "8.1" + - "8.4" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 6c2d3a43..ebd326e8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.11" - nodejs_version: "7.10" - - nodejs_version: "8.1" + - nodejs_version: "8.4" cache: - node_modules install: From 112e8b3bfa3f724474ed470228610cb6916529f4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Sep 2017 19:26:01 -0400 Subject: [PATCH 177/334] deps: etag@~1.8.1 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index bd172a8d..2dab9cb9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: etag@~1.8.1 + - perf: replace regular expression with substring + 0.15.4 / 2017-08-05 =================== diff --git a/package.json b/package.json index 47a3438a..e15a31d7 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "destroy": "~1.0.4", "encodeurl": "~1.0.1", "escape-html": "~1.0.3", - "etag": "~1.8.0", + "etag": "~1.8.1", "fresh": "0.5.0", "http-errors": "~1.6.2", "mime": "1.3.4", From 32ef137f30c1fcd9f9fb5bcb18fb9fd9fb6abe1e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Sep 2017 19:38:27 -0400 Subject: [PATCH 178/334] deps: fresh@0.5.2 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 2dab9cb9..e4bd7ed7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,10 @@ unreleased * deps: etag@~1.8.1 - perf: replace regular expression with substring + * deps: fresh@0.5.2 + - Fix handling of modified headers with invalid dates + - perf: improve ETag match loop + - perf: improve `If-None-Match` token parsing 0.15.4 / 2017-08-05 =================== diff --git a/package.json b/package.json index e15a31d7..476b5f63 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "encodeurl": "~1.0.1", "escape-html": "~1.0.3", "etag": "~1.8.1", - "fresh": "0.5.0", + "fresh": "0.5.2", "http-errors": "~1.6.2", "mime": "1.3.4", "ms": "2.0.0", From 2d17fa124adc7f81f1d9bf4841fff42b674b8448 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 20 Sep 2017 22:26:18 -0400 Subject: [PATCH 179/334] Release 0.15.5 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e4bd7ed7..1d4d83e8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.15.5 / 2017-09-20 +=================== * deps: etag@~1.8.1 - perf: replace regular expression with substring diff --git a/package.json b/package.json index 476b5f63..4e34e6c3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.15.4", + "version": "0.15.5", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From 4edb37e4e8e9a6900927a02a577ed5d5d5b0a3be Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 Sep 2017 15:18:04 -0400 Subject: [PATCH 180/334] deps: debug@2.6.9 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1d4d83e8..419c4cbb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: debug@2.6.9 + 0.15.5 / 2017-09-20 =================== diff --git a/package.json b/package.json index 4e34e6c3..10ee1a43 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "server" ], "dependencies": { - "debug": "2.6.8", + "debug": "2.6.9", "depd": "~1.1.1", "destroy": "~1.0.4", "encodeurl": "~1.0.1", From c3fd47b9b43908b9ae5ddcdb085b6fddea987974 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 Sep 2017 15:20:39 -0400 Subject: [PATCH 181/334] lint: remote parameter reassignments --- .eslintrc | 5 ++++- test/send.js | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.eslintrc b/.eslintrc index e3578aad..a819f736 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,3 +1,6 @@ { - "extends": "standard" + "extends": "standard", + "rules": { + "no-param-reassign": "error" + } } diff --git a/test/send.js b/test/send.js index 8efe9c51..eb99d8d5 100644 --- a/test/send.js +++ b/test/send.js @@ -162,8 +162,7 @@ describe('send(file).pipe(res)', function () { // simulate file ENOENT after on open, after stat var fn = this.send this.send = function (path, stat) { - path += '__xxx_no_exist' - fn.call(this, path, stat) + fn.call(this, (path + '__xxx_no_exist'), stat) } }) .pipe(res) From 43738dd9b2727fcdc67a6be698230b13f3e5f54a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 Sep 2017 15:25:34 -0400 Subject: [PATCH 182/334] perf: improve If-Match token parsing --- HISTORY.md | 1 + index.js | 45 +++++++++++++++++++++++++++++++++++++-------- test/send.js | 2 +- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 419c4cbb..d48aeb20 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * deps: debug@2.6.9 + * perf: improve `If-Match` token parsing 0.15.5 / 2017-09-20 =================== diff --git a/index.js b/index.js index 37568412..e817ca53 100644 --- a/index.js +++ b/index.js @@ -49,13 +49,6 @@ var sep = path.sep var BYTES_RANGE_REGEXP = /^ *bytes=/ -/** - * Simple expression to split token list. - * @private - */ - -var TOKEN_LIST_REGEXP = / *, */ - /** * Maximum value allowed for the max age. * @private @@ -345,7 +338,7 @@ SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () { var match = req.headers['if-match'] if (match) { var etag = res.getHeader('ETag') - return !etag || (match !== '*' && match.split(TOKEN_LIST_REGEXP).every(function (match) { + return !etag || (match !== '*' && parseTokenList(match).every(function (match) { return match !== etag && match !== 'W/' + etag && 'W/' + match !== etag })) } @@ -1056,6 +1049,42 @@ function parseHttpDate (date) { : NaN } +/** + * Parse a HTTP token list. + * + * @param {string} str + * @private + */ + +function parseTokenList (str) { + var end = 0 + var list = [] + var start = 0 + + // gather tokens + for (var i = 0, len = str.length; i < len; i++) { + switch (str.charCodeAt(i)) { + case 0x20: /* */ + if (start === end) { + start = end = i + 1 + } + break + case 0x2c: /* , */ + list.push(str.substring(start, end)) + start = end = i + 1 + break + default: + end = i + 1 + break + } + } + + // final token + list.push(str.substring(start, end)) + + return list +} + /** * Set an object of headers on a response. * diff --git a/test/send.js b/test/send.js index eb99d8d5..ac2c4ffd 100644 --- a/test/send.js +++ b/test/send.js @@ -447,7 +447,7 @@ describe('send(file).pipe(res)', function () { it('should respond with 412 when ETag unmatched', function (done) { request(app) .get('/name.txt') - .set('If-Match', '"foo", "bar"') + .set('If-Match', ' "foo", "bar" ') .expect(412, done) }) From 8b080c8c4e127fe3dd41a758f06f6b15899b39ec Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 22 Sep 2017 18:19:57 -0400 Subject: [PATCH 183/334] Release 0.15.6 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d48aeb20..319aad83 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.15.6 / 2017-09-22 +=================== * deps: debug@2.6.9 * perf: improve `If-Match` token parsing diff --git a/package.json b/package.json index 10ee1a43..e33aced2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.15.5", + "version": "0.15.6", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From ccdf3ab71ccc717489271f8bf386f102969d8c5f Mon Sep 17 00:00:00 2001 From: Bradley Farias Date: Mon, 28 Aug 2017 11:18:14 -0500 Subject: [PATCH 184/334] deps: mime@1.4.0 closes #142 --- HISTORY.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 319aad83..46e9db62 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,10 @@ +unreleased +========== + + * deps: mime@1.4.0 + - Add 70 new types for file extensions + - Set charset as "UTF-8" for .js and .json + 0.15.6 / 2017-09-22 =================== diff --git a/package.json b/package.json index e33aced2..05067cd9 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "~1.6.2", - "mime": "1.3.4", + "mime": "1.4.0", "ms": "2.0.0", "on-finished": "~2.3.0", "range-parser": "~1.2.0", From bc6b5d41bee554641af11641ec838aea6828e181 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 25 Sep 2017 20:20:45 -0400 Subject: [PATCH 185/334] Use instance methods on steam to check for listeners --- HISTORY.md | 1 + index.js | 33 ++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 46e9db62..7f921ecc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Use instance methods on steam to check for listeners * deps: mime@1.4.0 - Add 70 new types for file extensions - Set charset as "UTF-8" for .js and .json diff --git a/index.js b/index.js index e817ca53..3c0140f4 100644 --- a/index.js +++ b/index.js @@ -19,7 +19,6 @@ var destroy = require('destroy') var encodeUrl = require('encodeurl') var escapeHtml = require('escape-html') var etag = require('etag') -var EventEmitter = require('events').EventEmitter var fresh = require('fresh') var fs = require('fs') var mime = require('mime') @@ -71,14 +70,6 @@ var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/ module.exports = send module.exports.mime = mime -/** - * Shim EventEmitter.listenerCount for node.js < 0.10 - */ - -/* istanbul ignore next */ -var listenerCount = EventEmitter.listenerCount || - function (emitter, type) { return emitter.listeners(type).length } - /** * Return a `SendStream` for `req` and `path`. * @@ -271,7 +262,7 @@ SendStream.prototype.maxage = deprecate.function(function maxage (maxAge) { SendStream.prototype.error = function error (status, err) { // emit if listeners instead of responding - if (listenerCount(this, 'error') !== 0) { + if (hasListeners(this, 'error')) { return this.emit('error', createError(status, err, { expose: false })) @@ -480,7 +471,7 @@ SendStream.prototype.isRangeFresh = function isRangeFresh () { SendStream.prototype.redirect = function redirect (path) { var res = this.res - if (listenerCount(this, 'directory') !== 0) { + if (hasListeners(this, 'directory')) { this.emit('directory', res, path) return } @@ -1000,6 +991,26 @@ function getHeaderNames (res) { : res.getHeaderNames() } +/** + * Determine if emitter has listeners of a given type. + * + * The way to do this check is done three different ways in Node.js >= 0.8 + * so this consolidates them into a minimal set using instance methods. + * + * @param {EventEmitter} emitter + * @param {string} type + * @returns {boolean} + * @private + */ + +function hasListeners (emitter, type) { + var count = typeof emitter.listenerCount !== 'function' + ? emitter.listeners(type).length + : emitter.listenerCount(type) + + return count > 0 +} + /** * Determine if the response headers have been sent. * From 528559bb24fb1d494744fe35df55f0dcdc4df9b9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 25 Sep 2017 20:23:10 -0400 Subject: [PATCH 186/334] lint: apply standard 10 style --- .travis.yml | 2 +- appveyor.yml | 2 +- package.json | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c595e547..ebd2de2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ before_install: # Setup Node.js version-specific dependencies - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev eslint eslint-config-standard eslint-plugin-markdown eslint-plugin-promise eslint-plugin-standard" + - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev $(grep -E '\"eslint\\S*\"' package.json | cut -d'\"' -f2)" # Update Node.js modules - "test ! -d node_modules || npm prune" diff --git a/appveyor.yml b/appveyor.yml index ebd326e8..193e7594 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,7 @@ install: - ps: Install-Product node $env:nodejs_version - npm config set shrinkwrap false - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul - - npm rm --save-dev eslint eslint-config-standard eslint-plugin-markdown eslint-plugin-promise eslint-plugin-standard + - for /f tokens^=2^ delims^=^" %%m in ('findstr /r /c:"eslint[^ ]" package.json') do call npm rm --save-dev %%m - if exist node_modules npm prune - if exist node_modules npm rebuild - npm install diff --git a/package.json b/package.json index 05067cd9..5e94e7ec 100644 --- a/package.json +++ b/package.json @@ -33,10 +33,12 @@ "devDependencies": { "after": "0.8.2", "eslint": "3.19.0", - "eslint-config-standard": "7.1.0", + "eslint-config-standard": "10.2.1", + "eslint-plugin-import": "2.7.0", "eslint-plugin-markdown": "1.0.0-beta.6", + "eslint-plugin-node": "5.1.1", "eslint-plugin-promise": "3.5.0", - "eslint-plugin-standard": "2.3.1", + "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From a1a3445f4cf131ac644fe0c098b90fb5396ab488 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 25 Sep 2017 20:33:45 -0400 Subject: [PATCH 187/334] Fix missing in default error & redirects --- HISTORY.md | 1 + index.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 7f921ecc..66048a33 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix missing `` in default error & redirects * Use instance methods on steam to check for listeners * deps: mime@1.4.0 - Add 70 new types for file extensions diff --git a/index.js b/index.js index 3c0140f4..b6907cd1 100644 --- a/index.js +++ b/index.js @@ -956,7 +956,8 @@ function createHtmlDocument (title, body) { '\n' + '\n' + '
' + body + '
\n' + - '\n' + '\n' + + '\n' } /** From 63c0d3364419ae29d96d1ec6bea81c0fb31d5c50 Mon Sep 17 00:00:00 2001 From: James Wyatt Cready Date: Sat, 29 Apr 2017 11:56:34 -0400 Subject: [PATCH 188/334] Add "immutable" option closes #140 --- HISTORY.md | 1 + README.md | 10 +++++++++- index.js | 9 +++++++++ test/send.js | 16 +++++++++++++++- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 66048a33..ced63619 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Add `immutable` option * Fix missing `` in default error & redirects * Use instance methods on steam to check for listeners * deps: mime@1.4.0 diff --git a/README.md b/README.md index 0c8d11df..ca591ed4 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ of the `Range` request header. ##### cacheControl Enable or disable setting `Cache-Control` response header, defaults to -true. Disabling this will ignore the `maxAge` option. +true. Disabling this will ignore the `immutable` and `maxAge` options. ##### dotfiles @@ -86,6 +86,14 @@ in the given order. By default, this is disabled (set to `false`). An example value that will serve extension-less HTML files: `['html', 'htm']`. This is skipped if the requested file already has an extension. +##### immutable + +Enable or diable the `immutable` directive in the `Cache-Control` response +header, defaults to `false`. If set to `true`, the `maxAge` option should +also be specified to enable caching. The `immutable` directive will prevent +supported clients from making conditional requests during the life of the +`maxAge` option to check if the file has changed. + ##### index By default send supports "index.html" files, to disable this diff --git a/index.js b/index.js index b6907cd1..7e3268bd 100644 --- a/index.js +++ b/index.js @@ -137,6 +137,10 @@ function SendStream (req, path, options) { ? normalizeList(opts.extensions, 'extensions option') : [] + this._immutable = opts.immutable !== undefined + ? Boolean(opts.immutable) + : false + this._index = opts.index !== undefined ? normalizeList(opts.index, 'index option') : ['index.html'] @@ -861,6 +865,11 @@ SendStream.prototype.setHeader = function setHeader (path, stat) { if (this._cacheControl && !res.getHeader('Cache-Control')) { var cacheControl = 'public, max-age=' + Math.floor(this._maxage / 1000) + + if (this._immutable) { + cacheControl += ', immutable' + } + debug('cache-control %s', cacheControl) res.setHeader('Cache-Control', cacheControl) } diff --git a/test/send.js b/test/send.js index ac2c4ffd..81e0f961 100644 --- a/test/send.js +++ b/test/send.js @@ -1205,6 +1205,20 @@ describe('send(file, options)', function () { }) }) + describe('immutable', function () { + it('should default to false', function (done) { + request(createServer({root: fixtures})) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=0', done) + }) + + it('should set immutable directive in Cache-Control', function (done) { + request(createServer({immutable: true, maxAge: '1h', root: fixtures})) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=3600, immutable', done) + }) + }) + describe('maxAge', function () { it('should default to 0', function (done) { request(createServer({root: fixtures})) @@ -1225,7 +1239,7 @@ describe('send(file, options)', function () { }) it('should max at 1 year', function (done) { - request(createServer({maxAge: Infinity, root: fixtures})) + request(createServer({maxAge: '2y', root: fixtures})) .get('/name.txt') .expect('Cache-Control', 'public, max-age=31536000', done) }) From a472ed304701ef2c091ce4dddb89bdddfccc98da Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 27 Sep 2017 19:33:05 -0400 Subject: [PATCH 189/334] perf: improve path validation speed --- HISTORY.md | 1 + index.js | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ced63619..f75004fc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,6 +7,7 @@ unreleased * deps: mime@1.4.0 - Add 70 new types for file extensions - Set charset as "UTF-8" for .js and .json + * perf: improve path validation speed 0.15.6 / 2017-09-22 =================== diff --git a/index.js b/index.js index 7e3268bd..7835c3f2 100644 --- a/index.js +++ b/index.js @@ -529,19 +529,22 @@ SendStream.prototype.pipe = function pipe (res) { var parts if (root !== null) { + // normalize + path = normalize('.' + sep + path) + // malicious path - if (UP_PATH_REGEXP.test(normalize('.' + sep + path))) { + if (UP_PATH_REGEXP.test(path)) { debug('malicious path "%s"', path) this.error(403) return res } + // explode path parts + parts = path.split(sep) + // join / normalize from optional root dir path = normalize(join(root, path)) root = normalize(root + sep) - - // explode path parts - parts = path.substr(root.length).split(sep) } else { // ".." is malicious without "root" if (UP_PATH_REGEXP.test(path)) { @@ -928,7 +931,8 @@ function collapseLeadingSlashes (str) { function containsDotFile (parts) { for (var i = 0; i < parts.length; i++) { - if (parts[i][0] === '.') { + var part = parts[i] + if (part.length > 1 && part[0] === '.') { return true } } From 9f562e343115ba3f3e62635c4d2e51298f21c3a6 Mon Sep 17 00:00:00 2001 From: Louis Cloutier Date: Wed, 27 Sep 2017 15:16:03 -0400 Subject: [PATCH 190/334] deps: mime@1.4.1 closes #144 closes #145 --- HISTORY.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f75004fc..b02f157d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,7 +4,7 @@ unreleased * Add `immutable` option * Fix missing `` in default error & redirects * Use instance methods on steam to check for listeners - * deps: mime@1.4.0 + * deps: mime@1.4.1 - Add 70 new types for file extensions - Set charset as "UTF-8" for .js and .json * perf: improve path validation speed diff --git a/package.json b/package.json index 5e94e7ec..9808a8a7 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "~1.6.2", - "mime": "1.4.0", + "mime": "1.4.1", "ms": "2.0.0", "on-finished": "~2.3.0", "range-parser": "~1.2.0", From b11c3a3feba4601e19885776c189b81ae763c7d5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 27 Sep 2017 20:19:21 -0400 Subject: [PATCH 191/334] Release 0.16.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index b02f157d..51eccbf4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.16.0 / 2017-09-27 +=================== * Add `immutable` option * Fix missing `` in default error & redirects diff --git a/package.json b/package.json index 9808a8a7..c129f2cc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.15.6", + "version": "0.16.0", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From 04e5cbcb37ee8c0eb1c510a578161d8b9c095d43 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Sep 2017 12:34:32 -0400 Subject: [PATCH 192/334] build: eslint-plugin-node@5.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c129f2cc..baf81386 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "eslint-config-standard": "10.2.1", "eslint-plugin-import": "2.7.0", "eslint-plugin-markdown": "1.0.0-beta.6", - "eslint-plugin-node": "5.1.1", + "eslint-plugin-node": "5.2.0", "eslint-plugin-promise": "3.5.0", "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", From ff0d82ee71ad884966f062f75d5b2b2a520ddd59 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Sep 2017 15:08:25 -0400 Subject: [PATCH 193/334] Fix regression in edge-case behavior for empty path fixes #148 --- HISTORY.md | 5 +++++ index.js | 4 +++- test/send.js | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 51eccbf4..aec8b86e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Fix regression in edge-case behavior for empty `path` + 0.16.0 / 2017-09-27 =================== diff --git a/index.js b/index.js index 7835c3f2..c4c96773 100644 --- a/index.js +++ b/index.js @@ -530,7 +530,9 @@ SendStream.prototype.pipe = function pipe (res) { var parts if (root !== null) { // normalize - path = normalize('.' + sep + path) + if (path) { + path = normalize('.' + sep + path) + } // malicious path if (UP_PATH_REGEXP.test(path)) { diff --git a/test/send.js b/test/send.js index 81e0f961..ec7ff0dd 100644 --- a/test/send.js +++ b/test/send.js @@ -1343,6 +1343,23 @@ describe('send(file, options)', function () { .expect(301, /Redirecting to/, done) }) + // + // NOTE: This is not a real part of the API, but + // over time this has become something users + // are doing, so this will prevent unseen + // regressions around this use-case. + // + it('should try as file with empty path', function (done) { + var app = http.createServer(function (req, res) { + send(req, '', {root: path.join(fixtures, 'name.txt')}) + .pipe(res) + }) + + request(app) + .get('/') + .expect(200, 'tobi', done) + }) + it('should restrict paths to within root', function (done) { request(createServer({root: fixtures})) .get('/pets/../../send.js') From 3daa901cf731b86187e4449fa2c52f971e0b3dbc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 29 Sep 2017 15:20:01 -0400 Subject: [PATCH 194/334] Release 0.16.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index aec8b86e..1865dcd1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.16.1 / 2017-09-29 +=================== * Fix regression in edge-case behavior for empty `path` diff --git a/package.json b/package.json index baf81386..dc6d0382 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.16.0", + "version": "0.16.1", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From e8c1fdb2eb07ff73b31e30e7f33e0fdec24eb1f8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Jan 2018 20:38:58 -0500 Subject: [PATCH 195/334] build: Node.js@6.12 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ebd2de2a..96f371c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.8" - "5.12" - - "6.11" + - "6.12" - "7.10" - "8.4" sudo: false diff --git a/appveyor.yml b/appveyor.yml index 193e7594..43315b30 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.8" - nodejs_version: "5.12" - - nodejs_version: "6.11" + - nodejs_version: "6.12" - nodejs_version: "7.10" - nodejs_version: "8.4" cache: From 22821873b32a902e8fbf01a2452f84937c33e6f2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Jan 2018 20:39:59 -0500 Subject: [PATCH 196/334] docs: remove gratipay badge --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index ca591ed4..1a244035 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ [![Linux Build][travis-image]][travis-url] [![Windows Build][appveyor-image]][appveyor-url] [![Test Coverage][coveralls-image]][coveralls-url] -[![Gratipay][gratipay-image]][gratipay-url] Send is a library for streaming files from the file system as a http response supporting partial responses (Ranges), conditional-GET negotiation (If-Match, @@ -305,5 +304,3 @@ server.listen(3000) [coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master [downloads-image]: https://img.shields.io/npm/dm/send.svg [downloads-url]: https://npmjs.org/package/send -[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg -[gratipay-url]: https://www.gratipay.com/dougwilson/ From c973dba9913663ed27e1b2c6830141fa75be6cb1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Jan 2018 20:42:35 -0500 Subject: [PATCH 197/334] build: Node.js@8.9 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 96f371c8..9aea693e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.12" - "7.10" - - "8.4" + - "8.9" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 43315b30..180040c4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.12" - nodejs_version: "7.10" - - nodejs_version: "8.4" + - nodejs_version: "8.9" cache: - node_modules install: From e90aa277ff83b55858c248a003132136ac6f0113 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Jan 2018 21:10:54 -0500 Subject: [PATCH 198/334] build: eslint-plugin-import@2.8.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dc6d0382..b5fc549d 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "3.19.0", "eslint-config-standard": "10.2.1", - "eslint-plugin-import": "2.7.0", + "eslint-plugin-import": "2.8.0", "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-node": "5.2.0", "eslint-plugin-promise": "3.5.0", From f3cd2b655082364b965d3b67bb0830f402996b34 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Jan 2018 21:11:31 -0500 Subject: [PATCH 199/334] build: eslint-plugin-node@5.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b5fc549d..a6375c38 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "eslint-config-standard": "10.2.1", "eslint-plugin-import": "2.8.0", "eslint-plugin-markdown": "1.0.0-beta.6", - "eslint-plugin-node": "5.2.0", + "eslint-plugin-node": "5.2.1", "eslint-plugin-promise": "3.5.0", "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", From 6911ff6784fda06aae3cdd3d369a6342905e5bce Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Jan 2018 21:11:51 -0500 Subject: [PATCH 200/334] build: eslint-plugin-promise@3.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a6375c38..ced8bc87 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "eslint-plugin-import": "2.8.0", "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-node": "5.2.1", - "eslint-plugin-promise": "3.5.0", + "eslint-plugin-promise": "3.6.0", "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", "mocha": "2.5.3", From 386ad2f4336b6e9cbe222b3a81755da83adebcaf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 22 Jan 2018 13:26:41 -0500 Subject: [PATCH 201/334] deps: depd@~1.1.2 --- HISTORY.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 1865dcd1..6ead8911 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,9 @@ +unreleased +========== + + * deps: depd@~1.1.2 + - perf: remove argument reassignment + 0.16.1 / 2017-09-29 =================== diff --git a/package.json b/package.json index ced8bc87..6cf579d1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "dependencies": { "debug": "2.6.9", - "depd": "~1.1.1", + "depd": "~1.1.2", "destroy": "~1.0.4", "encodeurl": "~1.0.1", "escape-html": "~1.0.3", From 6469a33de9e4d16b521d9ef7148d1a470bb6bea8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 22 Jan 2018 13:29:40 -0500 Subject: [PATCH 202/334] deps: encodeurl@~1.0.2 --- HISTORY.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6ead8911..a06bc3db 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,8 @@ unreleased * deps: depd@~1.1.2 - perf: remove argument reassignment + * deps: encodeurl@~1.0.2 + - Fix encoding `%` as last character 0.16.1 / 2017-09-29 =================== diff --git a/package.json b/package.json index 6cf579d1..39c49869 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "debug": "2.6.9", "depd": "~1.1.2", "destroy": "~1.0.4", - "encodeurl": "~1.0.1", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", From 21c390a76d4c23022e08eb5646b6d6ed8553ef79 Mon Sep 17 00:00:00 2001 From: Wyatt Cready Date: Sat, 20 Jan 2018 11:53:59 -0500 Subject: [PATCH 203/334] Fix incorrect end tag in default error & redirects closes #156 --- HISTORY.md | 1 + index.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index a06bc3db..12c54fa9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix incorrect end tag in default error & redirects * deps: depd@~1.1.2 - perf: remove argument reassignment * deps: encodeurl@~1.0.2 diff --git a/index.js b/index.js index c4c96773..f297c4c5 100644 --- a/index.js +++ b/index.js @@ -972,7 +972,7 @@ function createHtmlDocument (title, body) { '\n' + '
' + body + '
\n' + '\n' + - '\n' + '\n' } /** From a60b7e1858a14e463cc4b6693e8c2418fc73970c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 24 Jan 2018 19:09:25 -0500 Subject: [PATCH 204/334] deps: statuses@~1.4.0 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 12c54fa9..56497f2a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,6 +6,7 @@ unreleased - perf: remove argument reassignment * deps: encodeurl@~1.0.2 - Fix encoding `%` as last character + * deps: statuses@~1.4.0 0.16.1 / 2017-09-29 =================== diff --git a/package.json b/package.json index 39c49869..156fa67b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "ms": "2.0.0", "on-finished": "~2.3.0", "range-parser": "~1.2.0", - "statuses": "~1.3.1" + "statuses": "~1.4.0" }, "devDependencies": { "after": "0.8.2", From c378e25a4212eb0fff2c869cbf5d0d6606bbc389 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 7 Feb 2018 11:00:04 -0500 Subject: [PATCH 205/334] Release 0.16.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 56497f2a..88ab9304 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.16.2 / 2018-02-07 +=================== * Fix incorrect end tag in default error & redirects * deps: depd@~1.1.2 diff --git a/package.json b/package.json index 156fa67b..6b3209ee 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.16.1", + "version": "0.16.2", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From 90f29102987ea1810d9d5522b7d3b8929d583123 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 11 Feb 2018 19:54:40 -0500 Subject: [PATCH 206/334] build: fix AppVeyor Node.js 0.8 build --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 180040c4..4a4e645a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,6 +17,7 @@ install: - ps: Install-Product node $env:nodejs_version - npm config set shrinkwrap false - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul + - if "%nodejs_version%" equ "0.8" npm config set strict-ssl false - for /f tokens^=2^ delims^=^" %%m in ('findstr /r /c:"eslint[^ ]" package.json') do call npm rm --save-dev %%m - if exist node_modules npm prune - if exist node_modules npm rebuild From a7eb5700cba634f6584110d5f31cf0ff2ad2e7bd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 11 Feb 2018 20:09:30 -0500 Subject: [PATCH 207/334] deps: statuses@~1.5.0 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 88ab9304..b504854f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: statuses@~1.4.0 + 0.16.2 / 2018-02-07 =================== diff --git a/package.json b/package.json index 6b3209ee..f6d3a182 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "ms": "2.0.0", "on-finished": "~2.3.0", "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "statuses": "~1.5.0" }, "devDependencies": { "after": "0.8.2", From 7b65a8ecca1e56e25c20417f36c3e445176d88e5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 7 Mar 2018 22:09:39 -0500 Subject: [PATCH 208/334] lint: apply standard 11 style --- README.md | 12 +- package.json | 8 +- test/send.js | 1028 +++++++++++++++++++++++++------------------------- 3 files changed, 524 insertions(+), 524 deletions(-) diff --git a/README.md b/README.md index 1a244035..4e95a22a 100644 --- a/README.md +++ b/README.md @@ -225,8 +225,8 @@ var send = require('send') // with a custom handler for directory listing var server = http.createServer(function onRequest (req, res) { send(req, parseUrl(req).pathname, {index: false, root: '/www/example.com/public'}) - .once('directory', directory) - .pipe(res) + .once('directory', directory) + .pipe(res) }) server.listen(3000) @@ -281,10 +281,10 @@ var server = http.createServer(function onRequest (req, res) { // transfer arbitrary files from within // /www/example.com/public/* send(req, parseUrl(req).pathname, {root: '/www/example.com/public'}) - .on('error', error) - .on('directory', redirect) - .on('headers', headers) - .pipe(res) + .on('error', error) + .on('directory', redirect) + .on('headers', headers) + .pipe(res) }) server.listen(3000) diff --git a/package.json b/package.json index f6d3a182..776fb5b4 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,11 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "3.19.0", - "eslint-config-standard": "10.2.1", - "eslint-plugin-import": "2.8.0", + "eslint": "4.18.2", + "eslint-config-standard": "11.0.0", + "eslint-plugin-import": "2.9.0", "eslint-plugin-markdown": "1.0.0-beta.6", - "eslint-plugin-node": "5.2.1", + "eslint-plugin-node": "6.0.1", "eslint-plugin-promise": "3.6.0", "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", diff --git a/test/send.js b/test/send.js index ec7ff0dd..d143c001 100644 --- a/test/send.js +++ b/test/send.js @@ -20,116 +20,116 @@ var app = http.createServer(function (req, res) { } send(req, req.url, {root: fixtures}) - .on('error', error) - .pipe(res) + .on('error', error) + .pipe(res) }) describe('send(file).pipe(res)', function () { it('should stream the file contents', function (done) { request(app) - .get('/name.txt') - .expect('Content-Length', '4') - .expect(200, 'tobi', done) + .get('/name.txt') + .expect('Content-Length', '4') + .expect(200, 'tobi', done) }) it('should stream a zero-length file', function (done) { request(app) - .get('/empty.txt') - .expect('Content-Length', '0') - .expect(200, '', done) + .get('/empty.txt') + .expect('Content-Length', '0') + .expect(200, '', done) }) it('should decode the given path as a URI', function (done) { request(app) - .get('/some%20thing.txt') - .expect(200, 'hey', done) + .get('/some%20thing.txt') + .expect(200, 'hey', done) }) it('should serve files with dots in name', function (done) { request(app) - .get('/do..ts.txt') - .expect(200, '...', done) + .get('/do..ts.txt') + .expect(200, '...', done) }) it('should treat a malformed URI as a bad request', function (done) { request(app) - .get('/some%99thing.txt') - .expect(400, 'Bad Request', done) + .get('/some%99thing.txt') + .expect(400, 'Bad Request', done) }) it('should 400 on NULL bytes', function (done) { request(app) - .get('/some%00thing.txt') - .expect(400, 'Bad Request', done) + .get('/some%00thing.txt') + .expect(400, 'Bad Request', done) }) it('should treat an ENAMETOOLONG as a 404', function (done) { var path = Array(100).join('foobar') request(app) - .get('/' + path) - .expect(404, done) + .get('/' + path) + .expect(404, done) }) it('should handle headers already sent error', function (done) { var app = http.createServer(function (req, res) { res.write('0') send(req, req.url, {root: fixtures}) - .on('error', function (err) { res.end(' - ' + err.message) }) - .pipe(res) + .on('error', function (err) { res.end(' - ' + err.message) }) + .pipe(res) }) request(app) - .get('/nums') - .expect(200, '0 - Can\'t set headers after they are sent.', done) + .get('/nums') + .expect(200, '0 - Can\'t set headers after they are sent.', done) }) it('should support HEAD', function (done) { request(app) - .head('/name.txt') - .expect('Content-Length', '4') - .expect(200, '', done) + .head('/name.txt') + .expect('Content-Length', '4') + .expect(200, '', done) }) it('should add an ETag header field', function (done) { request(app) - .get('/name.txt') - .expect('etag', /^W\/"[^"]+"$/) - .end(done) + .get('/name.txt') + .expect('etag', /^W\/"[^"]+"$/) + .end(done) }) it('should add a Date header field', function (done) { request(app) - .get('/name.txt') - .expect('date', dateRegExp, done) + .get('/name.txt') + .expect('date', dateRegExp, done) }) it('should add a Last-Modified header field', function (done) { request(app) - .get('/name.txt') - .expect('last-modified', dateRegExp, done) + .get('/name.txt') + .expect('last-modified', dateRegExp, done) }) it('should add a Accept-Ranges header field', function (done) { request(app) - .get('/name.txt') - .expect('Accept-Ranges', 'bytes', done) + .get('/name.txt') + .expect('Accept-Ranges', 'bytes', done) }) it('should 404 if the file does not exist', function (done) { request(app) - .get('/meow') - .expect(404, 'Not Found', done) + .get('/meow') + .expect(404, 'Not Found', done) }) it('should emit ENOENT if the file does not exist', function (done) { var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('error', function (err) { res.end(err.statusCode + ' ' + err.code) }) - .pipe(res) + .on('error', function (err) { res.end(err.statusCode + ' ' + err.code) }) + .pipe(res) }) request(app) - .get('/meow') - .expect(200, '404 ENOENT', done) + .get('/meow') + .expect(200, '404 ENOENT', done) }) it('should not override content-type', function (done) { @@ -138,56 +138,56 @@ describe('send(file).pipe(res)', function () { send(req, req.url, {root: fixtures}).pipe(res) }) request(app) - .get('/nums') - .expect('Content-Type', 'application/x-custom', done) + .get('/nums') + .expect('Content-Type', 'application/x-custom', done) }) it('should set Content-Type via mime map', function (done) { request(app) - .get('/name.txt') - .expect('Content-Type', 'text/plain; charset=UTF-8') - .expect(200, function (err) { - if (err) return done(err) - request(app) - .get('/tobi.html') - .expect('Content-Type', 'text/html; charset=UTF-8') - .expect(200, done) - }) + .get('/name.txt') + .expect('Content-Type', 'text/plain; charset=UTF-8') + .expect(200, function (err) { + if (err) return done(err) + request(app) + .get('/tobi.html') + .expect('Content-Type', 'text/html; charset=UTF-8') + .expect(200, done) + }) }) it('should 404 if file disappears after stat, before open', function (done) { var app = http.createServer(function (req, res) { send(req, req.url, {root: 'test/fixtures'}) - .on('file', function () { + .on('file', function () { // simulate file ENOENT after on open, after stat - var fn = this.send - this.send = function (path, stat) { - fn.call(this, (path + '__xxx_no_exist'), stat) - } - }) - .pipe(res) + var fn = this.send + this.send = function (path, stat) { + fn.call(this, (path + '__xxx_no_exist'), stat) + } + }) + .pipe(res) }) request(app) - .get('/name.txt') - .expect(404, done) + .get('/name.txt') + .expect(404, done) }) it('should 500 on file stream error', function (done) { var app = http.createServer(function (req, res) { send(req, req.url, {root: 'test/fixtures'}) - .on('stream', function (stream) { + .on('stream', function (stream) { // simulate file error - process.nextTick(function () { - stream.emit('error', new Error('boom!')) + process.nextTick(function () { + stream.emit('error', new Error('boom!')) + }) }) - }) - .pipe(res) + .pipe(res) }) request(app) - .get('/name.txt') - .expect(500, done) + .get('/name.txt') + .expect(500, done) }) describe('"headers" event', function () { @@ -195,60 +195,60 @@ describe('send(file).pipe(res)', function () { var cb = after(2, done) var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('headers', function () { cb() }) - .pipe(res) + .on('headers', function () { cb() }) + .pipe(res) }) request(server) - .get('/nums') - .expect(200, '123456789', cb) + .get('/nums') + .expect(200, '123456789', cb) }) it('should not fire on 404', function (done) { var cb = after(1, done) var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('headers', function () { cb() }) - .pipe(res) + .on('headers', function () { cb() }) + .pipe(res) }) request(server) - .get('/bogus') - .expect(404, cb) + .get('/bogus') + .expect(404, cb) }) it('should fire on index', function (done) { var cb = after(2, done) var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('headers', function () { cb() }) - .pipe(res) + .on('headers', function () { cb() }) + .pipe(res) }) request(server) - .get('/pets/') - .expect(200, /tobi/, cb) + .get('/pets/') + .expect(200, /tobi/, cb) }) it('should not fire on redirect', function (done) { var cb = after(1, done) var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('headers', function () { cb() }) - .pipe(res) + .on('headers', function () { cb() }) + .pipe(res) }) request(server) - .get('/pets') - .expect(301, cb) + .get('/pets') + .expect(301, cb) }) it('should provide path', function (done) { var cb = after(2, done) var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('headers', onHeaders) - .pipe(res) + .on('headers', onHeaders) + .pipe(res) }) function onHeaders (res, filePath) { @@ -258,16 +258,16 @@ describe('send(file).pipe(res)', function () { } request(server) - .get('/nums') - .expect(200, '123456789', cb) + .get('/nums') + .expect(200, '123456789', cb) }) it('should provide stat', function (done) { var cb = after(2, done) var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('headers', onHeaders) - .pipe(res) + .on('headers', onHeaders) + .pipe(res) }) function onHeaders (res, path, stat) { @@ -278,15 +278,15 @@ describe('send(file).pipe(res)', function () { } request(server) - .get('/nums') - .expect(200, '123456789', cb) + .get('/nums') + .expect(200, '123456789', cb) }) it('should allow altering headers', function (done) { var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('headers', onHeaders) - .pipe(res) + .on('headers', onHeaders) + .pipe(res) }) function onHeaders (res, path, stat) { @@ -297,12 +297,12 @@ describe('send(file).pipe(res)', function () { } request(server) - .get('/nums') - .expect('Cache-Control', 'no-cache') - .expect('Content-Type', 'text/x-custom') - .expect('ETag', 'W/"everything"') - .expect('X-Created', dateRegExp) - .expect(200, '123456789', done) + .get('/nums') + .expect('Cache-Control', 'no-cache') + .expect('Content-Type', 'text/x-custom') + .expect('ETag', 'W/"everything"') + .expect('X-Created', dateRegExp) + .expect(200, '123456789', done) }) }) @@ -310,8 +310,8 @@ describe('send(file).pipe(res)', function () { it('should be called when sending directory', function (done) { var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('directory', onDirectory) - .pipe(res) + .on('directory', onDirectory) + .pipe(res) }) function onDirectory (res) { @@ -320,15 +320,15 @@ describe('send(file).pipe(res)', function () { } request(server) - .get('/pets') - .expect(400, 'No directory for you', done) + .get('/pets') + .expect(400, 'No directory for you', done) }) it('should be called with path', function (done) { var server = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .on('directory', onDirectory) - .pipe(res) + .on('directory', onDirectory) + .pipe(res) }) function onDirectory (res, dirPath) { @@ -336,68 +336,68 @@ describe('send(file).pipe(res)', function () { } request(server) - .get('/pets') - .expect(200, path.normalize(path.join(fixtures, 'pets')), done) + .get('/pets') + .expect(200, path.normalize(path.join(fixtures, 'pets')), done) }) }) describe('when no "directory" listeners are present', function () { it('should redirect directories to trailing slash', function (done) { request(createServer({root: fixtures})) - .get('/pets') - .expect('Location', '/pets/') - .expect(301, done) + .get('/pets') + .expect('Location', '/pets/') + .expect(301, done) }) it('should respond with an HTML redirect', function (done) { request(createServer({root: fixtures})) - .get('/pets') - .expect('Location', '/pets/') - .expect('Content-Type', /html/) - .expect(301, />Redirecting to \/pets\/<\/a>Redirecting to \/pets\/<\/a>Redirecting to \/snow%20%E2%98%83\/<\/a>Redirecting to \/snow%20%E2%98%83\/<\/a>Not FoundNot Foundtobi

', done) + .get('/') + .expect(200, '

tobi

', done) }) it('should support disabling', function (done) { var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .index(false) - .pipe(res) + .index(false) + .pipe(res) }) request(app) - .get('/pets/') - .expect(403, done) + .get('/pets/') + .expect(403, done) }) it('should support fallbacks', function (done) { var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures}) - .index(['default.htm', 'index.html']) - .pipe(res) + .index(['default.htm', 'index.html']) + .pipe(res) }) request(app) - .get('/pets/') - .expect(200, fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) + .get('/pets/') + .expect(200, fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) }) }) @@ -853,49 +853,49 @@ describe('send(file).pipe(res)', function () { it('should default to 0', function (done) { var app = http.createServer(function (req, res) { send(req, 'test/fixtures/name.txt') - .maxage(undefined) - .pipe(res) + .maxage(undefined) + .pipe(res) }) request(app) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=0', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=0', done) }) it('should floor to integer', function (done) { var app = http.createServer(function (req, res) { send(req, 'test/fixtures/name.txt') - .maxage(1234) - .pipe(res) + .maxage(1234) + .pipe(res) }) request(app) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=1', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=1', done) }) it('should accept string', function (done) { var app = http.createServer(function (req, res) { send(req, 'test/fixtures/name.txt') - .maxage('30d') - .pipe(res) + .maxage('30d') + .pipe(res) }) request(app) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=2592000', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=2592000', done) }) it('should max at 1 year', function (done) { var app = http.createServer(function (req, res) { send(req, 'test/fixtures/name.txt') - .maxage(Infinity) - .pipe(res) + .maxage(Infinity) + .pipe(res) }) request(app) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=31536000', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=31536000', done) }) }) @@ -903,13 +903,13 @@ describe('send(file).pipe(res)', function () { it('should set root', function (done) { var app = http.createServer(function (req, res) { send(req, req.url) - .root(fixtures) - .pipe(res) + .root(fixtures) + .pipe(res) }) request(app) - .get('/pets/../name.txt') - .expect(200, 'tobi', done) + .get('/pets/../name.txt') + .expect(200, 'tobi', done) }) }) }) @@ -918,211 +918,211 @@ describe('send(file, options)', function () { describe('acceptRanges', function () { it('should support disabling accept-ranges', function (done) { request(createServer({acceptRanges: false, root: fixtures})) - .get('/nums') - .expect(shouldNotHaveHeader('Accept-Ranges')) - .expect(200, done) + .get('/nums') + .expect(shouldNotHaveHeader('Accept-Ranges')) + .expect(200, done) }) it('should ignore requested range', function (done) { request(createServer({acceptRanges: false, root: fixtures})) - .get('/nums') - .set('Range', 'bytes=0-2') - .expect(shouldNotHaveHeader('Accept-Ranges')) - .expect(shouldNotHaveHeader('Content-Range')) - .expect(200, '123456789', done) + .get('/nums') + .set('Range', 'bytes=0-2') + .expect(shouldNotHaveHeader('Accept-Ranges')) + .expect(shouldNotHaveHeader('Content-Range')) + .expect(200, '123456789', done) }) }) describe('cacheControl', function () { it('should support disabling cache-control', function (done) { request(createServer({cacheControl: false, root: fixtures})) - .get('/nums') - .expect(shouldNotHaveHeader('Cache-Control')) - .expect(200, done) + .get('/nums') + .expect(shouldNotHaveHeader('Cache-Control')) + .expect(200, done) }) it('should ignore maxAge option', function (done) { request(createServer({cacheControl: false, maxAge: 1000, root: fixtures})) - .get('/nums') - .expect(shouldNotHaveHeader('Cache-Control')) - .expect(200, done) + .get('/nums') + .expect(shouldNotHaveHeader('Cache-Control')) + .expect(200, done) }) }) describe('etag', function () { it('should support disabling etags', function (done) { request(createServer({etag: false, root: fixtures})) - .get('/nums') - .expect(shouldNotHaveHeader('ETag')) - .expect(200, done) + .get('/nums') + .expect(shouldNotHaveHeader('ETag')) + .expect(200, done) }) }) describe('extensions', function () { it('should reject numbers', function (done) { request(createServer({extensions: 42, root: fixtures})) - .get('/pets/') - .expect(500, /TypeError: extensions option/, done) + .get('/pets/') + .expect(500, /TypeError: extensions option/, done) }) it('should reject true', function (done) { request(createServer({extensions: true, root: fixtures})) - .get('/pets/') - .expect(500, /TypeError: extensions option/, done) + .get('/pets/') + .expect(500, /TypeError: extensions option/, done) }) it('should be not be enabled by default', function (done) { request(createServer({root: fixtures})) - .get('/tobi') - .expect(404, done) + .get('/tobi') + .expect(404, done) }) it('should be configurable', function (done) { request(createServer({extensions: 'txt', root: fixtures})) - .get('/name') - .expect(200, 'tobi', done) + .get('/name') + .expect(200, 'tobi', done) }) it('should support disabling extensions', function (done) { request(createServer({extensions: false, root: fixtures})) - .get('/name') - .expect(404, done) + .get('/name') + .expect(404, done) }) it('should support fallbacks', function (done) { request(createServer({extensions: ['htm', 'html', 'txt'], root: fixtures})) - .get('/name') - .expect(200, '

tobi

', done) + .get('/name') + .expect(200, '

tobi

', done) }) it('should 404 if nothing found', function (done) { request(createServer({extensions: ['htm', 'html', 'txt'], root: fixtures})) - .get('/bob') - .expect(404, done) + .get('/bob') + .expect(404, done) }) it('should skip directories', function (done) { request(createServer({extensions: ['file', 'dir'], root: fixtures})) - .get('/name') - .expect(404, done) + .get('/name') + .expect(404, done) }) it('should not search if file has extension', function (done) { request(createServer({extensions: 'html', root: fixtures})) - .get('/thing.html') - .expect(404, done) + .get('/thing.html') + .expect(404, done) }) }) describe('lastModified', function () { it('should support disabling last-modified', function (done) { request(createServer({lastModified: false, root: fixtures})) - .get('/nums') - .expect(shouldNotHaveHeader('Last-Modified')) - .expect(200, done) + .get('/nums') + .expect(shouldNotHaveHeader('Last-Modified')) + .expect(200, done) }) }) describe('from', function () { it('should set with deprecated from', function (done) { request(createServer({from: fixtures})) - .get('/pets/../name.txt') - .expect(200, 'tobi', done) + .get('/pets/../name.txt') + .expect(200, 'tobi', done) }) }) describe('dotfiles', function () { it('should default to "ignore"', function (done) { request(createServer({root: fixtures})) - .get('/.hidden') - .expect(404, done) + .get('/.hidden') + .expect(404, done) }) it('should allow file within dotfile directory for back-compat', function (done) { request(createServer({root: fixtures})) - .get('/.mine/name.txt') - .expect(200, /tobi/, done) + .get('/.mine/name.txt') + .expect(200, /tobi/, done) }) it('should reject bad value', function (done) { request(createServer({dotfiles: 'bogus'})) - .get('/nums') - .expect(500, /dotfiles/, done) + .get('/nums') + .expect(500, /dotfiles/, done) }) describe('when "allow"', function (done) { it('should send dotfile', function (done) { request(createServer({dotfiles: 'allow', root: fixtures})) - .get('/.hidden') - .expect(200, /secret/, done) + .get('/.hidden') + .expect(200, /secret/, done) }) it('should send within dotfile directory', function (done) { request(createServer({dotfiles: 'allow', root: fixtures})) - .get('/.mine/name.txt') - .expect(200, /tobi/, done) + .get('/.mine/name.txt') + .expect(200, /tobi/, done) }) it('should 404 for non-existent dotfile', function (done) { request(createServer({dotfiles: 'allow', root: fixtures})) - .get('/.nothere') - .expect(404, done) + .get('/.nothere') + .expect(404, done) }) }) describe('when "deny"', function (done) { it('should 403 for dotfile', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/.hidden') - .expect(403, done) + .get('/.hidden') + .expect(403, done) }) it('should 403 for dotfile directory', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/.mine') - .expect(403, done) + .get('/.mine') + .expect(403, done) }) it('should 403 for dotfile directory with trailing slash', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/.mine/') - .expect(403, done) + .get('/.mine/') + .expect(403, done) }) it('should 403 for file within dotfile directory', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/.mine/name.txt') - .expect(403, done) + .get('/.mine/name.txt') + .expect(403, done) }) it('should 403 for non-existent dotfile', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/.nothere') - .expect(403, done) + .get('/.nothere') + .expect(403, done) }) it('should 403 for non-existent dotfile directory', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/.what/name.txt') - .expect(403, done) + .get('/.what/name.txt') + .expect(403, done) }) it('should 403 for dotfile in directory', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/pets/.hidden') - .expect(403, done) + .get('/pets/.hidden') + .expect(403, done) }) it('should 403 for dotfile in dotfile directory', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/.mine/.hidden') - .expect(403, done) + .get('/.mine/.hidden') + .expect(403, done) }) it('should send files in root dotfile directory', function (done) { request(createServer({dotfiles: 'deny', root: path.join(fixtures, '.mine')})) - .get('/name.txt') - .expect(200, /tobi/, done) + .get('/name.txt') + .expect(200, /tobi/, done) }) it('should 403 for dotfile without root', function (done) { @@ -1131,52 +1131,52 @@ describe('send(file, options)', function () { }) request(server) - .get('/name.txt') - .expect(403, done) + .get('/name.txt') + .expect(403, done) }) }) describe('when "ignore"', function (done) { it('should 404 for dotfile', function (done) { request(createServer({dotfiles: 'ignore', root: fixtures})) - .get('/.hidden') - .expect(404, done) + .get('/.hidden') + .expect(404, done) }) it('should 404 for dotfile directory', function (done) { request(createServer({dotfiles: 'ignore', root: fixtures})) - .get('/.mine') - .expect(404, done) + .get('/.mine') + .expect(404, done) }) it('should 404 for dotfile directory with trailing slash', function (done) { request(createServer({dotfiles: 'ignore', root: fixtures})) - .get('/.mine/') - .expect(404, done) + .get('/.mine/') + .expect(404, done) }) it('should 404 for file within dotfile directory', function (done) { request(createServer({dotfiles: 'ignore', root: fixtures})) - .get('/.mine/name.txt') - .expect(404, done) + .get('/.mine/name.txt') + .expect(404, done) }) it('should 404 for non-existent dotfile', function (done) { request(createServer({dotfiles: 'ignore', root: fixtures})) - .get('/.nothere') - .expect(404, done) + .get('/.nothere') + .expect(404, done) }) it('should 404 for non-existent dotfile directory', function (done) { request(createServer({dotfiles: 'ignore', root: fixtures})) - .get('/.what/name.txt') - .expect(404, done) + .get('/.what/name.txt') + .expect(404, done) }) it('should send files in root dotfile directory', function (done) { request(createServer({dotfiles: 'ignore', root: path.join(fixtures, '.mine')})) - .get('/name.txt') - .expect(200, /tobi/, done) + .get('/name.txt') + .expect(200, /tobi/, done) }) it('should 404 for dotfile without root', function (done) { @@ -1185,8 +1185,8 @@ describe('send(file, options)', function () { }) request(server) - .get('/name.txt') - .expect(404, done) + .get('/name.txt') + .expect(404, done) }) }) }) @@ -1194,122 +1194,122 @@ describe('send(file, options)', function () { describe('hidden', function () { it('should default to false', function (done) { request(app) - .get('/.hidden') - .expect(404, 'Not Found', done) + .get('/.hidden') + .expect(404, 'Not Found', done) }) it('should default support sending hidden files', function (done) { request(createServer({hidden: true, root: fixtures})) - .get('/.hidden') - .expect(200, /secret/, done) + .get('/.hidden') + .expect(200, /secret/, done) }) }) describe('immutable', function () { it('should default to false', function (done) { request(createServer({root: fixtures})) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=0', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=0', done) }) it('should set immutable directive in Cache-Control', function (done) { request(createServer({immutable: true, maxAge: '1h', root: fixtures})) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=3600, immutable', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=3600, immutable', done) }) }) describe('maxAge', function () { it('should default to 0', function (done) { request(createServer({root: fixtures})) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=0', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=0', done) }) it('should floor to integer', function (done) { request(createServer({maxAge: 123956, root: fixtures})) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=123', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=123', done) }) it('should accept string', function (done) { request(createServer({maxAge: '30d', root: fixtures})) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=2592000', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=2592000', done) }) it('should max at 1 year', function (done) { request(createServer({maxAge: '2y', root: fixtures})) - .get('/name.txt') - .expect('Cache-Control', 'public, max-age=31536000', done) + .get('/name.txt') + .expect('Cache-Control', 'public, max-age=31536000', done) }) }) describe('index', function () { it('should reject numbers', function (done) { request(createServer({root: fixtures, index: 42})) - .get('/pets/') - .expect(500, /TypeError: index option/, done) + .get('/pets/') + .expect(500, /TypeError: index option/, done) }) it('should reject true', function (done) { request(createServer({root: fixtures, index: true})) - .get('/pets/') - .expect(500, /TypeError: index option/, done) + .get('/pets/') + .expect(500, /TypeError: index option/, done) }) it('should default to index.html', function (done) { request(createServer({root: fixtures})) - .get('/pets/') - .expect(fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) + .get('/pets/') + .expect(fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) }) it('should be configurable', function (done) { request(createServer({root: fixtures, index: 'tobi.html'})) - .get('/') - .expect(200, '

tobi

', done) + .get('/') + .expect(200, '

tobi

', done) }) it('should support disabling', function (done) { request(createServer({root: fixtures, index: false})) - .get('/pets/') - .expect(403, done) + .get('/pets/') + .expect(403, done) }) it('should support fallbacks', function (done) { request(createServer({root: fixtures, index: ['default.htm', 'index.html']})) - .get('/pets/') - .expect(200, fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) + .get('/pets/') + .expect(200, fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) }) it('should 404 if no index file found (file)', function (done) { request(createServer({root: fixtures, index: 'default.htm'})) - .get('/pets/') - .expect(404, done) + .get('/pets/') + .expect(404, done) }) it('should 404 if no index file found (dir)', function (done) { request(createServer({root: fixtures, index: 'pets'})) - .get('/') - .expect(404, done) + .get('/') + .expect(404, done) }) it('should not follow directories', function (done) { request(createServer({root: fixtures, index: ['pets', 'name.txt']})) - .get('/') - .expect(200, 'tobi', done) + .get('/') + .expect(200, 'tobi', done) }) it('should work without root', function (done) { var server = http.createServer(function (req, res) { var p = path.join(fixtures, 'pets').replace(/\\/g, '/') + '/' send(req, p, {index: ['index.html']}) - .pipe(res) + .pipe(res) }) request(server) - .get('/') - .expect(200, /tobi/, done) + .get('/') + .expect(200, /tobi/, done) }) }) @@ -1317,30 +1317,30 @@ describe('send(file, options)', function () { describe('when given', function () { it('should join root', function (done) { request(createServer({root: fixtures})) - .get('/pets/../name.txt') - .expect(200, 'tobi', done) + .get('/pets/../name.txt') + .expect(200, 'tobi', done) }) it('should work with trailing slash', function (done) { var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures + '/'}) - .pipe(res) + .pipe(res) }) request(app) - .get('/name.txt') - .expect(200, 'tobi', done) + .get('/name.txt') + .expect(200, 'tobi', done) }) it('should work with empty path', function (done) { var app = http.createServer(function (req, res) { send(req, '', {root: fixtures}) - .pipe(res) + .pipe(res) }) request(app) - .get('/name.txt') - .expect(301, /Redirecting to/, done) + .get('/name.txt') + .expect(301, /Redirecting to/, done) }) // @@ -1352,41 +1352,41 @@ describe('send(file, options)', function () { it('should try as file with empty path', function (done) { var app = http.createServer(function (req, res) { send(req, '', {root: path.join(fixtures, 'name.txt')}) - .pipe(res) + .pipe(res) }) request(app) - .get('/') - .expect(200, 'tobi', done) + .get('/') + .expect(200, 'tobi', done) }) it('should restrict paths to within root', function (done) { request(createServer({root: fixtures})) - .get('/pets/../../send.js') - .expect(403, done) + .get('/pets/../../send.js') + .expect(403, done) }) it('should allow .. in root', function (done) { var app = http.createServer(function (req, res) { send(req, req.url, {root: fixtures + '/../fixtures'}) - .pipe(res) + .pipe(res) }) request(app) - .get('/pets/../../send.js') - .expect(403, done) + .get('/pets/../../send.js') + .expect(403, done) }) it('should not allow root transversal', function (done) { request(createServer({root: path.join(fixtures, 'name.d')})) - .get('/../name.dir/name.txt') - .expect(403, done) + .get('/../name.dir/name.txt') + .expect(403, done) }) it('should not allow root path disclosure', function (done) { request(createServer({root: fixtures})) - .get('/pets/../../fixtures/name.txt') - .expect(403, done) + .get('/pets/../../fixtures/name.txt') + .expect(403, done) }) }) @@ -1394,23 +1394,23 @@ describe('send(file, options)', function () { it('should consider .. malicious', function (done) { var app = http.createServer(function (req, res) { send(req, fixtures + req.url) - .pipe(res) + .pipe(res) }) request(app) - .get('/../send.js') - .expect(403, done) + .get('/../send.js') + .expect(403, done) }) it('should still serve files with dots in name', function (done) { var app = http.createServer(function (req, res) { send(req, fixtures + req.url) - .pipe(res) + .pipe(res) }) request(app) - .get('/do..ts.txt') - .expect(200, '...', done) + .get('/do..ts.txt') + .expect(200, '...', done) }) }) }) @@ -1434,18 +1434,18 @@ describe('send.mime', function () { send.mime.default_type = 'text/plain' request(createServer({root: fixtures})) - .get('/nums') - .expect('Content-Type', 'text/plain; charset=UTF-8') - .expect(200, done) + .get('/nums') + .expect('Content-Type', 'text/plain; charset=UTF-8') + .expect(200, done) }) it('should not add Content-Type for undefined default', function (done) { send.mime.default_type = undefined request(createServer({root: fixtures})) - .get('/nums') - .expect(shouldNotHaveHeader('Content-Type')) - .expect(200, done) + .get('/nums') + .expect(shouldNotHaveHeader('Content-Type')) + .expect(200, done) }) }) }) From cefe58e762b548da790f2b15eb321fb40f297d4b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Apr 2018 12:22:31 -0400 Subject: [PATCH 209/334] docs: improve the examples --- README.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4e95a22a..de1629e1 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,27 @@ $ npm test ## Examples -### Small example +### Serve a specific file + +This simple example will send a specific file to all requests. + +```js +var http = require('http') +var send = require('send') + +var server = http.createServer(function onRequest (req, res) { + send(req, '/path/to/index.html') + .pipe(res) +}) + +server.listen(3000) +``` + +### Serve all files from a directory + +This simple example will just serve up all the files in a +given directory as the top-level. For example, a request +`GET /foo.txt` will send back `/www/public/foo.txt`. ```js var http = require('http') @@ -182,7 +202,8 @@ var parseUrl = require('parseurl') var send = require('send') var server = http.createServer(function onRequest (req, res) { - send(req, parseUrl(req).pathname).pipe(res) + send(req, parseUrl(req).pathname, { root: '/www/public' }) + .pipe(res) }) server.listen(3000) @@ -204,7 +225,8 @@ send.mime.define({ }) var server = http.createServer(function onRequest (req, res) { - send(req, parseUrl(req).pathname).pipe(res) + send(req, parseUrl(req).pathname, { root: '/www/public' }) + .pipe(res) }) server.listen(3000) @@ -224,7 +246,7 @@ var send = require('send') // Transfer arbitrary files from within /www/example.com/public/* // with a custom handler for directory listing var server = http.createServer(function onRequest (req, res) { - send(req, parseUrl(req).pathname, {index: false, root: '/www/example.com/public'}) + send(req, parseUrl(req).pathname, { index: false, root: '/www/public' }) .once('directory', directory) .pipe(res) }) @@ -280,7 +302,7 @@ var server = http.createServer(function onRequest (req, res) { // transfer arbitrary files from within // /www/example.com/public/* - send(req, parseUrl(req).pathname, {root: '/www/example.com/public'}) + send(req, parseUrl(req).pathname, { root: '/www/public' }) .on('error', error) .on('directory', redirect) .on('headers', headers) From d5c2f1e811895743627178404786908a07347076 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Apr 2018 12:23:39 -0400 Subject: [PATCH 210/334] build: Node.js@6.13 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9aea693e..ad14167f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.8" - "5.12" - - "6.12" + - "6.13" - "7.10" - "8.9" sudo: false diff --git a/appveyor.yml b/appveyor.yml index 4a4e645a..9f47b057 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.8" - nodejs_version: "5.12" - - nodejs_version: "6.12" + - nodejs_version: "6.13" - nodejs_version: "7.10" - nodejs_version: "8.9" cache: From cf4c6a14e1300c814253d780923d21bb0b6877d0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 20 Apr 2018 12:23:52 -0400 Subject: [PATCH 211/334] build: Node.js@8.10 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ad14167f..3920fff8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.13" - "7.10" - - "8.9" + - "8.10" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 9f47b057..ffb55568 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.13" - nodejs_version: "7.10" - - nodejs_version: "8.9" + - nodejs_version: "8.10" cache: - node_modules install: From f10d34b92029278a464145e76fdfd41615955e45 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 1 May 2018 09:20:02 -0400 Subject: [PATCH 212/334] docs: fix typo in history --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index b504854f..103f4aa0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,7 @@ unreleased ========== - * deps: statuses@~1.4.0 + * deps: statuses@~1.5.0 0.16.2 / 2018-02-07 =================== From af3cd0f7741afbb034f3ac0f3ebd88e40d66e514 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 1 May 2018 09:28:21 -0400 Subject: [PATCH 213/334] build: Node.js@4.9 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3920fff8..bac0f5f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ node_js: - "1.8" - "2.5" - "3.3" - - "4.8" + - "4.9" - "5.12" - "6.13" - "7.10" diff --git a/appveyor.yml b/appveyor.yml index ffb55568..a7e35961 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: - nodejs_version: "1.8" - nodejs_version: "2.5" - nodejs_version: "3.3" - - nodejs_version: "4.8" + - nodejs_version: "4.9" - nodejs_version: "5.12" - nodejs_version: "6.13" - nodejs_version: "7.10" From 8f11db09ffad8d6ee041f809b2da485c47dfe090 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 1 May 2018 09:34:40 -0400 Subject: [PATCH 214/334] build: Node.js@6.14 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bac0f5f5..30021aa2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.9" - "5.12" - - "6.13" + - "6.14" - "7.10" - "8.10" sudo: false diff --git a/appveyor.yml b/appveyor.yml index a7e35961..b4b45248 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.9" - nodejs_version: "5.12" - - nodejs_version: "6.13" + - nodejs_version: "6.14" - nodejs_version: "7.10" - nodejs_version: "8.10" cache: From c41ebcaff4c30723dd3139e8c74c85cfb297d4fe Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 1 May 2018 09:39:02 -0400 Subject: [PATCH 215/334] build: Node.js@8.11 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 30021aa2..5c646083 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.14" - "7.10" - - "8.10" + - "8.11" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index b4b45248..96c4cc13 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.14" - nodejs_version: "7.10" - - nodejs_version: "8.10" + - nodejs_version: "8.11" cache: - node_modules install: From 8f9db9280ca003caecce2dc753c77d95e45b3d91 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 6 May 2018 15:50:31 -0400 Subject: [PATCH 216/334] deps: http-errors@~1.6.3 --- HISTORY.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 103f4aa0..741989eb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ unreleased ========== + * deps: http-errors@~1.6.3 + - deps: depd@~1.1.2 + - deps: setprototypeof@1.1.0 + - deps: statuses@'>= 1.3.1 < 2' * deps: statuses@~1.5.0 0.16.2 / 2018-02-07 diff --git a/package.json b/package.json index 776fb5b4..3b463ee8 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", + "http-errors": "~1.6.3", "mime": "1.4.1", "ms": "2.0.0", "on-finished": "~2.3.0", From 9becebbd281168096464e820e240b8548ee9f291 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 7 May 2018 13:30:01 -0400 Subject: [PATCH 217/334] build: eslint@4.19.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b463ee8..715e418f 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "4.18.2", + "eslint": "4.19.1", "eslint-config-standard": "11.0.0", "eslint-plugin-import": "2.9.0", "eslint-plugin-markdown": "1.0.0-beta.6", From 601002d06448768f7a8a4556c92818de6e262c85 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 10 May 2018 01:20:21 -0400 Subject: [PATCH 218/334] build: eslint-plugin-standard@3.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 715e418f..66c2f16f 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-node": "6.0.1", "eslint-plugin-promise": "3.6.0", - "eslint-plugin-standard": "3.0.1", + "eslint-plugin-standard": "3.1.0", "istanbul": "0.4.5", "mocha": "2.5.3", "supertest": "1.1.0" From e0cdeec3d86a85e38b4d9925af4734d77c13c0ff Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 26 May 2018 23:40:25 -0400 Subject: [PATCH 219/334] build: eslint-plugin-promise@3.8.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 66c2f16f..64e70245 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "eslint-plugin-import": "2.9.0", "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-node": "6.0.1", - "eslint-plugin-promise": "3.6.0", + "eslint-plugin-promise": "3.8.0", "eslint-plugin-standard": "3.1.0", "istanbul": "0.4.5", "mocha": "2.5.3", From a94271e2604ba953328ea2b2da8f65526c882b6c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 26 May 2018 23:49:07 -0400 Subject: [PATCH 220/334] build: eslint-plugin-import@2.12.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 64e70245..751c11f8 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "4.19.1", "eslint-config-standard": "11.0.0", - "eslint-plugin-import": "2.9.0", + "eslint-plugin-import": "2.12.0", "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-node": "6.0.1", "eslint-plugin-promise": "3.8.0", From 97c33ef0d26a98b44c197cfa32637fd8c635e8fd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 May 2018 00:04:38 -0400 Subject: [PATCH 221/334] build: support Node.js 9.x --- .travis.yml | 1 + appveyor.yml | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5c646083..1be3cbce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ node_js: - "6.14" - "7.10" - "8.11" + - "9.11" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 96c4cc13..57e1bf50 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,10 +11,13 @@ environment: - nodejs_version: "6.14" - nodejs_version: "7.10" - nodejs_version: "8.11" + - nodejs_version: "9.11" cache: - node_modules install: - - ps: Install-Product node $env:nodejs_version + - ps: >- + try { Install-Product node $env:nodejs_version -ErrorAction Stop } + catch { Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) } - npm config set shrinkwrap false - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul - if "%nodejs_version%" equ "0.8" npm config set strict-ssl false From 1fc942549a205474071ae35c3bf53445f96a983c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 27 May 2018 00:15:03 -0400 Subject: [PATCH 222/334] build: support Node.js 10.x --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 1be3cbce..b419a374 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ node_js: - "7.10" - "8.11" - "9.11" + - "10.2" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 57e1bf50..d0199f56 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,6 +12,7 @@ environment: - nodejs_version: "7.10" - nodejs_version: "8.11" - nodejs_version: "9.11" + - nodejs_version: "10.2" cache: - node_modules install: From 9542ffd3a020edffc8eb2e9c422dda1c7a486a54 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 7 Aug 2018 18:09:25 -0400 Subject: [PATCH 223/334] build: eslint-plugin-import@2.13.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 751c11f8..69bb74c3 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "4.19.1", "eslint-config-standard": "11.0.0", - "eslint-plugin-import": "2.12.0", + "eslint-plugin-import": "2.13.0", "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-node": "6.0.1", "eslint-plugin-promise": "3.8.0", From fc7b79b4ee08395c8a2d7befc5eb8d74e1f9b8db Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 7 Aug 2018 18:16:04 -0400 Subject: [PATCH 224/334] build: Node.js@10.8 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b419a374..f80172ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.11" - "9.11" - - "10.2" + - "10.8" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index d0199f56..dcdb3325 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,7 @@ environment: - nodejs_version: "7.10" - nodejs_version: "8.11" - nodejs_version: "9.11" - - nodejs_version: "10.2" + - nodejs_version: "10.8" cache: - node_modules install: From f5886265326192c6b7658def7fbcf2fa8c71a3cf Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 8 Aug 2018 22:01:27 -0400 Subject: [PATCH 225/334] build: use yaml eslint configuration --- .eslintrc | 6 ------ .eslintrc.yml | 4 ++++ test/.eslintrc | 5 ----- test/.eslintrc.yml | 2 ++ 4 files changed, 6 insertions(+), 11 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.yml delete mode 100644 test/.eslintrc create mode 100644 test/.eslintrc.yml diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index a819f736..00000000 --- a/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "standard", - "rules": { - "no-param-reassign": "error" - } -} diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 00000000..c6a7986c --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,4 @@ +root: true +extends: standard +rules: + no-param-reassign: error diff --git a/test/.eslintrc b/test/.eslintrc deleted file mode 100644 index 7eeefc33..00000000 --- a/test/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "env": { - "mocha": true - } -} diff --git a/test/.eslintrc.yml b/test/.eslintrc.yml new file mode 100644 index 00000000..9808c3b2 --- /dev/null +++ b/test/.eslintrc.yml @@ -0,0 +1,2 @@ +env: + mocha: true From a17c053568c269d99e5b6671abeab341f4d7783a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 14 Aug 2018 16:09:28 -0400 Subject: [PATCH 226/334] tests: fix flaky test --- test/send.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/send.js b/test/send.js index d143c001..51dd3a5d 100644 --- a/test/send.js +++ b/test/send.js @@ -178,7 +178,7 @@ describe('send(file).pipe(res)', function () { send(req, req.url, {root: 'test/fixtures'}) .on('stream', function (stream) { // simulate file error - process.nextTick(function () { + stream.on('open', function () { stream.emit('error', new Error('boom!')) }) }) From 24f6531115eca11c013ccc7578c73d5f632c3c69 Mon Sep 17 00:00:00 2001 From: Feross Aboukhadijeh Date: Tue, 14 Aug 2018 11:35:27 -0700 Subject: [PATCH 227/334] perf: remove redundant path.normalize call closes #167 --- HISTORY.md | 1 + index.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 741989eb..746e4a87 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,6 +6,7 @@ unreleased - deps: setprototypeof@1.1.0 - deps: statuses@'>= 1.3.1 < 2' * deps: statuses@~1.5.0 + * perf: remove redundant `path.normalize` call 0.16.2 / 2018-02-07 =================== diff --git a/index.js b/index.js index f297c4c5..e91191d7 100644 --- a/index.js +++ b/index.js @@ -546,7 +546,6 @@ SendStream.prototype.pipe = function pipe (res) { // join / normalize from optional root dir path = normalize(join(root, path)) - root = normalize(root + sep) } else { // ".." is malicious without "root" if (UP_PATH_REGEXP.test(path)) { From 30d4edd13134b7185e665fe76a1142b63e054eba Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 15 Aug 2018 23:40:01 -0400 Subject: [PATCH 228/334] deps: ms@2.1.1 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 746e4a87..db30465b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,9 @@ unreleased - deps: depd@~1.1.2 - deps: setprototypeof@1.1.0 - deps: statuses@'>= 1.3.1 < 2' + * deps: ms@2.1.1 + - Add `week`/`w` support + - Fix negative number handling * deps: statuses@~1.5.0 * perf: remove redundant `path.normalize` call diff --git a/package.json b/package.json index 69bb74c3..881f0472 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "fresh": "0.5.2", "http-errors": "~1.6.3", "mime": "1.4.1", - "ms": "2.0.0", + "ms": "2.1.1", "on-finished": "~2.3.0", "range-parser": "~1.2.0", "statuses": "~1.5.0" From 287bcafdae8a6fcd480d39cef2ff4e90b45b4713 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 15 Aug 2018 23:47:38 -0400 Subject: [PATCH 229/334] deps: http-errors@~1.7.0 --- HISTORY.md | 6 ++++-- package.json | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index db30465b..caef4dca 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,10 +1,12 @@ unreleased ========== - * deps: http-errors@~1.6.3 + * deps: http-errors@~1.7.0 + - Set constructor name when possible + - Use `toidentifier` module to make class names - deps: depd@~1.1.2 - deps: setprototypeof@1.1.0 - - deps: statuses@'>= 1.3.1 < 2' + - deps: statuses@'>= 1.5.0 < 2' * deps: ms@2.1.1 - Add `week`/`w` support - Fix negative number handling diff --git a/package.json b/package.json index 881f0472..1cf10418 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.3", + "http-errors": "~1.7.0", "mime": "1.4.1", "ms": "2.1.1", "on-finished": "~2.3.0", From 82a500cc8642bcc9213641d5729129fd67b1d0dd Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Sep 2018 21:40:02 -0400 Subject: [PATCH 230/334] build: Node.js@8.12 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f80172ba..efbdc15e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.14" - "7.10" - - "8.11" + - "8.12" - "9.11" - "10.8" sudo: false diff --git a/appveyor.yml b/appveyor.yml index dcdb3325..b539a47b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.14" - nodejs_version: "7.10" - - nodejs_version: "8.11" + - nodejs_version: "8.12" - nodejs_version: "9.11" - nodejs_version: "10.8" cache: From 65149cec80711c00252393fce3e273d31d595efa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Sep 2018 21:43:28 -0400 Subject: [PATCH 231/334] build: Node.js@10.11 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index efbdc15e..4ff23d61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.12" - "9.11" - - "10.8" + - "10.11" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index b539a47b..b4734314 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,7 @@ environment: - nodejs_version: "7.10" - nodejs_version: "8.12" - nodejs_version: "9.11" - - nodejs_version: "10.8" + - nodejs_version: "10.11" cache: - node_modules install: From 59e7e394c34380e652b2de7b892c6e509ade4007 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Sep 2018 21:50:22 -0400 Subject: [PATCH 232/334] build: coveralls@2.13.3 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4ff23d61..25358813 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,4 +34,4 @@ script: - "test -z $(npm -ps ls istanbul) || npm run-script test-ci" - "test -z $(npm -ps ls eslint ) || npm run-script lint" after_script: - - "test -e ./coverage/lcov.info && npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls" + - "test -e ./coverage/lcov.info && npm install coveralls@2.13.3 && cat ./coverage/lcov.info | coveralls" From 775e29df670f4ff5128e880b9252a4d94c108941 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 27 Sep 2018 21:59:11 -0400 Subject: [PATCH 233/334] tests: use strict equality --- test/send.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/send.js b/test/send.js index 51dd3a5d..0a20bc33 100644 --- a/test/send.js +++ b/test/send.js @@ -253,7 +253,7 @@ describe('send(file).pipe(res)', function () { function onHeaders (res, filePath) { assert.ok(filePath) - assert.equal(path.normalize(filePath), path.normalize(path.join(fixtures, 'nums'))) + assert.strictEqual(path.normalize(filePath), path.normalize(path.join(fixtures, 'nums'))) cb() } From a3b1a26462f72928fbacd4ad1ec536522ae91282 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 1 Oct 2018 22:06:39 -0400 Subject: [PATCH 234/334] build: restructure CI build steps --- .travis.yml | 55 +++++++++++++++++++++++++++++++++++++++------------- appveyor.yml | 42 ++++++++++++++++++++++++++++----------- 2 files changed, 73 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25358813..55af824a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,20 +18,49 @@ cache: directories: - node_modules before_install: - # Skip updating shrinkwrap / lock - - "npm config set shrinkwrap false" - + # Configure npm + - | + # Skip updating shrinkwrap / lock + npm config set shrinkwrap false # Setup Node.js version-specific dependencies - - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev $(grep -E '\"eslint\\S*\"' package.json | cut -d'\"' -f2)" - + - | + # istanbul for coverage + # - remove for Node.js < 0.10 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + npm rm --silent --save-dev istanbul + fi + - | + # eslint for linting + # - remove on Node.js < 4 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ + grep -E '^eslint(-|$)' | \ + xargs npm rm --save-dev + fi # Update Node.js modules - - "test ! -d node_modules || npm prune" - - "test ! -d node_modules || npm rebuild" + - | + # Prune and rebuild node_modules + if [[ -d node_modules ]]; then + npm prune + npm rebuild + fi script: - # Run test script, depending on istanbul install - - "test ! -z $(npm -ps ls istanbul) || npm test" - - "test -z $(npm -ps ls istanbul) || npm run-script test-ci" - - "test -z $(npm -ps ls eslint ) || npm run-script lint" + # Run test script + - | + if npm -ps ls istanbul | grep -q istanbul; then + npm run test-ci + else + npm test + fi + # Run linting + - | + if npm -ps ls eslint | grep -q eslint; then + npm run lint + fi after_script: - - "test -e ./coverage/lcov.info && npm install coveralls@2.13.3 && cat ./coverage/lcov.info | coveralls" + - | + # Upload coverage to coveralls + if [[ -f ./coverage/lcov.info ]]; then + npm install --save-dev coveralls@2.13.3 + coveralls < ./coverage/lcov.info + fi diff --git a/appveyor.yml b/appveyor.yml index b4734314..cd7cf66a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,21 +16,41 @@ environment: cache: - node_modules install: + # Install Node.js - ps: >- try { Install-Product node $env:nodejs_version -ErrorAction Stop } catch { Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) } - - npm config set shrinkwrap false - - if "%nodejs_version%" equ "0.8" npm rm --save-dev istanbul - - if "%nodejs_version%" equ "0.8" npm config set strict-ssl false - - for /f tokens^=2^ delims^=^" %%m in ('findstr /r /c:"eslint[^ ]" package.json') do call npm rm --save-dev %%m - - if exist node_modules npm prune - - if exist node_modules npm rebuild + # Configure npm + - ps: | + # Skip updating shrinkwrap / lock + npm config set shrinkwrap false + # Skip SSL validation on Node.js < 0.10 + if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { + npm config set strict-ssl false + } + # Remove all non-test dependencies + - ps: | + # Remove coverage dependency + npm rm --silent --save-dev istanbul + # Remove lint dependencies + cmd.exe /c "node -pe `"Object.keys(require('./package').devDependencies).join('\n')`"" | ` + sls "^eslint(-|$)" | ` + %{ npm rm --silent --save-dev $_ } + # Update Node.js modules + - ps: | + # Prune & rebuild node_modules + if (Test-Path -Path node_modules) { + npm prune + npm rebuild + } + # Install Node.js modules - npm install build: off test_script: - - node --version - - npm --version - - set npm_test_command=test - - for /f %%l in ('npm -ps ls istanbul') do set npm_test_command=test-ci - - npm run %npm_test_command% + # Output version data + - ps: | + node --version + npm --version + # Run test script + - npm test version: "{build}" From 0113d8e26088d34bd361b67414c46971cdf5c7ab Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 1 Oct 2018 22:18:02 -0400 Subject: [PATCH 235/334] build: mocha@5.2.0 --- .travis.yml | 9 +++++++++ appveyor.yml | 10 ++++++++++ package.json | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 55af824a..91f27c8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,15 @@ before_install: # Skip updating shrinkwrap / lock npm config set shrinkwrap false # Setup Node.js version-specific dependencies + - | + # mocha for testing + # - use 2.x for Node.js < 0.10 + # - use 3.x for Node.js < 6 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + npm install --save-dev mocha@2.5.3 + elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then + npm install --save-dev mocha@3.5.3 + fi - | # istanbul for coverage # - remove for Node.js < 0.10 diff --git a/appveyor.yml b/appveyor.yml index cd7cf66a..8a25d939 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -36,6 +36,16 @@ install: cmd.exe /c "node -pe `"Object.keys(require('./package').devDependencies).join('\n')`"" | ` sls "^eslint(-|$)" | ` %{ npm rm --silent --save-dev $_ } + # Setup Node.js version-specific dependencies + - ps: | + # mocha for testing + # - use 2.x for Node.js < 0.10 + # - use 3.x for Node.js < 6 + if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { + npm install --silent --save-dev mocha@2.5.3 + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { + npm install --silent --save-dev mocha@3.5.3 + } # Update Node.js modules - ps: | # Prune & rebuild node_modules diff --git a/package.json b/package.json index 1cf10418..817782f5 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "eslint-plugin-promise": "3.8.0", "eslint-plugin-standard": "3.1.0", "istanbul": "0.4.5", - "mocha": "2.5.3", + "mocha": "5.2.0", "supertest": "1.1.0" }, "files": [ From 3d21f2ed1c5a45710c570ae7f54ea8a59f5cfd29 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 1 Oct 2018 22:37:11 -0400 Subject: [PATCH 236/334] tests: add extension to nums file --- test/fixtures/no_ext | 1 + test/fixtures/{nums => nums.txt} | 0 test/send.js | 98 ++++++++++++++++---------------- 3 files changed, 51 insertions(+), 48 deletions(-) create mode 100644 test/fixtures/no_ext rename test/fixtures/{nums => nums.txt} (100%) diff --git a/test/fixtures/no_ext b/test/fixtures/no_ext new file mode 100644 index 00000000..f6ea0495 --- /dev/null +++ b/test/fixtures/no_ext @@ -0,0 +1 @@ +foobar \ No newline at end of file diff --git a/test/fixtures/nums b/test/fixtures/nums.txt similarity index 100% rename from test/fixtures/nums rename to test/fixtures/nums.txt diff --git a/test/send.js b/test/send.js index 0a20bc33..26be1ed9 100644 --- a/test/send.js +++ b/test/send.js @@ -78,7 +78,7 @@ describe('send(file).pipe(res)', function () { .pipe(res) }) request(app) - .get('/nums') + .get('/name.txt') .expect(200, '0 - Can\'t set headers after they are sent.', done) }) @@ -138,7 +138,7 @@ describe('send(file).pipe(res)', function () { send(req, req.url, {root: fixtures}).pipe(res) }) request(app) - .get('/nums') + .get('/name.txt') .expect('Content-Type', 'application/x-custom', done) }) @@ -200,8 +200,8 @@ describe('send(file).pipe(res)', function () { }) request(server) - .get('/nums') - .expect(200, '123456789', cb) + .get('/name.txt') + .expect(200, 'tobi', cb) }) it('should not fire on 404', function (done) { @@ -253,13 +253,13 @@ describe('send(file).pipe(res)', function () { function onHeaders (res, filePath) { assert.ok(filePath) - assert.strictEqual(path.normalize(filePath), path.normalize(path.join(fixtures, 'nums'))) + assert.strictEqual(path.normalize(filePath), path.normalize(path.join(fixtures, 'name.txt'))) cb() } request(server) - .get('/nums') - .expect(200, '123456789', cb) + .get('/name.txt') + .expect(200, 'tobi', cb) }) it('should provide stat', function (done) { @@ -278,8 +278,8 @@ describe('send(file).pipe(res)', function () { } request(server) - .get('/nums') - .expect(200, '123456789', cb) + .get('/name.txt') + .expect(200, 'tobi', cb) }) it('should allow altering headers', function (done) { @@ -297,12 +297,14 @@ describe('send(file).pipe(res)', function () { } request(server) - .get('/nums') + .get('/name.txt') + .expect(200) .expect('Cache-Control', 'no-cache') .expect('Content-Type', 'text/x-custom') .expect('ETag', 'W/"everything"') .expect('X-Created', dateRegExp) - .expect(200, '123456789', done) + .expect('tobi') + .end(done) }) }) @@ -557,28 +559,28 @@ describe('send(file).pipe(res)', function () { describe('with Range request', function () { it('should support byte ranges', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=0-4') .expect(206, '12345', done) }) it('should ignore non-byte ranges', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'items=0-4') .expect(200, '123456789', done) }) it('should be inclusive', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=0-0') .expect(206, '1', done) }) it('should set Content-Range', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=2-5') .expect('Content-Range', 'bytes 2-5/9') .expect(206, done) @@ -586,28 +588,28 @@ describe('send(file).pipe(res)', function () { it('should support -n', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=-3') .expect(206, '789', done) }) it('should support n-', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=3-') .expect(206, '456789', done) }) it('should respond with 206 "Partial Content"', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=0-4') .expect(206, done) }) it('should set Content-Length to the # of octets transferred', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=2-3') .expect('Content-Length', '2') .expect(206, '34', done) @@ -616,7 +618,7 @@ describe('send(file).pipe(res)', function () { describe('when last-byte-pos of the range is greater the length', function () { it('is taken to be equal to one less than the length', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=2-50') .expect('Content-Range', 'bytes 2-8/9') .expect(206, done) @@ -624,7 +626,7 @@ describe('send(file).pipe(res)', function () { it('should adapt the Content-Length accordingly', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=2-50') .expect('Content-Length', '7') .expect(206, done) @@ -634,7 +636,7 @@ describe('send(file).pipe(res)', function () { describe('when the first- byte-pos of the range is greater length', function () { it('should respond with 416', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=9-50') .expect('Content-Range', 'bytes */9') .expect(416, done) @@ -644,7 +646,7 @@ describe('send(file).pipe(res)', function () { describe('when syntactically invalid', function () { it('should respond with 200 and the entire contents', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'asdf') .expect(200, '123456789', done) }) @@ -653,7 +655,7 @@ describe('send(file).pipe(res)', function () { describe('when multiple ranges', function () { it('should respond with 200 and the entire contents', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=1-1,3-') .expect(shouldNotHaveHeader('Content-Range')) .expect(200, '123456789', done) @@ -661,7 +663,7 @@ describe('send(file).pipe(res)', function () { it('should respond with 206 is all ranges can be combined', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=1-2,3-5') .expect('Content-Range', 'bytes 1-5/9') .expect(206, '23456', done) @@ -671,13 +673,13 @@ describe('send(file).pipe(res)', function () { describe('when if-range present', function () { it('should respond with parts when etag unchanged', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .expect(200, function (err, res) { if (err) return done(err) var etag = res.headers.etag request(app) - .get('/nums') + .get('/nums.txt') .set('If-Range', etag) .set('Range', 'bytes=0-0') .expect(206, '1', done) @@ -686,13 +688,13 @@ describe('send(file).pipe(res)', function () { it('should respond with 200 when etag changed', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .expect(200, function (err, res) { if (err) return done(err) var etag = res.headers.etag.replace(/"(.)/, '"0$1') request(app) - .get('/nums') + .get('/nums.txt') .set('If-Range', etag) .set('Range', 'bytes=0-0') .expect(200, '123456789', done) @@ -701,13 +703,13 @@ describe('send(file).pipe(res)', function () { it('should respond with parts when modified unchanged', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .expect(200, function (err, res) { if (err) return done(err) var modified = res.headers['last-modified'] request(app) - .get('/nums') + .get('/nums.txt') .set('If-Range', modified) .set('Range', 'bytes=0-0') .expect(206, '1', done) @@ -716,13 +718,13 @@ describe('send(file).pipe(res)', function () { it('should respond with 200 when modified changed', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .expect(200, function (err, res) { if (err) return done(err) var modified = Date.parse(res.headers['last-modified']) - 20000 request(app) - .get('/nums') + .get('/nums.txt') .set('If-Range', new Date(modified).toUTCString()) .set('Range', 'bytes=0-0') .expect(200, '123456789', done) @@ -731,7 +733,7 @@ describe('send(file).pipe(res)', function () { it('should respond with 200 when invalid value', function (done) { request(app) - .get('/nums') + .get('/nums.txt') .set('If-Range', 'foo') .set('Range', 'bytes=0-0') .expect(200, '123456789', done) @@ -742,26 +744,26 @@ describe('send(file).pipe(res)', function () { describe('when "options" is specified', function () { it('should support start/end', function (done) { request(createServer({root: fixtures, start: 3, end: 5})) - .get('/nums') + .get('/nums.txt') .expect(200, '456', done) }) it('should adjust too large end', function (done) { request(createServer({root: fixtures, start: 3, end: 90})) - .get('/nums') + .get('/nums.txt') .expect(200, '456789', done) }) it('should support start/end with Range request', function (done) { request(createServer({root: fixtures, start: 0, end: 2})) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=-2') .expect(206, '23', done) }) it('should support start/end with unsatisfiable Range request', function (done) { request(createServer({root: fixtures, start: 0, end: 2})) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=5-9') .expect('Content-Range', 'bytes */3') .expect(416, done) @@ -777,7 +779,7 @@ describe('send(file).pipe(res)', function () { }) request(app) - .get('/nums') + .get('/name.txt') .expect(shouldNotHaveHeader('ETag')) .expect(200, done) }) @@ -918,14 +920,14 @@ describe('send(file, options)', function () { describe('acceptRanges', function () { it('should support disabling accept-ranges', function (done) { request(createServer({acceptRanges: false, root: fixtures})) - .get('/nums') + .get('/nums.txt') .expect(shouldNotHaveHeader('Accept-Ranges')) .expect(200, done) }) it('should ignore requested range', function (done) { request(createServer({acceptRanges: false, root: fixtures})) - .get('/nums') + .get('/nums.txt') .set('Range', 'bytes=0-2') .expect(shouldNotHaveHeader('Accept-Ranges')) .expect(shouldNotHaveHeader('Content-Range')) @@ -936,14 +938,14 @@ describe('send(file, options)', function () { describe('cacheControl', function () { it('should support disabling cache-control', function (done) { request(createServer({cacheControl: false, root: fixtures})) - .get('/nums') + .get('/name.txt') .expect(shouldNotHaveHeader('Cache-Control')) .expect(200, done) }) it('should ignore maxAge option', function (done) { request(createServer({cacheControl: false, maxAge: 1000, root: fixtures})) - .get('/nums') + .get('/name.txt') .expect(shouldNotHaveHeader('Cache-Control')) .expect(200, done) }) @@ -952,7 +954,7 @@ describe('send(file, options)', function () { describe('etag', function () { it('should support disabling etags', function (done) { request(createServer({etag: false, root: fixtures})) - .get('/nums') + .get('/name.txt') .expect(shouldNotHaveHeader('ETag')) .expect(200, done) }) @@ -1017,7 +1019,7 @@ describe('send(file, options)', function () { describe('lastModified', function () { it('should support disabling last-modified', function (done) { request(createServer({lastModified: false, root: fixtures})) - .get('/nums') + .get('/name.txt') .expect(shouldNotHaveHeader('Last-Modified')) .expect(200, done) }) @@ -1046,7 +1048,7 @@ describe('send(file, options)', function () { it('should reject bad value', function (done) { request(createServer({dotfiles: 'bogus'})) - .get('/nums') + .get('/name.txt') .expect(500, /dotfiles/, done) }) @@ -1434,7 +1436,7 @@ describe('send.mime', function () { send.mime.default_type = 'text/plain' request(createServer({root: fixtures})) - .get('/nums') + .get('/no_ext') .expect('Content-Type', 'text/plain; charset=UTF-8') .expect(200, done) }) @@ -1443,7 +1445,7 @@ describe('send.mime', function () { send.mime.default_type = undefined request(createServer({root: fixtures})) - .get('/nums') + .get('/no_ext') .expect(shouldNotHaveHeader('Content-Type')) .expect(200, done) }) From fe8837c4698610b26ad5e86adee3e6666d7cda45 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 1 Oct 2018 22:42:20 -0400 Subject: [PATCH 237/334] tests: add extension to .hidden file --- test/fixtures/.hidden | 1 - test/fixtures/.hidden.txt | 1 + test/send.js | 20 ++++++++++---------- 3 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 test/fixtures/.hidden create mode 100644 test/fixtures/.hidden.txt diff --git a/test/fixtures/.hidden b/test/fixtures/.hidden deleted file mode 100644 index d97c5ead..00000000 --- a/test/fixtures/.hidden +++ /dev/null @@ -1 +0,0 @@ -secret diff --git a/test/fixtures/.hidden.txt b/test/fixtures/.hidden.txt new file mode 100644 index 00000000..536aca34 --- /dev/null +++ b/test/fixtures/.hidden.txt @@ -0,0 +1 @@ +secret \ No newline at end of file diff --git a/test/send.js b/test/send.js index 26be1ed9..3ee9d3c8 100644 --- a/test/send.js +++ b/test/send.js @@ -808,8 +808,8 @@ describe('send(file).pipe(res)', function () { }) request(app) - .get('/.hidden') - .expect(200, /secret/, done) + .get('/.hidden.txt') + .expect(200, 'secret', done) }) }) @@ -1036,7 +1036,7 @@ describe('send(file, options)', function () { describe('dotfiles', function () { it('should default to "ignore"', function (done) { request(createServer({root: fixtures})) - .get('/.hidden') + .get('/.hidden.txt') .expect(404, done) }) @@ -1055,8 +1055,8 @@ describe('send(file, options)', function () { describe('when "allow"', function (done) { it('should send dotfile', function (done) { request(createServer({dotfiles: 'allow', root: fixtures})) - .get('/.hidden') - .expect(200, /secret/, done) + .get('/.hidden.txt') + .expect(200, 'secret', done) }) it('should send within dotfile directory', function (done) { @@ -1075,7 +1075,7 @@ describe('send(file, options)', function () { describe('when "deny"', function (done) { it('should 403 for dotfile', function (done) { request(createServer({dotfiles: 'deny', root: fixtures})) - .get('/.hidden') + .get('/.hidden.txt') .expect(403, done) }) @@ -1141,7 +1141,7 @@ describe('send(file, options)', function () { describe('when "ignore"', function (done) { it('should 404 for dotfile', function (done) { request(createServer({dotfiles: 'ignore', root: fixtures})) - .get('/.hidden') + .get('/.hidden.txt') .expect(404, done) }) @@ -1196,14 +1196,14 @@ describe('send(file, options)', function () { describe('hidden', function () { it('should default to false', function (done) { request(app) - .get('/.hidden') + .get('/.hidden.txt') .expect(404, 'Not Found', done) }) it('should default support sending hidden files', function (done) { request(createServer({hidden: true, root: fixtures})) - .get('/.hidden') - .expect(200, /secret/, done) + .get('/.hidden.txt') + .expect(200, 'secret', done) }) }) From 31c5277ce1e76d02ee68a593ee23248800eb6ca7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 2 Oct 2018 00:40:02 -0400 Subject: [PATCH 238/334] build: supertest@3.3.0 --- .travis.yml | 9 +++++++++ appveyor.yml | 9 +++++++++ package.json | 2 +- test/send.js | 10 +++++++++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 91f27c8b..4b224701 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,15 @@ before_install: elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then npm install --save-dev mocha@3.5.3 fi + - | + # supertest for http calls + # - use 1.1.0 for Node.js < 0.10 + # - use 2.0.0 for Node.js < 4 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then + npm install --save-dev supertest@1.1.0 + elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + npm install --save-dev supertest@2.0.0 + fi - | # istanbul for coverage # - remove for Node.js < 0.10 diff --git a/appveyor.yml b/appveyor.yml index 8a25d939..b6f83286 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -46,6 +46,15 @@ install: } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { npm install --silent --save-dev mocha@3.5.3 } + - ps: | + # supertest for http calls + # - use 1.1.0 for Node.js < 0.10 + # - use 2.0.0 for Node.js < 4 + if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { + npm install --silent --save-dev supertest@1.1.0 + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 4) { + npm install --silent --save-dev supertest@2.0.0 + } # Update Node.js modules - ps: | # Prune & rebuild node_modules diff --git a/package.json b/package.json index 817782f5..58f89b0a 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "eslint-plugin-standard": "3.1.0", "istanbul": "0.4.5", "mocha": "5.2.0", - "supertest": "1.1.0" + "supertest": "3.3.0" }, "files": [ "HISTORY.md", diff --git a/test/send.js b/test/send.js index 3ee9d3c8..5a3945b1 100644 --- a/test/send.js +++ b/test/send.js @@ -85,8 +85,10 @@ describe('send(file).pipe(res)', function () { it('should support HEAD', function (done) { request(app) .head('/name.txt') + .expect(200) .expect('Content-Length', '4') - .expect(200, '', done) + .expect(shouldNotHaveBody()) + .end(done) }) it('should add an ETag header field', function (done) { @@ -1464,6 +1466,12 @@ function createServer (opts, fn) { }) } +function shouldNotHaveBody () { + return function (res) { + assert.ok(res.text === '' || res.text === undefined) + } +} + function shouldNotHaveHeader (header) { return function (res) { assert.ok(!(header.toLowerCase() in res.headers), 'should not have header ' + header) From f60b775d4736635046ef25708b9493d215f05ff0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 21 Oct 2018 23:40:02 -0400 Subject: [PATCH 239/334] lint: apply standard 12 style --- .travis.yml | 4 +- index.js | 2 +- package.json | 12 ++-- test/send.js | 200 +++++++++++++++++++++++++-------------------------- 4 files changed, 109 insertions(+), 109 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4b224701..015d07ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,8 +49,8 @@ before_install: fi - | # eslint for linting - # - remove on Node.js < 4 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then + # - remove on Node.js < 6 + if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ grep -E '^eslint(-|$)' | \ xargs npm rm --save-dev diff --git a/index.js b/index.js index e91191d7..0b7a39db 100644 --- a/index.js +++ b/index.js @@ -668,7 +668,7 @@ SendStream.prototype.send = function send (path, stat) { // 416 Requested Range Not Satisfiable return this.error(416, { - headers: {'Content-Range': res.getHeader('Content-Range')} + headers: { 'Content-Range': res.getHeader('Content-Range') } }) } diff --git a/package.json b/package.json index 58f89b0a..8cfa40c0 100644 --- a/package.json +++ b/package.json @@ -32,13 +32,13 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "4.19.1", - "eslint-config-standard": "11.0.0", - "eslint-plugin-import": "2.13.0", + "eslint": "5.7.0", + "eslint-config-standard": "12.0.0", + "eslint-plugin-import": "2.14.0", "eslint-plugin-markdown": "1.0.0-beta.6", - "eslint-plugin-node": "6.0.1", - "eslint-plugin-promise": "3.8.0", - "eslint-plugin-standard": "3.1.0", + "eslint-plugin-node": "7.0.1", + "eslint-plugin-promise": "4.0.1", + "eslint-plugin-standard": "4.0.0", "istanbul": "0.4.5", "mocha": "5.2.0", "supertest": "3.3.0" diff --git a/test/send.js b/test/send.js index 5a3945b1..7586fb4d 100644 --- a/test/send.js +++ b/test/send.js @@ -19,7 +19,7 @@ var app = http.createServer(function (req, res) { res.end(http.STATUS_CODES[err.status]) } - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('error', error) .pipe(res) }) @@ -73,7 +73,7 @@ describe('send(file).pipe(res)', function () { it('should handle headers already sent error', function (done) { var app = http.createServer(function (req, res) { res.write('0') - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('error', function (err) { res.end(' - ' + err.message) }) .pipe(res) }) @@ -124,7 +124,7 @@ describe('send(file).pipe(res)', function () { it('should emit ENOENT if the file does not exist', function (done) { var app = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('error', function (err) { res.end(err.statusCode + ' ' + err.code) }) .pipe(res) }) @@ -137,7 +137,7 @@ describe('send(file).pipe(res)', function () { it('should not override content-type', function (done) { var app = http.createServer(function (req, res) { res.setHeader('Content-Type', 'application/x-custom') - send(req, req.url, {root: fixtures}).pipe(res) + send(req, req.url, { root: fixtures }).pipe(res) }) request(app) .get('/name.txt') @@ -159,7 +159,7 @@ describe('send(file).pipe(res)', function () { it('should 404 if file disappears after stat, before open', function (done) { var app = http.createServer(function (req, res) { - send(req, req.url, {root: 'test/fixtures'}) + send(req, req.url, { root: 'test/fixtures' }) .on('file', function () { // simulate file ENOENT after on open, after stat var fn = this.send @@ -177,7 +177,7 @@ describe('send(file).pipe(res)', function () { it('should 500 on file stream error', function (done) { var app = http.createServer(function (req, res) { - send(req, req.url, {root: 'test/fixtures'}) + send(req, req.url, { root: 'test/fixtures' }) .on('stream', function (stream) { // simulate file error stream.on('open', function () { @@ -196,7 +196,7 @@ describe('send(file).pipe(res)', function () { it('should fire when sending file', function (done) { var cb = after(2, done) var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('headers', function () { cb() }) .pipe(res) }) @@ -209,7 +209,7 @@ describe('send(file).pipe(res)', function () { it('should not fire on 404', function (done) { var cb = after(1, done) var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('headers', function () { cb() }) .pipe(res) }) @@ -222,7 +222,7 @@ describe('send(file).pipe(res)', function () { it('should fire on index', function (done) { var cb = after(2, done) var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('headers', function () { cb() }) .pipe(res) }) @@ -235,7 +235,7 @@ describe('send(file).pipe(res)', function () { it('should not fire on redirect', function (done) { var cb = after(1, done) var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('headers', function () { cb() }) .pipe(res) }) @@ -248,7 +248,7 @@ describe('send(file).pipe(res)', function () { it('should provide path', function (done) { var cb = after(2, done) var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('headers', onHeaders) .pipe(res) }) @@ -267,7 +267,7 @@ describe('send(file).pipe(res)', function () { it('should provide stat', function (done) { var cb = after(2, done) var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('headers', onHeaders) .pipe(res) }) @@ -286,7 +286,7 @@ describe('send(file).pipe(res)', function () { it('should allow altering headers', function (done) { var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('headers', onHeaders) .pipe(res) }) @@ -313,7 +313,7 @@ describe('send(file).pipe(res)', function () { describe('when "directory" listeners are present', function () { it('should be called when sending directory', function (done) { var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('directory', onDirectory) .pipe(res) }) @@ -330,7 +330,7 @@ describe('send(file).pipe(res)', function () { it('should be called with path', function (done) { var server = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures}) + send(req, req.url, { root: fixtures }) .on('directory', onDirectory) .pipe(res) }) @@ -347,14 +347,14 @@ describe('send(file).pipe(res)', function () { describe('when no "directory" listeners are present', function () { it('should redirect directories to trailing slash', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/pets') .expect('Location', '/pets/') .expect(301, done) }) it('should respond with an HTML redirect', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/pets') .expect('Location', '/pets/') .expect('Content-Type', /html/) @@ -362,7 +362,7 @@ describe('send(file).pipe(res)', function () { }) it('should respond with default Content-Security-Policy', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/pets') .expect('Location', '/pets/') .expect('Content-Security-Policy', "default-src 'self'") @@ -370,7 +370,7 @@ describe('send(file).pipe(res)', function () { }) it('should not redirect to protocol-relative locations', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('//pets') .expect('Location', '/pets/') .expect(301, done) @@ -378,7 +378,7 @@ describe('send(file).pipe(res)', function () { it('should respond with an HTML redirect', function (done) { var app = http.createServer(function (req, res) { - send(req, req.url.replace('/snow', '/snow ☃'), {root: 'test/fixtures'}) + send(req, req.url.replace('/snow', '/snow ☃'), { root: 'test/fixtures' }) .pipe(res) }) @@ -392,20 +392,20 @@ describe('send(file).pipe(res)', function () { describe('when no "error" listeners are present', function () { it('should respond to errors directly', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/foobar') .expect(404, />Not Foundtobi

', done) }) it('should 404 if nothing found', function (done) { - request(createServer({extensions: ['htm', 'html', 'txt'], root: fixtures})) + request(createServer({ extensions: ['htm', 'html', 'txt'], root: fixtures })) .get('/bob') .expect(404, done) }) it('should skip directories', function (done) { - request(createServer({extensions: ['file', 'dir'], root: fixtures})) + request(createServer({ extensions: ['file', 'dir'], root: fixtures })) .get('/name') .expect(404, done) }) it('should not search if file has extension', function (done) { - request(createServer({extensions: 'html', root: fixtures})) + request(createServer({ extensions: 'html', root: fixtures })) .get('/thing.html') .expect(404, done) }) @@ -1020,7 +1020,7 @@ describe('send(file, options)', function () { describe('lastModified', function () { it('should support disabling last-modified', function (done) { - request(createServer({lastModified: false, root: fixtures})) + request(createServer({ lastModified: false, root: fixtures })) .get('/name.txt') .expect(shouldNotHaveHeader('Last-Modified')) .expect(200, done) @@ -1029,7 +1029,7 @@ describe('send(file, options)', function () { describe('from', function () { it('should set with deprecated from', function (done) { - request(createServer({from: fixtures})) + request(createServer({ from: fixtures })) .get('/pets/../name.txt') .expect(200, 'tobi', done) }) @@ -1037,38 +1037,38 @@ describe('send(file, options)', function () { describe('dotfiles', function () { it('should default to "ignore"', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/.hidden.txt') .expect(404, done) }) it('should allow file within dotfile directory for back-compat', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/.mine/name.txt') .expect(200, /tobi/, done) }) it('should reject bad value', function (done) { - request(createServer({dotfiles: 'bogus'})) + request(createServer({ dotfiles: 'bogus' })) .get('/name.txt') .expect(500, /dotfiles/, done) }) describe('when "allow"', function (done) { it('should send dotfile', function (done) { - request(createServer({dotfiles: 'allow', root: fixtures})) + request(createServer({ dotfiles: 'allow', root: fixtures })) .get('/.hidden.txt') .expect(200, 'secret', done) }) it('should send within dotfile directory', function (done) { - request(createServer({dotfiles: 'allow', root: fixtures})) + request(createServer({ dotfiles: 'allow', root: fixtures })) .get('/.mine/name.txt') .expect(200, /tobi/, done) }) it('should 404 for non-existent dotfile', function (done) { - request(createServer({dotfiles: 'allow', root: fixtures})) + request(createServer({ dotfiles: 'allow', root: fixtures })) .get('/.nothere') .expect(404, done) }) @@ -1076,62 +1076,62 @@ describe('send(file, options)', function () { describe('when "deny"', function (done) { it('should 403 for dotfile', function (done) { - request(createServer({dotfiles: 'deny', root: fixtures})) + request(createServer({ dotfiles: 'deny', root: fixtures })) .get('/.hidden.txt') .expect(403, done) }) it('should 403 for dotfile directory', function (done) { - request(createServer({dotfiles: 'deny', root: fixtures})) + request(createServer({ dotfiles: 'deny', root: fixtures })) .get('/.mine') .expect(403, done) }) it('should 403 for dotfile directory with trailing slash', function (done) { - request(createServer({dotfiles: 'deny', root: fixtures})) + request(createServer({ dotfiles: 'deny', root: fixtures })) .get('/.mine/') .expect(403, done) }) it('should 403 for file within dotfile directory', function (done) { - request(createServer({dotfiles: 'deny', root: fixtures})) + request(createServer({ dotfiles: 'deny', root: fixtures })) .get('/.mine/name.txt') .expect(403, done) }) it('should 403 for non-existent dotfile', function (done) { - request(createServer({dotfiles: 'deny', root: fixtures})) + request(createServer({ dotfiles: 'deny', root: fixtures })) .get('/.nothere') .expect(403, done) }) it('should 403 for non-existent dotfile directory', function (done) { - request(createServer({dotfiles: 'deny', root: fixtures})) + request(createServer({ dotfiles: 'deny', root: fixtures })) .get('/.what/name.txt') .expect(403, done) }) it('should 403 for dotfile in directory', function (done) { - request(createServer({dotfiles: 'deny', root: fixtures})) + request(createServer({ dotfiles: 'deny', root: fixtures })) .get('/pets/.hidden') .expect(403, done) }) it('should 403 for dotfile in dotfile directory', function (done) { - request(createServer({dotfiles: 'deny', root: fixtures})) + request(createServer({ dotfiles: 'deny', root: fixtures })) .get('/.mine/.hidden') .expect(403, done) }) it('should send files in root dotfile directory', function (done) { - request(createServer({dotfiles: 'deny', root: path.join(fixtures, '.mine')})) + request(createServer({ dotfiles: 'deny', root: path.join(fixtures, '.mine') })) .get('/name.txt') .expect(200, /tobi/, done) }) it('should 403 for dotfile without root', function (done) { var server = http.createServer(function onRequest (req, res) { - send(req, fixtures + '/.mine' + req.url, {dotfiles: 'deny'}).pipe(res) + send(req, fixtures + '/.mine' + req.url, { dotfiles: 'deny' }).pipe(res) }) request(server) @@ -1142,50 +1142,50 @@ describe('send(file, options)', function () { describe('when "ignore"', function (done) { it('should 404 for dotfile', function (done) { - request(createServer({dotfiles: 'ignore', root: fixtures})) + request(createServer({ dotfiles: 'ignore', root: fixtures })) .get('/.hidden.txt') .expect(404, done) }) it('should 404 for dotfile directory', function (done) { - request(createServer({dotfiles: 'ignore', root: fixtures})) + request(createServer({ dotfiles: 'ignore', root: fixtures })) .get('/.mine') .expect(404, done) }) it('should 404 for dotfile directory with trailing slash', function (done) { - request(createServer({dotfiles: 'ignore', root: fixtures})) + request(createServer({ dotfiles: 'ignore', root: fixtures })) .get('/.mine/') .expect(404, done) }) it('should 404 for file within dotfile directory', function (done) { - request(createServer({dotfiles: 'ignore', root: fixtures})) + request(createServer({ dotfiles: 'ignore', root: fixtures })) .get('/.mine/name.txt') .expect(404, done) }) it('should 404 for non-existent dotfile', function (done) { - request(createServer({dotfiles: 'ignore', root: fixtures})) + request(createServer({ dotfiles: 'ignore', root: fixtures })) .get('/.nothere') .expect(404, done) }) it('should 404 for non-existent dotfile directory', function (done) { - request(createServer({dotfiles: 'ignore', root: fixtures})) + request(createServer({ dotfiles: 'ignore', root: fixtures })) .get('/.what/name.txt') .expect(404, done) }) it('should send files in root dotfile directory', function (done) { - request(createServer({dotfiles: 'ignore', root: path.join(fixtures, '.mine')})) + request(createServer({ dotfiles: 'ignore', root: path.join(fixtures, '.mine') })) .get('/name.txt') .expect(200, /tobi/, done) }) it('should 404 for dotfile without root', function (done) { var server = http.createServer(function onRequest (req, res) { - send(req, fixtures + '/.mine' + req.url, {dotfiles: 'ignore'}).pipe(res) + send(req, fixtures + '/.mine' + req.url, { dotfiles: 'ignore' }).pipe(res) }) request(server) @@ -1203,7 +1203,7 @@ describe('send(file, options)', function () { }) it('should default support sending hidden files', function (done) { - request(createServer({hidden: true, root: fixtures})) + request(createServer({ hidden: true, root: fixtures })) .get('/.hidden.txt') .expect(200, 'secret', done) }) @@ -1211,13 +1211,13 @@ describe('send(file, options)', function () { describe('immutable', function () { it('should default to false', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/name.txt') .expect('Cache-Control', 'public, max-age=0', done) }) it('should set immutable directive in Cache-Control', function (done) { - request(createServer({immutable: true, maxAge: '1h', root: fixtures})) + request(createServer({ immutable: true, maxAge: '1h', root: fixtures })) .get('/name.txt') .expect('Cache-Control', 'public, max-age=3600, immutable', done) }) @@ -1225,25 +1225,25 @@ describe('send(file, options)', function () { describe('maxAge', function () { it('should default to 0', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/name.txt') .expect('Cache-Control', 'public, max-age=0', done) }) it('should floor to integer', function (done) { - request(createServer({maxAge: 123956, root: fixtures})) + request(createServer({ maxAge: 123956, root: fixtures })) .get('/name.txt') .expect('Cache-Control', 'public, max-age=123', done) }) it('should accept string', function (done) { - request(createServer({maxAge: '30d', root: fixtures})) + request(createServer({ maxAge: '30d', root: fixtures })) .get('/name.txt') .expect('Cache-Control', 'public, max-age=2592000', done) }) it('should max at 1 year', function (done) { - request(createServer({maxAge: '2y', root: fixtures})) + request(createServer({ maxAge: '2y', root: fixtures })) .get('/name.txt') .expect('Cache-Control', 'public, max-age=31536000', done) }) @@ -1251,55 +1251,55 @@ describe('send(file, options)', function () { describe('index', function () { it('should reject numbers', function (done) { - request(createServer({root: fixtures, index: 42})) + request(createServer({ root: fixtures, index: 42 })) .get('/pets/') .expect(500, /TypeError: index option/, done) }) it('should reject true', function (done) { - request(createServer({root: fixtures, index: true})) + request(createServer({ root: fixtures, index: true })) .get('/pets/') .expect(500, /TypeError: index option/, done) }) it('should default to index.html', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/pets/') .expect(fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) }) it('should be configurable', function (done) { - request(createServer({root: fixtures, index: 'tobi.html'})) + request(createServer({ root: fixtures, index: 'tobi.html' })) .get('/') .expect(200, '

tobi

', done) }) it('should support disabling', function (done) { - request(createServer({root: fixtures, index: false})) + request(createServer({ root: fixtures, index: false })) .get('/pets/') .expect(403, done) }) it('should support fallbacks', function (done) { - request(createServer({root: fixtures, index: ['default.htm', 'index.html']})) + request(createServer({ root: fixtures, index: ['default.htm', 'index.html'] })) .get('/pets/') .expect(200, fs.readFileSync(path.join(fixtures, 'pets', 'index.html'), 'utf8'), done) }) it('should 404 if no index file found (file)', function (done) { - request(createServer({root: fixtures, index: 'default.htm'})) + request(createServer({ root: fixtures, index: 'default.htm' })) .get('/pets/') .expect(404, done) }) it('should 404 if no index file found (dir)', function (done) { - request(createServer({root: fixtures, index: 'pets'})) + request(createServer({ root: fixtures, index: 'pets' })) .get('/') .expect(404, done) }) it('should not follow directories', function (done) { - request(createServer({root: fixtures, index: ['pets', 'name.txt']})) + request(createServer({ root: fixtures, index: ['pets', 'name.txt'] })) .get('/') .expect(200, 'tobi', done) }) @@ -1307,7 +1307,7 @@ describe('send(file, options)', function () { it('should work without root', function (done) { var server = http.createServer(function (req, res) { var p = path.join(fixtures, 'pets').replace(/\\/g, '/') + '/' - send(req, p, {index: ['index.html']}) + send(req, p, { index: ['index.html'] }) .pipe(res) }) @@ -1320,14 +1320,14 @@ describe('send(file, options)', function () { describe('root', function () { describe('when given', function () { it('should join root', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/pets/../name.txt') .expect(200, 'tobi', done) }) it('should work with trailing slash', function (done) { var app = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures + '/'}) + send(req, req.url, { root: fixtures + '/' }) .pipe(res) }) @@ -1338,7 +1338,7 @@ describe('send(file, options)', function () { it('should work with empty path', function (done) { var app = http.createServer(function (req, res) { - send(req, '', {root: fixtures}) + send(req, '', { root: fixtures }) .pipe(res) }) @@ -1355,7 +1355,7 @@ describe('send(file, options)', function () { // it('should try as file with empty path', function (done) { var app = http.createServer(function (req, res) { - send(req, '', {root: path.join(fixtures, 'name.txt')}) + send(req, '', { root: path.join(fixtures, 'name.txt') }) .pipe(res) }) @@ -1365,14 +1365,14 @@ describe('send(file, options)', function () { }) it('should restrict paths to within root', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/pets/../../send.js') .expect(403, done) }) it('should allow .. in root', function (done) { var app = http.createServer(function (req, res) { - send(req, req.url, {root: fixtures + '/../fixtures'}) + send(req, req.url, { root: fixtures + '/../fixtures' }) .pipe(res) }) @@ -1382,13 +1382,13 @@ describe('send(file, options)', function () { }) it('should not allow root transversal', function (done) { - request(createServer({root: path.join(fixtures, 'name.d')})) + request(createServer({ root: path.join(fixtures, 'name.d') })) .get('/../name.dir/name.txt') .expect(403, done) }) it('should not allow root path disclosure', function (done) { - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/pets/../../fixtures/name.txt') .expect(403, done) }) @@ -1437,7 +1437,7 @@ describe('send.mime', function () { it('should change the default type', function (done) { send.mime.default_type = 'text/plain' - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/no_ext') .expect('Content-Type', 'text/plain; charset=UTF-8') .expect(200, done) @@ -1446,7 +1446,7 @@ describe('send.mime', function () { it('should not add Content-Type for undefined default', function (done) { send.mime.default_type = undefined - request(createServer({root: fixtures})) + request(createServer({ root: fixtures })) .get('/no_ext') .expect(shouldNotHaveHeader('Content-Type')) .expect(200, done) From c6e5ca11abd67617bf78391503fe55e188e8469f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 23 Oct 2018 16:09:27 -0400 Subject: [PATCH 240/334] deps: http-errors@~1.7.1 --- HISTORY.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index caef4dca..e8b42c59 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,7 @@ unreleased ========== - * deps: http-errors@~1.7.0 + * deps: http-errors@~1.7.1 - Set constructor name when possible - Use `toidentifier` module to make class names - deps: depd@~1.1.2 diff --git a/package.json b/package.json index 8cfa40c0..ac58fb8f 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.0", + "http-errors": "~1.7.1", "mime": "1.4.1", "ms": "2.1.1", "on-finished": "~2.3.0", From 1a6d97315286dd8ac3683c6086d7f426c7716712 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 23 Oct 2018 16:20:39 -0400 Subject: [PATCH 241/334] docs: switch badges to badgen --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index de1629e1..179e8c32 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # send -[![NPM Version][npm-image]][npm-url] -[![NPM Downloads][downloads-image]][downloads-url] +[![NPM Version][npm-version-image]][npm-url] +[![NPM Downloads][npm-downloads-image]][npm-url] [![Linux Build][travis-image]][travis-url] [![Windows Build][appveyor-image]][appveyor-url] [![Test Coverage][coveralls-image]][coveralls-url] @@ -316,13 +316,14 @@ server.listen(3000) [MIT](LICENSE) -[npm-image]: https://img.shields.io/npm/v/send.svg -[npm-url]: https://npmjs.org/package/send -[travis-image]: https://img.shields.io/travis/pillarjs/send/master.svg?label=linux -[travis-url]: https://travis-ci.org/pillarjs/send -[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/send/master.svg?label=windows +[appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/send/master?label=windows [appveyor-url]: https://ci.appveyor.com/project/dougwilson/send -[coveralls-image]: https://img.shields.io/coveralls/pillarjs/send/master.svg +[coveralls-image]: https://badgen.net/coveralls/c/github/pillarjs/send/master [coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master -[downloads-image]: https://img.shields.io/npm/dm/send.svg -[downloads-url]: https://npmjs.org/package/send +[node-image]: https://badgen.net/npm/node/send +[node-url]: https://nodejs.org/en/download/ +[npm-downloads-image]: https://badgen.net/npm/dm/send +[npm-url]: https://npmjs.org/package/send +[npm-version-image]: https://badgen.net/npm/v/send +[travis-image]: https://badgen.net/travis/pillarjs/send/master?label=linux +[travis-url]: https://travis-ci.org/pillarjs/send From 4645e8b9c6e8d4fcb577238e6aebae79595a3304 Mon Sep 17 00:00:00 2001 From: Andres Castillo Date: Fri, 1 Dec 2017 16:23:48 +0100 Subject: [PATCH 242/334] deps: mime@1.6.0 closes #154 closes #173 --- HISTORY.md | 13 +++++++++++++ package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index e8b42c59..609d315e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,6 +7,19 @@ unreleased - deps: depd@~1.1.2 - deps: setprototypeof@1.1.0 - deps: statuses@'>= 1.5.0 < 2' + * deps: mime@1.6.0 + - Add extensions for JPEG-2000 images + - Add new `font/*` types from IANA + - Add WASM mapping + - Update `.bdoc` to `application/bdoc` + - Update `.bmp` to `image/bmp` + - Update `.m4a` to `audio/mp4` + - Update `.rtf` to `application/rtf` + - Update `.wav` to `audio/wav` + - Update `.xml` to `application/xml` + - Update generic extensions to `application/octet-stream`: + `.deb`, `.dll`, `.dmg`, `.exe`, `.iso`, `.msi` + - Use mime-score module to resolve extension conflicts * deps: ms@2.1.1 - Add `week`/`w` support - Fix negative number handling diff --git a/package.json b/package.json index ac58fb8f..627ac01f 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "~1.7.1", - "mime": "1.4.1", + "mime": "1.6.0", "ms": "2.1.1", "on-finished": "~2.3.0", "range-parser": "~1.2.0", From 00d2e0d5a652878ed217d67d3eb14b8448c55cba Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 27 Oct 2018 21:28:47 -0400 Subject: [PATCH 243/334] build: Node.js@10.12 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 015d07ad..554d8154 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.12" - "9.11" - - "10.11" + - "10.12" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index b6f83286..7311c7e5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,7 @@ environment: - nodejs_version: "7.10" - nodejs_version: "8.12" - nodejs_version: "9.11" - - nodejs_version: "10.11" + - nodejs_version: "10.12" cache: - node_modules install: From 0069789c0a9fa8ef05fe2df445a89f81d4e44208 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 27 Oct 2018 21:50:32 -0400 Subject: [PATCH 244/334] deps: depd@~2.0.0 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 609d315e..375d85da 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,9 @@ unreleased ========== + * deps: depd@~2.0.0 + - Replace internal `eval` usage with `Function` constructor + - Use instance methods on `process` to check for listeners * deps: http-errors@~1.7.1 - Set constructor name when possible - Use `toidentifier` module to make class names diff --git a/package.json b/package.json index 627ac01f..bd13e235 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "~2.0.0", "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", From acefad9fd496366892115b838056f21fe5cea150 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 27 Oct 2018 23:41:23 -0400 Subject: [PATCH 245/334] build: eslint@5.8.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bd13e235..e7c25022 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "5.7.0", + "eslint": "5.8.0", "eslint-config-standard": "12.0.0", "eslint-plugin-import": "2.14.0", "eslint-plugin-markdown": "1.0.0-beta.6", From 290dcfd81431d18acea9d04e0a46d6f619052656 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 28 Nov 2018 10:09:28 -0500 Subject: [PATCH 246/334] build: eslint-plugin-markdown@1.0.0-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7c25022..7dc1e1ca 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "eslint": "5.8.0", "eslint-config-standard": "12.0.0", "eslint-plugin-import": "2.14.0", - "eslint-plugin-markdown": "1.0.0-beta.6", + "eslint-plugin-markdown": "1.0.0-rc.1", "eslint-plugin-node": "7.0.1", "eslint-plugin-promise": "4.0.1", "eslint-plugin-standard": "4.0.0", From c93061c988bd104e3acc65c29aa8daaef562eb91 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 28 Nov 2018 10:15:50 -0500 Subject: [PATCH 247/334] build: Node.js@6.15 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 554d8154..f42daab0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.9" - "5.12" - - "6.14" + - "6.15" - "7.10" - "8.12" - "9.11" diff --git a/appveyor.yml b/appveyor.yml index 7311c7e5..44d2d30a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.9" - nodejs_version: "5.12" - - nodejs_version: "6.14" + - nodejs_version: "6.15" - nodejs_version: "7.10" - nodejs_version: "8.12" - nodejs_version: "9.11" From b76566e9f79bbba0c30ad45e28a55637e9aa7430 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 28 Nov 2018 10:21:34 -0500 Subject: [PATCH 248/334] build: Node.js@8.13 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f42daab0..f23b83d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.15" - "7.10" - - "8.12" + - "8.13" - "9.11" - "10.12" sudo: false diff --git a/appveyor.yml b/appveyor.yml index 44d2d30a..70250ff7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.15" - nodejs_version: "7.10" - - nodejs_version: "8.12" + - nodejs_version: "8.13" - nodejs_version: "9.11" - nodejs_version: "10.12" cache: From dd76210f3fa03759599965331f39d52329fb88c2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 21 Jan 2019 00:21:35 -0500 Subject: [PATCH 249/334] build: eslint-plugin-node@8.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7dc1e1ca..51aafa4f 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "eslint-config-standard": "12.0.0", "eslint-plugin-import": "2.14.0", "eslint-plugin-markdown": "1.0.0-rc.1", - "eslint-plugin-node": "7.0.1", + "eslint-plugin-node": "8.0.1", "eslint-plugin-promise": "4.0.1", "eslint-plugin-standard": "4.0.0", "istanbul": "0.4.5", From 7b5a31a8e82afc98033ed32261ba3a52d223cb2f Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 21 Jan 2019 00:28:30 -0500 Subject: [PATCH 250/334] build: eslint@5.12.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 51aafa4f..8a7b653d 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "5.8.0", + "eslint": "5.12.1", "eslint-config-standard": "12.0.0", "eslint-plugin-import": "2.14.0", "eslint-plugin-markdown": "1.0.0-rc.1", From 1ff10b234ed22abce303f365084d3fa7a1f6222a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 21 Jan 2019 00:35:31 -0500 Subject: [PATCH 251/334] build: support Node.js 11.x --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index f23b83d8..0bf171dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ node_js: - "8.13" - "9.11" - "10.12" + - "11.7" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 70250ff7..044a7716 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,6 +13,7 @@ environment: - nodejs_version: "8.13" - nodejs_version: "9.11" - nodejs_version: "10.12" + - nodejs_version: "11.7" cache: - node_modules install: From c23a4c0daa5514a01b846ff03ddd65923893ce39 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 21 Jan 2019 00:41:12 -0500 Subject: [PATCH 252/334] build: supertest@3.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a7b653d..53508dc6 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "eslint-plugin-standard": "4.0.0", "istanbul": "0.4.5", "mocha": "5.2.0", - "supertest": "3.3.0" + "supertest": "3.4.1" }, "files": [ "HISTORY.md", From b67b0edb6d6d9649c7d8909cbf82384c26392b0c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 25 Mar 2019 16:40:11 -0400 Subject: [PATCH 253/334] build: Node.js@6.17 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0bf171dd..143b7401 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ node_js: - "3.3" - "4.9" - "5.12" - - "6.15" + - "6.17" - "7.10" - "8.13" - "9.11" diff --git a/appveyor.yml b/appveyor.yml index 044a7716..f9435c3c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,7 +8,7 @@ environment: - nodejs_version: "3.3" - nodejs_version: "4.9" - nodejs_version: "5.12" - - nodejs_version: "6.15" + - nodejs_version: "6.17" - nodejs_version: "7.10" - nodejs_version: "8.13" - nodejs_version: "9.11" From 5139d39a4b34ecd0ff39a67de9b8017eb45960bb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 25 Mar 2019 16:44:39 -0400 Subject: [PATCH 254/334] build: Node.js@8.15 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 143b7401..0ad974e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.17" - "7.10" - - "8.13" + - "8.15" - "9.11" - "10.12" - "11.7" diff --git a/appveyor.yml b/appveyor.yml index f9435c3c..22d27478 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.17" - nodejs_version: "7.10" - - nodejs_version: "8.13" + - nodejs_version: "8.15" - nodejs_version: "9.11" - nodejs_version: "10.12" - nodejs_version: "11.7" From fca5da696d45bb4240b9c57d7011769daac89465 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 25 Mar 2019 16:47:25 -0400 Subject: [PATCH 255/334] build: Node.js@11.12 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0ad974e0..5ef34095 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.15" - "9.11" - "10.12" - - "11.7" + - "11.12" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 22d27478..db006c95 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,7 +13,7 @@ environment: - nodejs_version: "8.15" - nodejs_version: "9.11" - nodejs_version: "10.12" - - nodejs_version: "11.7" + - nodejs_version: "11.12" cache: - node_modules install: From e09579142e7f17009047a936383f41b67bb53a9e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 26 Mar 2019 20:30:06 -0400 Subject: [PATCH 256/334] build: mocha@6.0.2 --- .travis.yml | 7 +++++-- appveyor.yml | 7 +++++-- package.json | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5ef34095..0e44e857 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,11 +27,14 @@ before_install: - | # mocha for testing # - use 2.x for Node.js < 0.10 - # - use 3.x for Node.js < 6 + # - use 3.x for Node.js < 4 + # - use 5.x for Node.js < 6 if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then npm install --save-dev mocha@2.5.3 - elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then + elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then npm install --save-dev mocha@3.5.3 + elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then + npm install --save-dev mocha@5.2.0 fi - | # supertest for http calls diff --git a/appveyor.yml b/appveyor.yml index db006c95..e16d0c3b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -41,11 +41,14 @@ install: - ps: | # mocha for testing # - use 2.x for Node.js < 0.10 - # - use 3.x for Node.js < 6 + # - use 3.x for Node.js < 4 + # - use 5.x for Node.js < 6 if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { npm install --silent --save-dev mocha@2.5.3 - } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 4) { npm install --silent --save-dev mocha@3.5.3 + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { + npm install --silent --save-dev mocha@5.2.0 } - ps: | # supertest for http calls diff --git a/package.json b/package.json index 53508dc6..5df20536 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "eslint-plugin-promise": "4.0.1", "eslint-plugin-standard": "4.0.0", "istanbul": "0.4.5", - "mocha": "5.2.0", + "mocha": "6.0.2", "supertest": "3.4.1" }, "files": [ From 58c5440f7b0596bd5209e6a74762229708951c12 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 26 Mar 2019 20:34:33 -0400 Subject: [PATCH 257/334] build: eslint-plugin-import@2.16.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5df20536..545fc9cf 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "5.12.1", "eslint-config-standard": "12.0.0", - "eslint-plugin-import": "2.14.0", + "eslint-plugin-import": "2.16.0", "eslint-plugin-markdown": "1.0.0-rc.1", "eslint-plugin-node": "8.0.1", "eslint-plugin-promise": "4.0.1", From aa22da74743b87a31ae8bf1a9f35a0259f0ddb3d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 26 Mar 2019 20:39:28 -0400 Subject: [PATCH 258/334] build: eslint-plugin-markdown@1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 545fc9cf..bda4d223 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "eslint": "5.12.1", "eslint-config-standard": "12.0.0", "eslint-plugin-import": "2.16.0", - "eslint-plugin-markdown": "1.0.0-rc.1", + "eslint-plugin-markdown": "1.0.0", "eslint-plugin-node": "8.0.1", "eslint-plugin-promise": "4.0.1", "eslint-plugin-standard": "4.0.0", From ea8dd85d92df787705f65d0758c7a611a93b2b67 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 26 Mar 2019 20:47:18 -0400 Subject: [PATCH 259/334] build: supertest@4.0.2 --- .travis.yml | 3 +++ appveyor.yml | 3 +++ package.json | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0e44e857..98e41b58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,10 +40,13 @@ before_install: # supertest for http calls # - use 1.1.0 for Node.js < 0.10 # - use 2.0.0 for Node.js < 4 + # - use 3.4.2 for Node.js < 6 if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then npm install --save-dev supertest@1.1.0 elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then npm install --save-dev supertest@2.0.0 + elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then + npm install --save-dev supertest@3.4.2 fi - | # istanbul for coverage diff --git a/appveyor.yml b/appveyor.yml index e16d0c3b..13f86881 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -54,10 +54,13 @@ install: # supertest for http calls # - use 1.1.0 for Node.js < 0.10 # - use 2.0.0 for Node.js < 4 + # - use 3.4.2 for Node.js < 6 if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { npm install --silent --save-dev supertest@1.1.0 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 4) { npm install --silent --save-dev supertest@2.0.0 + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { + npm install --silent --save-dev supertest@3.4.2 } # Update Node.js modules - ps: | diff --git a/package.json b/package.json index bda4d223..77b5fbfc 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "eslint-plugin-standard": "4.0.0", "istanbul": "0.4.5", "mocha": "6.0.2", - "supertest": "3.4.1" + "supertest": "4.0.2" }, "files": [ "HISTORY.md", From a110266596c62948d79e529b63de7a57f09b069d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 30 Mar 2019 14:50:51 -0400 Subject: [PATCH 260/334] deps: http-errors@~1.7.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 375d85da..4acfa5ff 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,11 +4,11 @@ unreleased * deps: depd@~2.0.0 - Replace internal `eval` usage with `Function` constructor - Use instance methods on `process` to check for listeners - * deps: http-errors@~1.7.1 + * deps: http-errors@~1.7.2 - Set constructor name when possible - Use `toidentifier` module to make class names - deps: depd@~1.1.2 - - deps: setprototypeof@1.1.0 + - deps: setprototypeof@1.1.1 - deps: statuses@'>= 1.5.0 < 2' * deps: mime@1.6.0 - Add extensions for JPEG-2000 images diff --git a/package.json b/package.json index 77b5fbfc..ad4925a0 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.1", + "http-errors": "~1.7.2", "mime": "1.6.0", "ms": "2.1.1", "on-finished": "~2.3.0", From 03d8c91ba6ce845c2db4cbaf3e0ba52d0650e415 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 30 Apr 2019 19:02:57 -0400 Subject: [PATCH 261/334] build: Node.js@8.16 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 98e41b58..83f3a9c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ node_js: - "5.12" - "6.17" - "7.10" - - "8.15" + - "8.16" - "9.11" - "10.12" - "11.12" diff --git a/appveyor.yml b/appveyor.yml index 13f86881..43c16153 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: - nodejs_version: "5.12" - nodejs_version: "6.17" - nodejs_version: "7.10" - - nodejs_version: "8.15" + - nodejs_version: "8.16" - nodejs_version: "9.11" - nodejs_version: "10.12" - nodejs_version: "11.12" From b670c8dd1b27c0408449df6e8b343ccd153e93eb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 30 Apr 2019 19:10:18 -0400 Subject: [PATCH 262/334] build: Node.js@10.15 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 83f3a9c8..a9713b9f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ node_js: - "7.10" - "8.16" - "9.11" - - "10.12" + - "10.15" - "11.12" sudo: false cache: diff --git a/appveyor.yml b/appveyor.yml index 43c16153..1a5705dd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,7 @@ environment: - nodejs_version: "7.10" - nodejs_version: "8.16" - nodejs_version: "9.11" - - nodejs_version: "10.12" + - nodejs_version: "10.15" - nodejs_version: "11.12" cache: - node_modules From e210d795350d0939657ac7430ad2b208a9302b07 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 30 Apr 2019 19:18:48 -0400 Subject: [PATCH 263/334] build: Node.js@11.15 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a9713b9f..3cb318cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ node_js: - "8.16" - "9.11" - "10.15" - - "11.12" + - "11.15" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 1a5705dd..79c55700 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,7 +13,7 @@ environment: - nodejs_version: "8.16" - nodejs_version: "9.11" - nodejs_version: "10.15" - - nodejs_version: "11.12" + - nodejs_version: "11.15" cache: - node_modules install: From 8e42e1ad0840cd752dcfddaeddb16cb54d504621 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 30 Apr 2019 19:23:03 -0400 Subject: [PATCH 264/334] build: support Node.js 12.x --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3cb318cc..8e1f4c4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ node_js: - "9.11" - "10.15" - "11.15" + - "12.1" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 79c55700..9fac2bda 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,7 @@ environment: - nodejs_version: "9.11" - nodejs_version: "10.15" - nodejs_version: "11.15" + - nodejs_version: "12.1" cache: - node_modules install: From b44395654b9d1ccc1e8c382bd23227054f698336 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 1 May 2019 22:21:51 -0400 Subject: [PATCH 265/334] build: eslint@5.16.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ad4925a0..bd5bc954 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "5.12.1", + "eslint": "5.16.0", "eslint-config-standard": "12.0.0", "eslint-plugin-import": "2.16.0", "eslint-plugin-markdown": "1.0.0", From 6087d95fc458592ae9a07fee4d23da2c485819d9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 1 May 2019 22:22:17 -0400 Subject: [PATCH 266/334] build: eslint-plugin-import@2.17.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bd5bc954..264d2b84 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "5.16.0", "eslint-config-standard": "12.0.0", - "eslint-plugin-import": "2.16.0", + "eslint-plugin-import": "2.17.2", "eslint-plugin-markdown": "1.0.0", "eslint-plugin-node": "8.0.1", "eslint-plugin-promise": "4.0.1", From 452c90d7e4a518d37077def0bc2d9ec31d1ea679 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 1 May 2019 22:22:46 -0400 Subject: [PATCH 267/334] build: eslint-plugin-promise@4.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 264d2b84..bda60332 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "eslint-plugin-import": "2.17.2", "eslint-plugin-markdown": "1.0.0", "eslint-plugin-node": "8.0.1", - "eslint-plugin-promise": "4.0.1", + "eslint-plugin-promise": "4.1.1", "eslint-plugin-standard": "4.0.0", "istanbul": "0.4.5", "mocha": "6.0.2", From 964921afadc6ab03a1663e190f37d8124111a3fc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 1 May 2019 22:23:11 -0400 Subject: [PATCH 268/334] build: mocha@6.1.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bda60332..d062c458 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "eslint-plugin-promise": "4.1.1", "eslint-plugin-standard": "4.0.0", "istanbul": "0.4.5", - "mocha": "6.0.2", + "mocha": "6.1.4", "supertest": "4.0.2" }, "files": [ From e6844c4712e4366308453c54aed9bd34054d99bb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 3 May 2019 16:42:01 -0400 Subject: [PATCH 269/334] Revert "deps: depd@~2.0.0" This reverts commit 0069789c0a9fa8ef05fe2df445a89f81d4e44208. --- HISTORY.md | 3 --- package.json | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 4acfa5ff..686170f3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,9 +1,6 @@ unreleased ========== - * deps: depd@~2.0.0 - - Replace internal `eval` usage with `Function` constructor - - Use instance methods on `process` to check for listeners * deps: http-errors@~1.7.2 - Set constructor name when possible - Use `toidentifier` module to make class names diff --git a/package.json b/package.json index d062c458..c2a100c7 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "dependencies": { "debug": "2.6.9", - "depd": "~2.0.0", + "depd": "~1.1.2", "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", From 0ef8f0cb8d8f3875f034d04d16db37a85f6150d8 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 3 May 2019 16:47:47 -0400 Subject: [PATCH 270/334] 0.17.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 686170f3..d25f7135 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.17.0 / 2019-05-03 +=================== * deps: http-errors@~1.7.2 - Set constructor name when possible diff --git a/package.json b/package.json index c2a100c7..5d984b64 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.16.2", + "version": "0.17.0", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From 836ed62923c10b50c67c55b96ac67c46d8d2e4c0 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 May 2019 22:06:27 -0400 Subject: [PATCH 271/334] build: Node.js@12.2 --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8e1f4c4f..ae5f35e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ node_js: - "9.11" - "10.15" - "11.15" - - "12.1" + - "12.2" sudo: false cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 9fac2bda..40abaa11 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,7 +14,7 @@ environment: - nodejs_version: "9.11" - nodejs_version: "10.15" - nodejs_version: "11.15" - - nodejs_version: "12.1" + - nodejs_version: "12.2" cache: - node_modules install: From 7e4e84569f69f8f8f272f5afa0190810d4fd3548 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 May 2019 22:08:55 -0400 Subject: [PATCH 272/334] Set stricter CSP header in redirect & error responses --- HISTORY.md | 5 +++++ index.js | 4 ++-- test/send.js | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d25f7135..59aae2e3 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Set stricter CSP header in redirect & error responses + 0.17.0 / 2019-05-03 =================== diff --git a/index.js b/index.js index 0b7a39db..fca21121 100644 --- a/index.js +++ b/index.js @@ -288,7 +288,7 @@ SendStream.prototype.error = function error (status, err) { res.statusCode = status res.setHeader('Content-Type', 'text/html; charset=UTF-8') res.setHeader('Content-Length', Buffer.byteLength(doc)) - res.setHeader('Content-Security-Policy', "default-src 'self'") + res.setHeader('Content-Security-Policy', "default-src 'none'") res.setHeader('X-Content-Type-Options', 'nosniff') res.end(doc) } @@ -493,7 +493,7 @@ SendStream.prototype.redirect = function redirect (path) { res.statusCode = 301 res.setHeader('Content-Type', 'text/html; charset=UTF-8') res.setHeader('Content-Length', Buffer.byteLength(doc)) - res.setHeader('Content-Security-Policy', "default-src 'self'") + res.setHeader('Content-Security-Policy', "default-src 'none'") res.setHeader('X-Content-Type-Options', 'nosniff') res.setHeader('Location', loc) res.end(doc) diff --git a/test/send.js b/test/send.js index 7586fb4d..8b27261f 100644 --- a/test/send.js +++ b/test/send.js @@ -365,7 +365,7 @@ describe('send(file).pipe(res)', function () { request(createServer({ root: fixtures })) .get('/pets') .expect('Location', '/pets/') - .expect('Content-Security-Policy', "default-src 'self'") + .expect('Content-Security-Policy', "default-src 'none'") .expect(301, done) }) @@ -400,7 +400,7 @@ describe('send(file).pipe(res)', function () { it('should respond with default Content-Security-Policy', function (done) { request(createServer({ root: fixtures })) .get('/foobar') - .expect('Content-Security-Policy', "default-src 'self'") + .expect('Content-Security-Policy', "default-src 'none'") .expect(404, done) }) From e0c53551289ced4747f56ab3d611e58330697192 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 May 2019 20:28:25 -0400 Subject: [PATCH 273/334] deps: range-parser@~1.2.1 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 59aae2e3..c77f2a8b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Set stricter CSP header in redirect & error responses + * deps: range-parser@~1.2.1 0.17.0 / 2019-05-03 =================== diff --git a/package.json b/package.json index 5d984b64..a6a54a32 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "mime": "1.6.0", "ms": "2.1.1", "on-finished": "~2.3.0", - "range-parser": "~1.2.0", + "range-parser": "~1.2.1", "statuses": "~1.5.0" }, "devDependencies": { From de073ed3237ade9ff71c61673a34474b30e5d45b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 May 2019 21:06:58 -0400 Subject: [PATCH 274/334] 0.17.1 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index c77f2a8b..d14ac069 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.17.1 / 2019-05-10 +=================== * Set stricter CSP header in redirect & error responses * deps: range-parser@~1.2.1 diff --git a/package.json b/package.json index a6a54a32..2ba9c06b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.17.0", + "version": "0.17.1", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From 57357b1299d9c081568360db3884b21e50132664 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 23 Nov 2020 22:51:58 -0500 Subject: [PATCH 275/334] build: use GitHub Actions instead of Travis CI --- .github/workflows/ci.yml | 160 +++++++++++++++++++++++++++++++++++++++ .travis.yml | 92 ---------------------- README.md | 6 +- 3 files changed, 163 insertions(+), 95 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..f822f0b7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,160 @@ +name: ci + +on: +- pull_request +- push + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + name: + - Node.js 0.8 + - Node.js 0.10 + - Node.js 0.12 + - io.js 1.x + - io.js 2.x + - io.js 3.x + - Node.js 4.x + - Node.js 5.x + - Node.js 6.x + - Node.js 7.x + - Node.js 8.x + - Node.js 9.x + - Node.js 10.x + - Node.js 11.x + - Node.js 12.x + + include: + - name: Node.js 0.8 + node-version: "0.8" + npm-i: mocha@2.5.3 supertest@1.1.0 + npm-rm: istanbul + + - name: Node.js 0.10 + node-version: "0.10" + npm-i: mocha@3.5.3 supertest@2.0.0 + + - name: Node.js 0.12 + node-version: "0.12" + npm-i: mocha@3.5.3 supertest@2.0.0 + + - name: io.js 1.x + node-version: "1.8" + npm-i: mocha@3.5.3 supertest@2.0.0 + + - name: io.js 2.x + node-version: "2.5" + npm-i: mocha@3.5.3 supertest@2.0.0 + + - name: io.js 3.x + node-version: "3.3" + npm-i: mocha@3.5.3 supertest@2.0.0 + + - name: Node.js 4.x + node-version: "4.9" + npm-i: mocha@5.2.0 supertest@3.4.2 + + - name: Node.js 5.x + node-version: "5.12" + npm-i: mocha@5.2.0 supertest@3.4.2 + + - name: Node.js 6.x + node-version: "6.17" + + - name: Node.js 7.x + node-version: "7.10" + + - name: Node.js 8.x + node-version: "8.16" + + - name: Node.js 9.x + node-version: "9.11" + + - name: Node.js 10.x + node-version: "10.15" + + - name: Node.js 11.x + node-version: "11.15" + + - name: Node.js 12.x + node-version: "12.2" + + steps: + - uses: actions/checkout@v2 + + - name: Install Node.js ${{ matrix.node-version }} + shell: bash -eo pipefail -l {0} + run: | + nvm install --default ${{ matrix.node-version }} + if [[ "${{ matrix.node-version }}" == 0.* ]]; then + npm config set strict-ssl false + fi + dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH" + + - name: Configure npm + run: npm config set shrinkwrap false + + - name: Remove npm module(s) ${{ matrix.npm-rm }} + run: npm rm --silent --save-dev ${{ matrix.npm-rm }} + if: matrix.npm-rm != '' + + - name: Install npm module(s) ${{ matrix.npm-i }} + run: npm install --save-dev ${{ matrix.npm-i }} + if: matrix.npm-i != '' + + - name: Setup Node.js version-specific dependencies + shell: bash + run: | + # eslint for linting + # - remove on Node.js < 6 + if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 6 ]]; then + node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ + grep -E '^eslint(-|$)' | \ + sort -r | \ + xargs -n1 npm rm --silent --save-dev + fi + + - name: Install Node.js dependencies + run: npm install + + - name: List environment + id: list_env + shell: bash + run: | + echo "node@$(node -v)" + echo "npm@$(npm -v)" + npm -s ls ||: + (npm -s ls --depth=0 ||:) | awk -F'[ @]' 'NR>1 && $2 { print "::set-output name=" $2 "::" $3 }' + + - name: Run tests + shell: bash + run: | + if npm -ps ls istanbul | grep -q istanbul; then + npm run test-ci + else + npm test + fi + + - name: Lint code + if: steps.list_env.outputs.eslint != '' + run: npm run lint + + - name: Collect code coverage + uses: coverallsapp/github-action@master + if: steps.list_env.outputs.istanbul != '' + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: run-${{ matrix.test_number }} + parallel: true + + coverage: + needs: test + runs-on: ubuntu-latest + steps: + - name: Uploade code coverage + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + parallel-finished: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ae5f35e0..00000000 --- a/.travis.yml +++ /dev/null @@ -1,92 +0,0 @@ -language: node_js -node_js: - - "0.8" - - "0.10" - - "0.12" - - "1.8" - - "2.5" - - "3.3" - - "4.9" - - "5.12" - - "6.17" - - "7.10" - - "8.16" - - "9.11" - - "10.15" - - "11.15" - - "12.2" -sudo: false -cache: - directories: - - node_modules -before_install: - # Configure npm - - | - # Skip updating shrinkwrap / lock - npm config set shrinkwrap false - # Setup Node.js version-specific dependencies - - | - # mocha for testing - # - use 2.x for Node.js < 0.10 - # - use 3.x for Node.js < 4 - # - use 5.x for Node.js < 6 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then - npm install --save-dev mocha@2.5.3 - elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then - npm install --save-dev mocha@3.5.3 - elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then - npm install --save-dev mocha@5.2.0 - fi - - | - # supertest for http calls - # - use 1.1.0 for Node.js < 0.10 - # - use 2.0.0 for Node.js < 4 - # - use 3.4.2 for Node.js < 6 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then - npm install --save-dev supertest@1.1.0 - elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then - npm install --save-dev supertest@2.0.0 - elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then - npm install --save-dev supertest@3.4.2 - fi - - | - # istanbul for coverage - # - remove for Node.js < 0.10 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -eq 0 && "$(cut -d. -f2 <<< "$TRAVIS_NODE_VERSION")" -lt 10 ]]; then - npm rm --silent --save-dev istanbul - fi - - | - # eslint for linting - # - remove on Node.js < 6 - if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then - node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ - grep -E '^eslint(-|$)' | \ - xargs npm rm --save-dev - fi - # Update Node.js modules - - | - # Prune and rebuild node_modules - if [[ -d node_modules ]]; then - npm prune - npm rebuild - fi -script: - # Run test script - - | - if npm -ps ls istanbul | grep -q istanbul; then - npm run test-ci - else - npm test - fi - # Run linting - - | - if npm -ps ls eslint | grep -q eslint; then - npm run lint - fi -after_script: - - | - # Upload coverage to coveralls - if [[ -f ./coverage/lcov.info ]]; then - npm install --save-dev coveralls@2.13.3 - coveralls < ./coverage/lcov.info - fi diff --git a/README.md b/README.md index 179e8c32..f878e2ef 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] -[![Linux Build][travis-image]][travis-url] +[![Linux Build][github-actions-ci-image]][github-actions-ci-url] [![Windows Build][appveyor-image]][appveyor-url] [![Test Coverage][coveralls-image]][coveralls-url] @@ -320,10 +320,10 @@ server.listen(3000) [appveyor-url]: https://ci.appveyor.com/project/dougwilson/send [coveralls-image]: https://badgen.net/coveralls/c/github/pillarjs/send/master [coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master +[github-actions-ci-image]: https://badgen.net/github/checks/pillarjs/send/master?label=ci +[github-actions-ci-url]: https://github.com/pillarjs/send/actions?query=workflow%3Aci [node-image]: https://badgen.net/npm/node/send [node-url]: https://nodejs.org/en/download/ [npm-downloads-image]: https://badgen.net/npm/dm/send [npm-url]: https://npmjs.org/package/send [npm-version-image]: https://badgen.net/npm/v/send -[travis-image]: https://badgen.net/travis/pillarjs/send/master?label=linux -[travis-url]: https://travis-ci.org/pillarjs/send From 25ad977ce2d1ba9a5d6cd70b8ab5b220592e8969 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 26 Nov 2020 17:43:14 -0500 Subject: [PATCH 276/334] build: Node.js@12.20 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f822f0b7..f2387ed3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,7 +79,7 @@ jobs: node-version: "11.15" - name: Node.js 12.x - node-version: "12.2" + node-version: "12.20" steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 40abaa11..1eeaf783 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,7 +14,7 @@ environment: - nodejs_version: "9.11" - nodejs_version: "10.15" - nodejs_version: "11.15" - - nodejs_version: "12.2" + - nodejs_version: "12.20" cache: - node_modules install: From 5d298ae85fe375bdce51f9bd93e39f5d58a0647d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 26 Nov 2020 17:45:20 -0500 Subject: [PATCH 277/334] build: Node.js@10.23 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2387ed3..16187de7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,7 +73,7 @@ jobs: node-version: "9.11" - name: Node.js 10.x - node-version: "10.15" + node-version: "10.23" - name: Node.js 11.x node-version: "11.15" diff --git a/appveyor.yml b/appveyor.yml index 1eeaf783..961dc7cf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,7 @@ environment: - nodejs_version: "7.10" - nodejs_version: "8.16" - nodejs_version: "9.11" - - nodejs_version: "10.15" + - nodejs_version: "10.23" - nodejs_version: "11.15" - nodejs_version: "12.20" cache: From ad6e44f408fe12bbfaa5ae21969055f3006ca1bb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 29 Nov 2020 20:51:03 -0500 Subject: [PATCH 278/334] build: mocha@6.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ba9c06b..2478354d 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "eslint-plugin-promise": "4.1.1", "eslint-plugin-standard": "4.0.0", "istanbul": "0.4.5", - "mocha": "6.1.4", + "mocha": "6.2.3", "supertest": "4.0.2" }, "files": [ From 7edc28fbbd54f4fa7ca6eb56512240c6c603b7de Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 17 Dec 2020 21:09:53 -0500 Subject: [PATCH 279/334] lint: apply standard 14 style --- .github/workflows/ci.yml | 4 ++-- index.js | 2 +- package.json | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16187de7..2d77ef27 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,8 +108,8 @@ jobs: shell: bash run: | # eslint for linting - # - remove on Node.js < 6 - if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 6 ]]; then + # - remove on Node.js < 8 + if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 8 ]]; then node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ grep -E '^eslint(-|$)' | \ sort -r | \ diff --git a/index.js b/index.js index fca21121..76bc44e9 100644 --- a/index.js +++ b/index.js @@ -435,7 +435,7 @@ SendStream.prototype.onStatError = function onStatError (error) { SendStream.prototype.isFresh = function isFresh () { return fresh(this.req.headers, { - 'etag': this.res.getHeader('ETag'), + etag: this.res.getHeader('ETag'), 'last-modified': this.res.getHeader('Last-Modified') }) } diff --git a/package.json b/package.json index 2478354d..146485d3 100644 --- a/package.json +++ b/package.json @@ -32,13 +32,13 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "5.16.0", - "eslint-config-standard": "12.0.0", - "eslint-plugin-import": "2.17.2", + "eslint": "6.8.0", + "eslint-config-standard": "14.1.1", + "eslint-plugin-import": "2.22.1", "eslint-plugin-markdown": "1.0.0", - "eslint-plugin-node": "8.0.1", - "eslint-plugin-promise": "4.1.1", - "eslint-plugin-standard": "4.0.0", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-promise": "4.2.1", + "eslint-plugin-standard": "4.0.2", "istanbul": "0.4.5", "mocha": "6.2.3", "supertest": "4.0.2" From 44c92c9a6629e1bd423a652da355c2d717879389 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 17 Dec 2020 21:12:54 -0500 Subject: [PATCH 280/334] build: support Node.js 13.x --- .github/workflows/ci.yml | 3 +++ appveyor.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d77ef27..5ddcc730 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,6 +81,9 @@ jobs: - name: Node.js 12.x node-version: "12.20" + - name: Node.js 13.x + node-version: "13.14" + steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 961dc7cf..b6e5e5e0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,6 +15,7 @@ environment: - nodejs_version: "10.23" - nodejs_version: "11.15" - nodejs_version: "12.20" + - nodejs_version: "13.14" cache: - node_modules install: From 1b0163b32c8f0e47f03d93cda8061066b326216e Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 26 Dec 2020 21:09:12 -0500 Subject: [PATCH 281/334] build: eslint-plugin-markdown@1.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 146485d3..ad3e865c 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "eslint": "6.8.0", "eslint-config-standard": "14.1.1", "eslint-plugin-import": "2.22.1", - "eslint-plugin-markdown": "1.0.0", + "eslint-plugin-markdown": "1.0.2", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "4.2.1", "eslint-plugin-standard": "4.0.2", From bde55faacec7a3181994ac28eef5270d630622fc Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 26 Dec 2020 21:15:03 -0500 Subject: [PATCH 282/334] build: mocha@7.2.0 --- .github/workflows/ci.yml | 2 ++ appveyor.yml | 3 +++ package.json | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ddcc730..946d930b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,9 +62,11 @@ jobs: - name: Node.js 6.x node-version: "6.17" + npm-i: mocha@6.2.3 - name: Node.js 7.x node-version: "7.10" + npm-i: mocha@6.2.3 - name: Node.js 8.x node-version: "8.16" diff --git a/appveyor.yml b/appveyor.yml index b6e5e5e0..a4da1840 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -45,12 +45,15 @@ install: # - use 2.x for Node.js < 0.10 # - use 3.x for Node.js < 4 # - use 5.x for Node.js < 6 + # - use 6.x for Node.js < 8 if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { npm install --silent --save-dev mocha@2.5.3 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 4) { npm install --silent --save-dev mocha@3.5.3 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { npm install --silent --save-dev mocha@5.2.0 + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 8) { + npm install --silent --save-dev mocha@6.2.3 } - ps: | # supertest for http calls diff --git a/package.json b/package.json index ad3e865c..4a816d9d 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "eslint-plugin-promise": "4.2.1", "eslint-plugin-standard": "4.0.2", "istanbul": "0.4.5", - "mocha": "6.2.3", + "mocha": "7.2.0", "supertest": "4.0.2" }, "files": [ From 598707020808fdd1c6e739d016b6bab02c2201e1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 29 Dec 2020 19:44:50 -0500 Subject: [PATCH 283/334] build: supertest@6.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4a816d9d..4c88cfac 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "eslint-plugin-standard": "4.0.2", "istanbul": "0.4.5", "mocha": "7.2.0", - "supertest": "4.0.2" + "supertest": "6.0.1" }, "files": [ "HISTORY.md", From 63a7a80fc8e1b475e6b4b8934c47c55c79a7998d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 29 Dec 2020 19:46:21 -0500 Subject: [PATCH 284/334] build: fix Node.js 13.x entry --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 946d930b..56cb7973 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,7 @@ jobs: - Node.js 10.x - Node.js 11.x - Node.js 12.x + - Node.js 13.x include: - name: Node.js 0.8 From 8e7082fc53be347cffe02712a90e563493db9bbe Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Oct 2021 20:03:00 -0400 Subject: [PATCH 285/334] build: update CI for npm TLS upgrade --- .github/workflows/ci.yml | 5 ++++- appveyor.yml | 15 ++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56cb7973..dbade2c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,7 +94,10 @@ jobs: shell: bash -eo pipefail -l {0} run: | nvm install --default ${{ matrix.node-version }} - if [[ "${{ matrix.node-version }}" == 0.* ]]; then + if [[ "${{ matrix.node-version }}" == 0.* && "$(cut -d. -f2 <<< "${{ matrix.node-version }}")" -lt 10 ]]; then + nvm install --alias=npm 0.10 + nvm use ${{ matrix.node-version }} + sed -i '1s;^.*$;'"$(printf '#!%q' "$(nvm which npm)")"';' "$(readlink -f "$(which npm)")" npm config set strict-ssl false fi dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH" diff --git a/appveyor.yml b/appveyor.yml index a4da1840..0d46e7a3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,5 @@ environment: matrix: - - nodejs_version: "0.8" - nodejs_version: "0.10" - nodejs_version: "0.12" - nodejs_version: "1.8" @@ -27,10 +26,6 @@ install: - ps: | # Skip updating shrinkwrap / lock npm config set shrinkwrap false - # Skip SSL validation on Node.js < 0.10 - if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { - npm config set strict-ssl false - } # Remove all non-test dependencies - ps: | # Remove coverage dependency @@ -42,13 +37,10 @@ install: # Setup Node.js version-specific dependencies - ps: | # mocha for testing - # - use 2.x for Node.js < 0.10 # - use 3.x for Node.js < 4 # - use 5.x for Node.js < 6 # - use 6.x for Node.js < 8 - if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { - npm install --silent --save-dev mocha@2.5.3 - } elseif ([int]$env:nodejs_version.split(".")[0] -lt 4) { + if ([int]$env:nodejs_version.split(".")[0] -lt 4) { npm install --silent --save-dev mocha@3.5.3 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { npm install --silent --save-dev mocha@5.2.0 @@ -57,12 +49,9 @@ install: } - ps: | # supertest for http calls - # - use 1.1.0 for Node.js < 0.10 # - use 2.0.0 for Node.js < 4 # - use 3.4.2 for Node.js < 6 - if ([int]$env:nodejs_version.split(".")[0] -eq 0 -and [int]$env:nodejs_version.split(".")[1] -lt 10) { - npm install --silent --save-dev supertest@1.1.0 - } elseif ([int]$env:nodejs_version.split(".")[0] -lt 4) { + if ([int]$env:nodejs_version.split(".")[0] -lt 4) { npm install --silent --save-dev supertest@2.0.0 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { npm install --silent --save-dev supertest@3.4.2 From 070bf34dd2707ac4f6093b4fb3ba60bd23ec40fb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Oct 2021 20:05:00 -0400 Subject: [PATCH 286/334] build: Node.js@10.24 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbade2c3..8e4fdbbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,7 +76,7 @@ jobs: node-version: "9.11" - name: Node.js 10.x - node-version: "10.23" + node-version: "10.24" - name: Node.js 11.x node-version: "11.15" diff --git a/appveyor.yml b/appveyor.yml index 0d46e7a3..6576a8b8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ environment: - nodejs_version: "7.10" - nodejs_version: "8.16" - nodejs_version: "9.11" - - nodejs_version: "10.23" + - nodejs_version: "10.24" - nodejs_version: "11.15" - nodejs_version: "12.20" - nodejs_version: "13.14" From 3fc84548ebff43fa44edc8a09601930247fcdc07 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 16 Oct 2021 20:06:00 -0400 Subject: [PATCH 287/334] build: Node.js@12.22 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e4fdbbd..2198fc18 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,7 +82,7 @@ jobs: node-version: "11.15" - name: Node.js 12.x - node-version: "12.20" + node-version: "12.22" - name: Node.js 13.x node-version: "13.14" diff --git a/appveyor.yml b/appveyor.yml index 6576a8b8..07dbbdf0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,7 +13,7 @@ environment: - nodejs_version: "9.11" - nodejs_version: "10.24" - nodejs_version: "11.15" - - nodejs_version: "12.20" + - nodejs_version: "12.22" - nodejs_version: "13.14" cache: - node_modules From b52f7a79d17e2a02d80fbb3ffae492cb6e7214fb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 17 Oct 2021 00:02:00 -0400 Subject: [PATCH 288/334] build: support Node.js 14.x --- .github/workflows/ci.yml | 3 +++ appveyor.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2198fc18..77e27e67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,6 +87,9 @@ jobs: - name: Node.js 13.x node-version: "13.14" + - name: Node.js 14.x + node-version: "14.18" + steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 07dbbdf0..78c8a432 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,6 +15,7 @@ environment: - nodejs_version: "11.15" - nodejs_version: "12.22" - nodejs_version: "13.14" + - nodejs_version: "14.18" cache: - node_modules install: From f814756d4e2f799eeefd6115ccf07efade9f6282 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 17 Oct 2021 00:05:00 -0400 Subject: [PATCH 289/334] build: eslint-plugin-import@2.24.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c88cfac..494ee79b 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "6.8.0", "eslint-config-standard": "14.1.1", - "eslint-plugin-import": "2.22.1", + "eslint-plugin-import": "2.24.2", "eslint-plugin-markdown": "1.0.2", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "4.2.1", From ad9ba540d1c96350feff5454a81b8c8590e2d2b1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 17 Oct 2021 00:11:00 -0400 Subject: [PATCH 290/334] build: mocha@8.4.0 --- .github/workflows/ci.yml | 2 ++ appveyor.yml | 3 +++ package.json | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77e27e67..39884c8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,9 +71,11 @@ jobs: - name: Node.js 8.x node-version: "8.16" + npm-i: mocha@7.2.0 - name: Node.js 9.x node-version: "9.11" + npm-i: mocha@7.2.0 - name: Node.js 10.x node-version: "10.24" diff --git a/appveyor.yml b/appveyor.yml index 78c8a432..9e69cc53 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -41,12 +41,15 @@ install: # - use 3.x for Node.js < 4 # - use 5.x for Node.js < 6 # - use 6.x for Node.js < 8 + # - use 7.x for Node.js < 10 if ([int]$env:nodejs_version.split(".")[0] -lt 4) { npm install --silent --save-dev mocha@3.5.3 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { npm install --silent --save-dev mocha@5.2.0 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 8) { npm install --silent --save-dev mocha@6.2.3 + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 10) { + npm install --silent --save-dev mocha@7.2.0 } - ps: | # supertest for http calls diff --git a/package.json b/package.json index 494ee79b..b813e07a 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "eslint-plugin-promise": "4.2.1", "eslint-plugin-standard": "4.0.2", "istanbul": "0.4.5", - "mocha": "7.2.0", + "mocha": "8.4.0", "supertest": "6.0.1" }, "files": [ From 5186f17f50ea70b6148b39a8e5aa9fd4a4bd7d4b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Nov 2021 19:21:00 -0400 Subject: [PATCH 291/334] build: support Node.js 15.x --- .github/workflows/ci.yml | 3 +++ appveyor.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39884c8b..179e460d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,6 +92,9 @@ jobs: - name: Node.js 14.x node-version: "14.18" + - name: Node.js 15.x + node-version: "15.14" + steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 9e69cc53..893363de 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,6 +16,7 @@ environment: - nodejs_version: "12.22" - nodejs_version: "13.14" - nodejs_version: "14.18" + - nodejs_version: "15.14" cache: - node_modules install: From ee9ace7d7e53b08cf2adcea72bcc6efd9ce93634 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Nov 2021 19:28:00 -0400 Subject: [PATCH 292/334] build: eslint@7.32.0 --- .github/workflows/ci.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 179e460d..a142f110 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -126,7 +126,7 @@ jobs: run: | # eslint for linting # - remove on Node.js < 8 - if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 8 ]]; then + if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -lt 10 ]]; then node -pe 'Object.keys(require("./package").devDependencies).join("\n")' | \ grep -E '^eslint(-|$)' | \ sort -r | \ diff --git a/package.json b/package.json index b813e07a..29404a5d 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ }, "devDependencies": { "after": "0.8.2", - "eslint": "6.8.0", + "eslint": "7.32.0", "eslint-config-standard": "14.1.1", "eslint-plugin-import": "2.24.2", "eslint-plugin-markdown": "1.0.2", From 2b2b275bcd55c08abc764fee227c49982111f873 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Nov 2021 19:31:00 -0400 Subject: [PATCH 293/334] build: support Node.js 16.x --- .github/workflows/ci.yml | 3 +++ appveyor.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a142f110..162820f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,6 +95,9 @@ jobs: - name: Node.js 15.x node-version: "15.14" + - name: Node.js 16.x + node-version: "16.13" + steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 893363de..874651b1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,6 +17,7 @@ environment: - nodejs_version: "13.14" - nodejs_version: "14.18" - nodejs_version: "15.14" + - nodejs_version: "16.13" cache: - node_modules install: From 5b08d3053f35b835dd0a23c3d25eb2dd9c5c9ae4 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 4 Nov 2021 19:34:00 -0400 Subject: [PATCH 294/334] build: mocha@8.1.3 --- .github/workflows/ci.yml | 2 ++ appveyor.yml | 3 +++ package.json | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 162820f6..0e96ed44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,9 +79,11 @@ jobs: - name: Node.js 10.x node-version: "10.24" + npm-i: mocha@8.4.0 - name: Node.js 11.x node-version: "11.15" + npm-i: mocha@8.4.0 - name: Node.js 12.x node-version: "12.22" diff --git a/appveyor.yml b/appveyor.yml index 874651b1..8ac03019 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -44,6 +44,7 @@ install: # - use 5.x for Node.js < 6 # - use 6.x for Node.js < 8 # - use 7.x for Node.js < 10 + # - use 8.x for Node.js < 12 if ([int]$env:nodejs_version.split(".")[0] -lt 4) { npm install --silent --save-dev mocha@3.5.3 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { @@ -52,6 +53,8 @@ install: npm install --silent --save-dev mocha@6.2.3 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 10) { npm install --silent --save-dev mocha@7.2.0 + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 12) { + npm install --silent --save-dev mocha@8.4.0 } - ps: | # supertest for http calls diff --git a/package.json b/package.json index 29404a5d..41fbdd32 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "eslint-plugin-promise": "4.2.1", "eslint-plugin-standard": "4.0.2", "istanbul": "0.4.5", - "mocha": "8.4.0", + "mocha": "9.1.3", "supertest": "6.0.1" }, "files": [ From aa11a0a5c2f6281f7a3a8841a2e35b695bd875ac Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 22 Nov 2021 23:09:00 -0500 Subject: [PATCH 295/334] deps: http-errors@~1.8.1 --- HISTORY.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index d14ac069..d4606b5a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,11 @@ +unreleased +========== + + * deps: http-errors@~1.8.1 + - deps: inherits@2.0.4 + - deps: toidentifier@1.0.1 + - deps: setprototypeof@1.2.0 + 0.17.1 / 2019-05-10 =================== diff --git a/package.json b/package.json index 41fbdd32..d5b6df2c 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", + "http-errors": "~1.8.1", "mime": "1.6.0", "ms": "2.1.1", "on-finished": "~2.3.0", From e648b783a7b2010a7fb286be1c0034beb9747364 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 22 Nov 2021 23:12:00 -0500 Subject: [PATCH 296/334] build: ignore package-lock --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3cd27afd..0fa6951f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ coverage/ node_modules/ npm-debug.log +package-lock.json From b7a18a307c7f64a28824db59fe14552c7672594c Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 22 Nov 2021 23:16:00 -0500 Subject: [PATCH 297/334] build: eslint-plugin-import@2.25.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5b6df2c..9100ff0a 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "7.32.0", "eslint-config-standard": "14.1.1", - "eslint-plugin-import": "2.24.2", + "eslint-plugin-import": "2.25.3", "eslint-plugin-markdown": "1.0.2", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "4.2.1", From 9eaa7cde0ada6c795b327bc94667607c777284d5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 23 Nov 2021 00:19:00 -0500 Subject: [PATCH 298/334] build: eslint-plugin-promise@5.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9100ff0a..fd892479 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "eslint-plugin-import": "2.25.3", "eslint-plugin-markdown": "1.0.2", "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "4.2.1", + "eslint-plugin-promise": "5.1.1", "eslint-plugin-standard": "4.0.2", "istanbul": "0.4.5", "mocha": "9.1.3", From be1bcc9101b0cc7604434a70291ac66392f147de Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 23 Nov 2021 00:22:00 -0500 Subject: [PATCH 299/334] build: eslint-plugin-markdown@2.2.1 --- .eslintrc.yml | 9 ++++++++- README.md | 2 -- package.json | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index c6a7986c..e4f03fba 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,4 +1,11 @@ root: true -extends: standard +extends: + - standard + - plugin:markdown/recommended +plugins: + - markdown +overrides: + - files: '**/*.md' + processor: 'markdown/markdown' rules: no-param-reassign: error diff --git a/README.md b/README.md index f878e2ef..bcba3106 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,6 @@ $ npm install send ## API - - ```js var send = require('send') ``` diff --git a/package.json b/package.json index fd892479..3f806234 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "eslint": "7.32.0", "eslint-config-standard": "14.1.1", "eslint-plugin-import": "2.25.3", - "eslint-plugin-markdown": "1.0.2", + "eslint-plugin-markdown": "2.2.1", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.1.1", "eslint-plugin-standard": "4.0.2", @@ -53,7 +53,7 @@ "node": ">= 0.8.0" }, "scripts": { - "lint": "eslint --plugin markdown --ext js,md .", + "lint": "eslint .", "test": "mocha --check-leaks --reporter spec --bail", "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot" From 24eed69d53fb16541bdb6646eb731796abaf1566 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Dec 2021 20:41:00 -0500 Subject: [PATCH 300/334] deps: ms@2.1.3 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index d4606b5a..6123f589 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,7 @@ unreleased - deps: inherits@2.0.4 - deps: toidentifier@1.0.1 - deps: setprototypeof@1.2.0 + * deps: ms@2.1.3 0.17.1 / 2019-05-10 =================== diff --git a/package.json b/package.json index 3f806234..c1784721 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "fresh": "0.5.2", "http-errors": "~1.8.1", "mime": "1.6.0", - "ms": "2.1.1", + "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" From d2db75bb8096cec1ee5025df5c2e2d395125ef6d Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Dec 2021 20:46:00 -0500 Subject: [PATCH 301/334] build: supertest@6.1.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c1784721..fb8318d9 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "eslint-plugin-standard": "4.0.2", "istanbul": "0.4.5", "mocha": "9.1.3", - "supertest": "6.0.1" + "supertest": "6.1.6" }, "files": [ "HISTORY.md", From 441c67c54110ed2bdf01b6ea95a97e8adcd1da77 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Dec 2021 20:52:00 -0500 Subject: [PATCH 302/334] build: support Node.js 17.x --- .github/workflows/ci.yml | 3 +++ appveyor.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e96ed44..cd44a8b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -100,6 +100,9 @@ jobs: - name: Node.js 16.x node-version: "16.13" + - name: Node.js 17.x + node-version: "17.2" + steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 8ac03019..c08539a7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,6 +18,7 @@ environment: - nodejs_version: "14.18" - nodejs_version: "15.14" - nodejs_version: "16.13" + - nodejs_version: "17.2" cache: - node_modules install: From 03571b72b233d1c76a4ef3c500b40b4ca452cbe9 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Thu, 9 Dec 2021 20:54:00 -0500 Subject: [PATCH 303/334] build: eslint-plugin-standard@4.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb8318d9..5dec9933 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "eslint-plugin-markdown": "2.2.1", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.1.1", - "eslint-plugin-standard": "4.0.2", + "eslint-plugin-standard": "4.1.0", "istanbul": "0.4.5", "mocha": "9.1.3", "supertest": "6.1.6" From ea40e673d6122918162a8ffec04f11860ff3cced Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Dec 2021 19:48:44 -0500 Subject: [PATCH 304/334] build: eslint-plugin-promise@5.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5dec9933..afda1927 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "eslint-plugin-import": "2.25.3", "eslint-plugin-markdown": "2.2.1", "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "5.1.1", + "eslint-plugin-promise": "5.2.0", "eslint-plugin-standard": "4.1.0", "istanbul": "0.4.5", "mocha": "9.1.3", From 3538251237e9e7c5c5d6752623167f31d84a4e4a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 10 Dec 2021 19:53:10 -0500 Subject: [PATCH 305/334] build: use nyc for coverage testing --- .github/workflows/ci.yml | 24 ++++++++++++------------ .gitignore | 1 + appveyor.yml | 2 +- package.json | 6 +++--- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd44a8b5..6f80ad33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,43 +31,43 @@ jobs: - name: Node.js 0.8 node-version: "0.8" npm-i: mocha@2.5.3 supertest@1.1.0 - npm-rm: istanbul + npm-rm: nyc - name: Node.js 0.10 node-version: "0.10" - npm-i: mocha@3.5.3 supertest@2.0.0 + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 - name: Node.js 0.12 node-version: "0.12" - npm-i: mocha@3.5.3 supertest@2.0.0 + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 - name: io.js 1.x node-version: "1.8" - npm-i: mocha@3.5.3 supertest@2.0.0 + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 - name: io.js 2.x node-version: "2.5" - npm-i: mocha@3.5.3 supertest@2.0.0 + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 - name: io.js 3.x node-version: "3.3" - npm-i: mocha@3.5.3 supertest@2.0.0 + npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 - name: Node.js 4.x node-version: "4.9" - npm-i: mocha@5.2.0 supertest@3.4.2 + npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2 - name: Node.js 5.x node-version: "5.12" - npm-i: mocha@5.2.0 supertest@3.4.2 + npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2 - name: Node.js 6.x node-version: "6.17" - npm-i: mocha@6.2.3 + npm-i: mocha@6.2.3 nyc@14.1.1 - name: Node.js 7.x node-version: "7.10" - npm-i: mocha@6.2.3 + npm-i: mocha@6.2.3 nyc@14.1.1 - name: Node.js 8.x node-version: "8.16" @@ -156,7 +156,7 @@ jobs: - name: Run tests shell: bash run: | - if npm -ps ls istanbul | grep -q istanbul; then + if npm -ps ls nyc | grep -q nyc; then npm run test-ci else npm test @@ -168,7 +168,7 @@ jobs: - name: Collect code coverage uses: coverallsapp/github-action@master - if: steps.list_env.outputs.istanbul != '' + if: steps.list_env.outputs.nyc != '' with: github-token: ${{ secrets.GITHUB_TOKEN }} flag-name: run-${{ matrix.test_number }} diff --git a/.gitignore b/.gitignore index 0fa6951f..f15b98e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.nyc_output/ coverage/ node_modules/ npm-debug.log diff --git a/appveyor.yml b/appveyor.yml index c08539a7..d577cca4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,7 +33,7 @@ install: # Remove all non-test dependencies - ps: | # Remove coverage dependency - npm rm --silent --save-dev istanbul + npm rm --silent --save-dev nyc # Remove lint dependencies cmd.exe /c "node -pe `"Object.keys(require('./package').devDependencies).join('\n')`"" | ` sls "^eslint(-|$)" | ` diff --git a/package.json b/package.json index afda1927..edf1eb5a 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,8 @@ "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.2.0", "eslint-plugin-standard": "4.1.0", - "istanbul": "0.4.5", "mocha": "9.1.3", + "nyc": "15.1.0", "supertest": "6.1.6" }, "files": [ @@ -55,7 +55,7 @@ "scripts": { "lint": "eslint .", "test": "mocha --check-leaks --reporter spec --bail", - "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot" + "test-ci": "nyc --reporter=lcov --reporter=text npm test", + "test-cov": "nyc --reporter=html --reporter=text npm test" } } From 57a6f6c2f10f5364b26bf5aa338d59ed21cf1cf8 Mon Sep 17 00:00:00 2001 From: Demian Dekoninck Date: Sat, 2 May 2020 14:08:55 +0200 Subject: [PATCH 306/334] docs: fix typo in readme closes #193 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bcba3106..fc1d3a14 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ This is skipped if the requested file already has an extension. ##### immutable -Enable or diable the `immutable` directive in the `Cache-Control` response +Enable or disable the `immutable` directive in the `Cache-Control` response header, defaults to `false`. If set to `true`, the `maxAge` option should also be specified to enable caching. The `immutable` directive will prevent supported clients from making conditional requests during the life of the From aeb69c607bd01be2009c1ec822dab36151544421 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 11 Dec 2021 02:53:49 -0500 Subject: [PATCH 307/334] pref: ignore empty http tokens --- HISTORY.md | 1 + index.js | 8 ++++++-- test/send.js | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 6123f589..a3bade6d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * pref: ignore empty http tokens * deps: http-errors@~1.8.1 - deps: inherits@2.0.4 - deps: toidentifier@1.0.1 diff --git a/index.js b/index.js index 76bc44e9..06d75075 100644 --- a/index.js +++ b/index.js @@ -1096,7 +1096,9 @@ function parseTokenList (str) { } break case 0x2c: /* , */ - list.push(str.substring(start, end)) + if (start !== end) { + list.push(str.substring(start, end)) + } start = end = i + 1 break default: @@ -1106,7 +1108,9 @@ function parseTokenList (str) { } // final token - list.push(str.substring(start, end)) + if (start !== end) { + list.push(str.substring(start, end)) + } return list } diff --git a/test/send.js b/test/send.js index 8b27261f..4daacfa4 100644 --- a/test/send.js +++ b/test/send.js @@ -451,7 +451,7 @@ describe('send(file).pipe(res)', function () { it('should respond with 412 when ETag unmatched', function (done) { request(app) .get('/name.txt') - .set('If-Match', ' "foo", "bar" ') + .set('If-Match', ' "foo",, "bar" ,') .expect(412, done) }) From 8f61fa24e499804c29bf1af7ec62082b9e1469ce Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 11 Dec 2021 03:48:08 -0500 Subject: [PATCH 308/334] deps: http-errors@1.8.1 --- HISTORY.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index a3bade6d..05f89f92 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,7 +2,7 @@ unreleased ========== * pref: ignore empty http tokens - * deps: http-errors@~1.8.1 + * deps: http-errors@1.8.1 - deps: inherits@2.0.4 - deps: toidentifier@1.0.1 - deps: setprototypeof@1.2.0 diff --git a/package.json b/package.json index edf1eb5a..e125ba21 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.8.1", + "http-errors": "1.8.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.3.0", From 0b7bd4b4db3d95c86674b3fb5186248c85ae5d9b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 11 Dec 2021 18:35:45 -0500 Subject: [PATCH 309/334] 0.17.2 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 05f89f92..8aa3ab34 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.17.2 / 2021-12-11 +=================== * pref: ignore empty http tokens * deps: http-errors@1.8.1 diff --git a/package.json b/package.json index e125ba21..f58140cb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.17.1", + "version": "0.17.2", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ", From 175bd7db07e9e45c492ac143c786d343f1fbe1bb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 29 Dec 2021 20:31:35 -0500 Subject: [PATCH 310/334] build: fix run names in Github Actions --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f80ad33..b0745b55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,10 @@ jobs: - Node.js 11.x - Node.js 12.x - Node.js 13.x + - Node.js 14.x + - Node.js 15.x + - Node.js 16.x + - Node.js 17.x include: - name: Node.js 0.8 From ab8aaf2d61c15c86b0698d0735f7b23780cc83f1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 24 Jan 2022 19:33:58 -0500 Subject: [PATCH 311/334] build: Node.js@17.4 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0745b55..fde60286 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: node-version: "16.13" - name: Node.js 17.x - node-version: "17.2" + node-version: "17.4" steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index d577cca4..e27c256d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,7 @@ environment: - nodejs_version: "14.18" - nodejs_version: "15.14" - nodejs_version: "16.13" - - nodejs_version: "17.2" + - nodejs_version: "17.4" cache: - node_modules install: From 2fd0b0e8d1e92542699563b4909d10ab3ea747da Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 24 Jan 2022 19:39:53 -0500 Subject: [PATCH 312/334] build: eslint-plugin-import@2.25.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f58140cb..80d4dfd7 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "after": "0.8.2", "eslint": "7.32.0", "eslint-config-standard": "14.1.1", - "eslint-plugin-import": "2.25.3", + "eslint-plugin-import": "2.25.4", "eslint-plugin-markdown": "2.2.1", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.2.0", From 336cedfdc98e776eb7dadad648c9fefcaf8297eb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 25 Jan 2022 01:43:51 -0500 Subject: [PATCH 313/334] build: mocha@9.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 80d4dfd7..7bdb2bbb 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.2.0", "eslint-plugin-standard": "4.1.0", - "mocha": "9.1.3", + "mocha": "9.2.0", "nyc": "15.1.0", "supertest": "6.1.6" }, From 1ae51cd960ad1324da214e5a7ff4e35fd3e02baa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 26 Jan 2022 20:05:00 -0500 Subject: [PATCH 314/334] build: supertest@6.2.2 --- .github/workflows/ci.yml | 4 ++-- appveyor.yml | 3 +++ package.json | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fde60286..165a6d7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,11 +67,11 @@ jobs: - name: Node.js 6.x node-version: "6.17" - npm-i: mocha@6.2.3 nyc@14.1.1 + npm-i: mocha@6.2.3 nyc@14.1.1 supertest@6.1.6 - name: Node.js 7.x node-version: "7.10" - npm-i: mocha@6.2.3 nyc@14.1.1 + npm-i: mocha@6.2.3 nyc@14.1.1 supertest@6.1.6 - name: Node.js 8.x node-version: "8.16" diff --git a/appveyor.yml b/appveyor.yml index e27c256d..47ea17e9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -61,10 +61,13 @@ install: # supertest for http calls # - use 2.0.0 for Node.js < 4 # - use 3.4.2 for Node.js < 6 + # - use 6.1.6 for Node.js < 8 if ([int]$env:nodejs_version.split(".")[0] -lt 4) { npm install --silent --save-dev supertest@2.0.0 } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) { npm install --silent --save-dev supertest@3.4.2 + } elseif ([int]$env:nodejs_version.split(".")[0] -lt 8) { + npm install --silent --save-dev supertest@6.1.6 } # Update Node.js modules - ps: | diff --git a/package.json b/package.json index 7bdb2bbb..3c968b43 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "eslint-plugin-standard": "4.1.0", "mocha": "9.2.0", "nyc": "15.1.0", - "supertest": "6.1.6" + "supertest": "6.2.2" }, "files": [ "HISTORY.md", From 879f19d92d784b45f611ced9f045f5ea3888f450 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 28 Jan 2022 18:58:00 -0500 Subject: [PATCH 315/334] build: Node.js@14.19 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 165a6d7f..7f7527fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: node-version: "13.14" - name: Node.js 14.x - node-version: "14.18" + node-version: "14.19" - name: Node.js 15.x node-version: "15.14" diff --git a/appveyor.yml b/appveyor.yml index 47ea17e9..06133a8b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,7 @@ environment: - nodejs_version: "11.15" - nodejs_version: "12.22" - nodejs_version: "13.14" - - nodejs_version: "14.18" + - nodejs_version: "14.19" - nodejs_version: "15.14" - nodejs_version: "16.13" - nodejs_version: "17.4" From 4eaab36637db751b90202eae4fb8d02567ef3a6a Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 6 Feb 2022 22:08:00 -0500 Subject: [PATCH 316/334] deps: destroy@1.1.0 --- HISTORY.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 8aa3ab34..597559d1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * deps: destroy@1.1.0 + 0.17.2 / 2021-12-11 =================== diff --git a/package.json b/package.json index 3c968b43..47dad5af 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "dependencies": { "debug": "2.6.9", "depd": "~1.1.2", - "destroy": "~1.0.4", + "destroy": "1.1.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", From f266d738a5c8e4228e23cda107988c8d471f3547 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Feb 2022 23:51:00 -0500 Subject: [PATCH 317/334] build: Node.js@16.14 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f7527fb..0ec3f757 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: node-version: "15.14" - name: Node.js 16.x - node-version: "16.13" + node-version: "16.14" - name: Node.js 17.x node-version: "17.4" diff --git a/appveyor.yml b/appveyor.yml index 06133a8b..8be85274 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,7 @@ environment: - nodejs_version: "13.14" - nodejs_version: "14.19" - nodejs_version: "15.14" - - nodejs_version: "16.13" + - nodejs_version: "16.14" - nodejs_version: "17.4" cache: - node_modules From 5a63b710990d60f111510b7585882e85abef15f2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Feb 2022 23:54:00 -0500 Subject: [PATCH 318/334] build: Node.js@17.5 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ec3f757..3de5ea13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: node-version: "16.14" - name: Node.js 17.x - node-version: "17.4" + node-version: "17.5" steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 8be85274..08e84a50 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,7 @@ environment: - nodejs_version: "14.19" - nodejs_version: "15.14" - nodejs_version: "16.14" - - nodejs_version: "17.4" + - nodejs_version: "17.5" cache: - node_modules install: From ab2a59d874d7b3a45bd219a2fba024bc15752563 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Fri, 25 Feb 2022 21:37:00 -0500 Subject: [PATCH 319/334] build: mocha@9.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 47dad5af..ac833942 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.2.0", "eslint-plugin-standard": "4.1.0", - "mocha": "9.2.0", + "mocha": "9.2.1", "nyc": "15.1.0", "supertest": "6.2.2" }, From a966ace3714af65f9e5a873f6082193f4c8d1bef Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 26 Feb 2022 00:17:00 -0500 Subject: [PATCH 320/334] build: Node.js@17.6 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3de5ea13..9b89db3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: node-version: "16.14" - name: Node.js 17.x - node-version: "17.5" + node-version: "17.6" steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 08e84a50..5fcc2175 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,7 @@ environment: - nodejs_version: "14.19" - nodejs_version: "15.14" - nodejs_version: "16.14" - - nodejs_version: "17.5" + - nodejs_version: "17.6" cache: - node_modules install: From 53f0ab476145670a9bdd3dc722ab2fdc8d358fc6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Mar 2022 00:17:00 -0500 Subject: [PATCH 321/334] deps: destroy@1.1.1 --- HISTORY.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 597559d1..26eeedea 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,7 @@ unreleased ========== - * deps: destroy@1.1.0 + * deps: destroy@1.1.1 0.17.2 / 2021-12-11 =================== diff --git a/package.json b/package.json index ac833942..b16826c9 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "dependencies": { "debug": "2.6.9", "depd": "~1.1.2", - "destroy": "1.1.0", + "destroy": "1.1.1", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", From 24b4af2eed289aca8869d875772de725b6cacbd6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 2 Mar 2022 00:39:00 -0500 Subject: [PATCH 322/334] Fix emitted 416 error missing headers property --- HISTORY.md | 1 + index.js | 22 +++++++++++++++++++--- test/send.js | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 26eeedea..9f4665a7 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ unreleased ========== + * Fix emitted 416 error missing headers property * deps: destroy@1.1.1 0.17.2 / 2021-12-11 diff --git a/index.js b/index.js index 06d75075..eba4a375 100644 --- a/index.js +++ b/index.js @@ -267,9 +267,7 @@ SendStream.prototype.maxage = deprecate.function(function maxage (maxAge) { SendStream.prototype.error = function error (status, err) { // emit if listeners instead of responding if (hasListeners(this, 'error')) { - return this.emit('error', createError(status, err, { - expose: false - })) + return this.emit('error', createHttpError(status, err)) } var res = this.res @@ -974,6 +972,24 @@ function createHtmlDocument (title, body) { '\n' } +/** + * Create a HttpError object from simple arguments. + * + * @param {number} status + * @param {Error|object} err + * @private + */ + +function createHttpError (status, err) { + if (!err) { + return createError(status) + } + + return err instanceof Error + ? createError(status, err, { expose: false }) + : createError(status, err) +} + /** * decodeURIComponent. * diff --git a/test/send.js b/test/send.js index 4daacfa4..04a68b65 100644 --- a/test/send.js +++ b/test/send.js @@ -643,6 +643,24 @@ describe('send(file).pipe(res)', function () { .expect('Content-Range', 'bytes */9') .expect(416, done) }) + + it('should emit error 416 with content-range header', function (done) { + var server = http.createServer(function (req, res) { + send(req, req.url, { root: fixtures }) + .on('error', function (err) { + res.setHeader('X-Content-Range', err.headers['Content-Range']) + res.statusCode = err.statusCode + res.end(err.message) + }) + .pipe(res) + }) + + request(server) + .get('/nums.txt') + .set('Range', 'bytes=9-50') + .expect('X-Content-Range', 'bytes */9') + .expect(416, done) + }) }) describe('when syntactically invalid', function () { From 21f0fbbd3c3bc0250ad4938194cccc599a0bb39b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 5 Mar 2022 21:33:00 -0500 Subject: [PATCH 323/334] deps: http-errors@2.0.0 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 9f4665a7..7c7f051c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,9 @@ unreleased * Fix emitted 416 error missing headers property * deps: destroy@1.1.1 + * deps: http-errors@2.0.0 + - deps: depd@2.0.0 + - deps: statuses@2.0.1 0.17.2 / 2021-12-11 =================== diff --git a/package.json b/package.json index b16826c9..9967f8eb 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.3.0", From 1495ddae1565528636789010e66483e07d2d6620 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 5 Mar 2022 21:43:00 -0500 Subject: [PATCH 324/334] deps: depd@2.0.0 --- HISTORY.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 7c7f051c..d779d5dc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,9 @@ unreleased ========== * Fix emitted 416 error missing headers property + * deps: depd@2.0.0 + - Replace internal `eval` usage with `Function` constructor + - Use instance methods on `process` to check for listeners * deps: destroy@1.1.1 * deps: http-errors@2.0.0 - deps: depd@2.0.0 diff --git a/package.json b/package.json index 9967f8eb..8317cdb7 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ], "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "destroy": "1.1.1", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", From f3cf8a9506618e08f80bb8476366604c7f2db0c1 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 8 Mar 2022 01:21:00 -0500 Subject: [PATCH 325/334] deps: statuses@2.0.1 --- HISTORY.md | 1 + index.js | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d779d5dc..f2b24ade 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,7 @@ unreleased * deps: http-errors@2.0.0 - deps: depd@2.0.0 - deps: statuses@2.0.1 + * deps: statuses@2.0.1 0.17.2 / 2021-12-11 =================== diff --git a/index.js b/index.js index eba4a375..fbdecf38 100644 --- a/index.js +++ b/index.js @@ -271,7 +271,7 @@ SendStream.prototype.error = function error (status, err) { } var res = this.res - var msg = statuses[status] || String(status) + var msg = statuses.message[status] || String(status) var doc = createHtmlDocument('Error', escapeHtml(msg)) // clear existing headers diff --git a/package.json b/package.json index 8317cdb7..03e1626d 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "ms": "2.1.3", "on-finished": "~2.3.0", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "devDependencies": { "after": "0.8.2", From 53642192064d636964e4dbf46268dd79b7635853 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Mar 2022 23:11:00 -0400 Subject: [PATCH 326/334] build: mocha@9.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03e1626d..3e19db0f 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.2.0", "eslint-plugin-standard": "4.1.0", - "mocha": "9.2.1", + "mocha": "9.2.2", "nyc": "15.1.0", "supertest": "6.2.2" }, From 8055f787fee1a189b23a27e67dcc185dfe26bac2 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 16 Mar 2022 23:13:00 -0400 Subject: [PATCH 327/334] build: Node.js@17.7 --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b89db3b..6c5b941a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,7 +105,7 @@ jobs: node-version: "16.14" - name: Node.js 17.x - node-version: "17.6" + node-version: "17.7" steps: - uses: actions/checkout@v2 diff --git a/appveyor.yml b/appveyor.yml index 5fcc2175..1332a991 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,7 @@ environment: - nodejs_version: "14.19" - nodejs_version: "15.14" - nodejs_version: "16.14" - - nodejs_version: "17.6" + - nodejs_version: "17.7" cache: - node_modules install: From 6060bdaf1a8684deec45704ad4e4b163d910f6fa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sat, 19 Mar 2022 23:11:00 -0400 Subject: [PATCH 328/334] deps: on-finished@2.4.1 --- HISTORY.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index f2b24ade..37b0d3a2 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,7 @@ unreleased * deps: http-errors@2.0.0 - deps: depd@2.0.0 - deps: statuses@2.0.1 + * deps: on-finished@2.4.1 * deps: statuses@2.0.1 0.17.2 / 2021-12-11 diff --git a/package.json b/package.json index 3e19db0f..0a2bab39 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" }, From aee1a657be9fdf558ce3448c6a908227e15f0645 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 20 Mar 2022 22:35:28 -0400 Subject: [PATCH 329/334] deps: destroy@1.2.0 --- HISTORY.md | 2 +- index.js | 24 ++++++++++-------------- package.json | 2 +- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 37b0d3a2..581fa892 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,7 +5,7 @@ unreleased * deps: depd@2.0.0 - Replace internal `eval` usage with `Function` constructor - Use instance methods on `process` to check for listeners - * deps: destroy@1.1.1 + * deps: destroy@1.2.0 * deps: http-errors@2.0.0 - deps: depd@2.0.0 - deps: statuses@2.0.1 diff --git a/index.js b/index.js index fbdecf38..5ba20d9e 100644 --- a/index.js +++ b/index.js @@ -785,8 +785,6 @@ SendStream.prototype.sendIndex = function sendIndex (path) { */ SendStream.prototype.stream = function stream (path, options) { - // TODO: this is all lame, refactor meeee - var finished = false var self = this var res = this.res @@ -795,20 +793,18 @@ SendStream.prototype.stream = function stream (path, options) { this.emit('stream', stream) stream.pipe(res) - // response finished, done with the fd - onFinished(res, function onfinished () { - finished = true - destroy(stream) - }) + // cleanup + function cleanup () { + destroy(stream, true) + } - // error handling code-smell - stream.on('error', function onerror (err) { - // request already finished - if (finished) return + // response finished, cleanup + onFinished(res, cleanup) - // clean up stream - finished = true - destroy(stream) + // error handling + stream.on('error', function onerror (err) { + // clean up stream early + cleanup() // error self.onStatError(err) diff --git a/package.json b/package.json index 0a2bab39..98d1a751 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "dependencies": { "debug": "2.6.9", "depd": "2.0.0", - "destroy": "1.1.1", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", From fed09ff7dd5b24470fadaa6626b5db1667cccec6 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 20 Mar 2022 22:36:02 -0400 Subject: [PATCH 330/334] docs: update copyright --- LICENSE | 2 +- index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 4aa69e83..b6ea1c1f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ (The MIT License) Copyright (c) 2012 TJ Holowaychuk -Copyright (c) 2014-2016 Douglas Christopher Wilson +Copyright (c) 2014-2022 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/index.js b/index.js index 5ba20d9e..e0441da0 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ /*! * send * Copyright(c) 2012 TJ Holowaychuk - * Copyright(c) 2014-2016 Douglas Christopher Wilson + * Copyright(c) 2014-2022 Douglas Christopher Wilson * MIT Licensed */ From b690ba4bd149d20fa6687ee6298fb6aede5b21d7 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 20 Mar 2022 22:47:39 -0400 Subject: [PATCH 331/334] docs: fix linux build badge link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc1d3a14..fadf8383 100644 --- a/README.md +++ b/README.md @@ -318,8 +318,8 @@ server.listen(3000) [appveyor-url]: https://ci.appveyor.com/project/dougwilson/send [coveralls-image]: https://badgen.net/coveralls/c/github/pillarjs/send/master [coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master -[github-actions-ci-image]: https://badgen.net/github/checks/pillarjs/send/master?label=ci -[github-actions-ci-url]: https://github.com/pillarjs/send/actions?query=workflow%3Aci +[github-actions-ci-image]: https://badgen.net/github/checks/pillarjs/send/master?label=linux +[github-actions-ci-url]: https://github.com/pillarjs/send/actions/workflows/ci.yml [node-image]: https://badgen.net/npm/node/send [node-url]: https://nodejs.org/en/download/ [npm-downloads-image]: https://badgen.net/npm/dm/send From 706d6ddf0d3c8a9248fc1edbc3ff60bbc6ad7b93 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 20 Mar 2022 23:07:27 -0400 Subject: [PATCH 332/334] docs: add security policy --- SECURITY.md | 24 ++++++++++++++++++++++++ package.json | 1 + 2 files changed, 25 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..46b48f7b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,24 @@ +# Security Policies and Procedures + +## Reporting a Bug + +The `send` team and community take all security bugs seriously. Thank you +for improving the security of Express. We appreciate your efforts and +responsible disclosure and will make every effort to acknowledge your +contributions. + +Report security bugs by emailing the current owner(s) of `send`. This information +can be found in the npm registry using the command `npm owner ls send`. +If unsure or unable to get the information from the above, open an issue +in the [project issue tracker](https://github.com/pillarjs/send/issues) +asking for the current contact information. + +To ensure the timely response to your report, please ensure that the entirety +of the report is contained within the email body and not solely behind a web +link or an attachment. + +At least one owner will acknowledge your email within 48 hours, and will send a +more detailed response within 48 hours indicating the next steps in handling +your report. After the initial reply to your report, the owners will +endeavor to keep you informed of the progress towards a fix and full +announcement, and may ask for additional information or guidance. diff --git a/package.json b/package.json index 98d1a751..124f111c 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "HISTORY.md", "LICENSE", "README.md", + "SECURITY.md", "index.js" ], "engines": { From f53edbb7f4f7ebdd936d3d714d84d52f2d3d00f3 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Sun, 20 Mar 2022 23:43:48 -0400 Subject: [PATCH 333/334] Limit the headers removed for 304 response closes #204 --- HISTORY.md | 1 + index.js | 14 ++++++-------- test/send.js | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 581fa892..9fd925fe 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,7 @@ unreleased ========== * Fix emitted 416 error missing headers property + * Limit the headers removed for 304 response * deps: depd@2.0.0 - Replace internal `eval` usage with `Function` constructor - Use instance methods on `process` to check for listeners diff --git a/index.js b/index.js index e0441da0..89afd7e5 100644 --- a/index.js +++ b/index.js @@ -347,21 +347,19 @@ SendStream.prototype.isPreconditionFailure = function isPreconditionFailure () { } /** - * Strip content-* header fields. + * Strip various content header fields for a change in entity. * * @private */ SendStream.prototype.removeContentHeaderFields = function removeContentHeaderFields () { var res = this.res - var headers = getHeaderNames(res) - for (var i = 0; i < headers.length; i++) { - var header = headers[i] - if (header.substr(0, 8) === 'content-' && header !== 'content-location') { - res.removeHeader(header) - } - } + res.removeHeader('Content-Encoding') + res.removeHeader('Content-Language') + res.removeHeader('Content-Length') + res.removeHeader('Content-Range') + res.removeHeader('Content-Type') } /** diff --git a/test/send.js b/test/send.js index 04a68b65..d419f8f9 100644 --- a/test/send.js +++ b/test/send.js @@ -440,6 +440,27 @@ describe('send(file).pipe(res)', function () { }) }) + it('should not remove all Content-* headers', function (done) { + var server = createServer({ root: fixtures }, function (req, res) { + res.setHeader('Content-Location', 'http://localhost/name.txt') + res.setHeader('Content-Security-Policy', 'default-src \'self\'') + }) + + request(server) + .get('/name.txt') + .expect(200, function (err, res) { + if (err) return done(err) + request(server) + .get('/name.txt') + .set('If-None-Match', res.headers.etag) + .expect(shouldNotHaveHeader('Content-Length')) + .expect(shouldNotHaveHeader('Content-Type')) + .expect('Content-Location', 'http://localhost/name.txt') + .expect('Content-Security-Policy', 'default-src \'self\'') + .expect(304, done) + }) + }) + describe('where "If-Match" is set', function () { it('should respond with 200 when "*"', function (done) { request(app) From b69cbb3dc4c09c37917d08a4c13fcd1bac97ade5 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Wed, 23 Mar 2022 22:53:50 -0400 Subject: [PATCH 334/334] 0.18.0 --- HISTORY.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9fd925fe..a7397749 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,5 @@ -unreleased -========== +0.18.0 / 2022-03-23 +=================== * Fix emitted 416 error missing headers property * Limit the headers removed for 304 response diff --git a/package.json b/package.json index 124f111c..7f269d51 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "send", "description": "Better streaming static file server with Range and conditional-GET support", - "version": "0.17.2", + "version": "0.18.0", "author": "TJ Holowaychuk ", "contributors": [ "Douglas Christopher Wilson ",