Skip to content

Commit

Permalink
Merge tag '0.18.0' into 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wesleytodd committed Mar 21, 2024
2 parents 00d54b6 + b69cbb3 commit b5e395c
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 45 deletions.
14 changes: 9 additions & 5 deletions .github/workflows/ci.yml
Expand Up @@ -25,6 +25,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.10
Expand Down Expand Up @@ -57,11 +61,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"
Expand All @@ -86,16 +90,16 @@ 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"

- name: Node.js 16.x
node-version: "16.13"
node-version: "16.14"

- name: Node.js 17.x
node-version: "17.2"
node-version: "17.7"

steps:
- uses: actions/checkout@v2
Expand Down
15 changes: 15 additions & 0 deletions HISTORY.md
Expand Up @@ -16,6 +16,21 @@
- Remove `DEBUG_FD` environment variable support
- Support 256 namespace colors

0.18.0 / 2022-03-23
===================

* 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
* deps: destroy@1.2.0
* 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
===================

Expand Down
2 changes: 1 addition & 1 deletion 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
Expand Down
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -311,8 +311,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
Expand Down
24 changes: 24 additions & 0 deletions 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.
9 changes: 6 additions & 3 deletions appveyor.yml
Expand Up @@ -15,10 +15,10 @@ 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.2"
- nodejs_version: "16.14"
- nodejs_version: "17.7"
cache:
- node_modules
install:
Expand Down Expand Up @@ -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: |
Expand Down
64 changes: 37 additions & 27 deletions 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
*/

Expand Down Expand Up @@ -166,13 +166,11 @@ util.inherits(SendStream, Stream)
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
var msg = statuses[status] || String(status)
var msg = statuses.message[status] || String(status)
var doc = createHtmlDocument('Error', escapeHtml(msg))

// clear existing headers
Expand Down Expand Up @@ -248,21 +246,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')
}

/**
Expand Down Expand Up @@ -677,8 +673,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

Expand All @@ -687,20 +681,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)
Expand Down Expand Up @@ -858,6 +850,24 @@ function createHtmlDocument (title, body) {
'</html>\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.
*
Expand Down
15 changes: 8 additions & 7 deletions package.json
Expand Up @@ -17,35 +17,36 @@
],
"dependencies": {
"debug": "3.1.0",
"destroy": "~1.0.4",
"destroy": "1.2.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "1.8.1",
"http-errors": "2.0.0",
"mime-types": "~2.1.34",
"ms": "2.1.3",
"on-finished": "~2.3.0",
"on-finished": "2.4.1",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
"statuses": "2.0.1"
},
"devDependencies": {
"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",
"eslint-plugin-standard": "4.1.0",
"mocha": "9.1.3",
"mocha": "9.2.2",
"nyc": "15.1.0",
"supertest": "6.1.6"
"supertest": "6.2.2"
},
"files": [
"HISTORY.md",
"LICENSE",
"README.md",
"SECURITY.md",
"index.js"
],
"engines": {
Expand Down
39 changes: 39 additions & 0 deletions test/send.js
Expand Up @@ -447,6 +447,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)
Expand Down Expand Up @@ -650,6 +671,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 () {
Expand Down

0 comments on commit b5e395c

Please sign in to comment.