send
Advanced tools
Comparing version 0.12.3 to 0.13.0
@@ -0,1 +1,22 @@ | ||
0.13.0 / 2015-06-16 | ||
=================== | ||
* 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 | ||
* 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 | ||
* 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 | ||
* perf: remove unnecessary array allocations | ||
0.12.3 / 2015-05-13 | ||
@@ -2,0 +23,0 @@ =================== |
137
index.js
@@ -8,6 +8,10 @@ /*! | ||
'use strict' | ||
/** | ||
* Module dependencies. | ||
* @private | ||
*/ | ||
var createError = require('http-errors') | ||
var debug = require('debug')('send') | ||
@@ -22,3 +26,2 @@ var deprecate = require('depd')('send') | ||
, path = require('path') | ||
, http = require('http') | ||
, fs = require('fs') | ||
@@ -31,2 +34,3 @@ , normalize = path.normalize | ||
var onFinished = require('on-finished') | ||
var statuses = require('statuses') | ||
@@ -44,14 +48,10 @@ /** | ||
/** | ||
* Expose `send`. | ||
* Module exports. | ||
* @public | ||
*/ | ||
exports = module.exports = send; | ||
module.exports = send | ||
module.exports.mime = mime | ||
/** | ||
* Expose mime module. | ||
*/ | ||
exports.mime = mime; | ||
/** | ||
* Shim EventEmitter.listenerCount for node.js < 0.10 | ||
@@ -67,7 +67,7 @@ */ | ||
* | ||
* @param {Request} req | ||
* @param {String} path | ||
* @param {object} req | ||
* @param {string} path | ||
* @param {object} [options] | ||
* @return {SendStream} | ||
* @api public | ||
* @public | ||
*/ | ||
@@ -85,3 +85,3 @@ | ||
* @param {object} [options] | ||
* @api private | ||
* @private | ||
*/ | ||
@@ -104,3 +104,3 @@ | ||
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"') | ||
@@ -244,24 +244,28 @@ } | ||
* | ||
* @param {Number} status | ||
* @api private | ||
* @param {number} status | ||
* @param {Error} [error] | ||
* @private | ||
*/ | ||
SendStream.prototype.error = function(status, err){ | ||
var res = this.res; | ||
var msg = http.STATUS_CODES[status]; | ||
err = err || new Error(msg); | ||
err.status = status; | ||
SendStream.prototype.error = function error(status, error) { | ||
// 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 = null | ||
res.statusCode = err.status; | ||
res.end(msg); | ||
}; | ||
// 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) | ||
} | ||
@@ -294,13 +298,16 @@ /** | ||
* | ||
* @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-' && header !== 'content-location') { | ||
res.removeHeader(header) | ||
} | ||
}); | ||
}; | ||
} | ||
} | ||
@@ -349,11 +356,18 @@ /** | ||
* | ||
* @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 | ||
} | ||
} | ||
@@ -389,22 +403,32 @@ /** | ||
/** | ||
* 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 <a href="' + escapeHtml(path) + '">' + escapeHtml(path) + '</a>\n'); | ||
}; | ||
if (this.hasTrailingSlash()) { | ||
this.error(403) | ||
return | ||
} | ||
var loc = path + '/' | ||
var msg = 'Redirecting to <a href="' + escapeHtml(loc) + '">' + escapeHtml(loc) + '</a>\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) | ||
} | ||
/** | ||
@@ -740,3 +764,2 @@ * Pipe to `res. | ||
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)); | ||
@@ -743,0 +766,0 @@ |
{ | ||
"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 <tj@vision-media.ca>", | ||
@@ -20,9 +20,11 @@ "contributors": [ | ||
"destroy": "1.0.3", | ||
"escape-html": "1.0.1", | ||
"etag": "~1.6.0", | ||
"fresh": "0.2.4", | ||
"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.2.1", | ||
"range-parser": "~1.0.2" | ||
"on-finished": "~2.3.0", | ||
"range-parser": "~1.0.2", | ||
"statuses": "~1.2.1" | ||
}, | ||
@@ -32,4 +34,4 @@ "devDependencies": { | ||
"istanbul": "0.3.9", | ||
"mocha": "2.2.4", | ||
"supertest": "~0.15.0" | ||
"mocha": "2.2.5", | ||
"supertest": "1.0.1" | ||
}, | ||
@@ -36,0 +38,0 @@ "files": [ |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
32129
681
12
+ Addedhttp-errors@~1.3.1
+ Addedstatuses@~1.2.1
+ Addedee-first@1.1.1(transitive)
+ Addedescape-html@1.0.2(transitive)
+ Addedetag@1.7.0(transitive)
+ Addedfresh@0.3.0(transitive)
+ Addedhttp-errors@1.3.1(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedon-finished@2.3.0(transitive)
+ Addedstatuses@1.2.1(transitive)
- Removedcrc@3.2.1(transitive)
- Removedee-first@1.1.0(transitive)
- Removedescape-html@1.0.1(transitive)
- Removedetag@1.6.0(transitive)
- Removedfresh@0.2.4(transitive)
- Removedon-finished@2.2.1(transitive)
Updatedescape-html@1.0.2
Updatedetag@~1.7.0
Updatedfresh@0.3.0
Updatedon-finished@~2.3.0