Comparing version 1.3.1 to 2.0.0
55
index.js
@@ -6,2 +6,3 @@ /** | ||
var debug = require('debug')('koa-send'); | ||
var resolvePath = require('resolve-path'); | ||
var assert = require('assert'); | ||
@@ -14,3 +15,2 @@ var path = require('path'); | ||
var fs = require('mz/fs'); | ||
var join = path.join; | ||
@@ -42,5 +42,7 @@ /** | ||
var root = opts.root ? normalize(resolve(opts.root)) : ''; | ||
path = path[0] == '/' ? path.slice(1) : path; | ||
var index = opts.index; | ||
var maxage = opts.maxage || opts.maxAge || 0; | ||
var hidden = opts.hidden || false; | ||
var gzip = opts.gzip || opts.gzip === undefined ? true : false; | ||
@@ -56,23 +58,12 @@ return function *(){ | ||
// null byte(s) | ||
if (~path.indexOf('\0')) return ctx.throw('null bytes', 400); | ||
// index file support | ||
if (index && trailingSlash) path += index; | ||
// malicious path | ||
if (!root && !isAbsolute(path)) return ctx.throw('relative paths require the .root option', 500); | ||
if (!root && ~path.indexOf('..')) return ctx.throw('malicious path', 400); | ||
path = resolvePath(root, path); | ||
// relative to root | ||
path = normalize(join(root, path)); | ||
// out of bounds | ||
if (root && 0 !== path.indexOf(root)) return ctx.throw('malicious path', 400); | ||
// hidden file support, ignore | ||
if (!hidden && leadingDot(path)) return; | ||
if (!hidden && isHidden(root, path)) return; | ||
// serve gzipped file when possible | ||
if (encoding === 'gzip' && (yield fs.exists(path + '.gz'))) { | ||
if (encoding === 'gzip' && gzip && (yield fs.exists(path + '.gz'))) { | ||
path = path + '.gz'; | ||
@@ -86,3 +77,13 @@ ctx.set('Content-Encoding', 'gzip'); | ||
var stats = yield fs.stat(path); | ||
if (stats.isDirectory()) return; | ||
// Format the path to serve static file servers | ||
// and not require a trailing slash for directories, | ||
// so that you can do both `/directory` and `/directory/` | ||
if (stats.isDirectory()) { | ||
if (opts.format) { | ||
path += '/' + index; | ||
} else { | ||
return; | ||
} | ||
} | ||
} catch (err) { | ||
@@ -110,4 +111,8 @@ var notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR']; | ||
function leadingDot(path) { | ||
return '.' == basename(path)[0]; | ||
function isHidden(root, path) { | ||
path = path.substr(root.length).split('/'); | ||
for(var i = 0; i < path.length; i++) { | ||
if(path[i][0] === '.') return true; | ||
} | ||
return false; | ||
} | ||
@@ -134,15 +139,1 @@ | ||
} | ||
/** | ||
* Check if `path` looks absolute. | ||
* | ||
* @param {String} path | ||
* @return {Boolean} | ||
* @api private | ||
*/ | ||
function isAbsolute(path){ | ||
if ('/' == path[0]) return true; | ||
if (':' == path[1] && '\\' == path[2]) return true; | ||
if ('\\\\' == path.substring(0, 2)) return true; // Microsoft Azure absolute path | ||
} |
@@ -5,3 +5,3 @@ { | ||
"repository": "koajs/send", | ||
"version": "1.3.1", | ||
"version": "2.0.0", | ||
"keywords": [ | ||
@@ -17,7 +17,7 @@ "koa", | ||
"devDependencies": { | ||
"koa": "*", | ||
"istanbul-harmony": "0", | ||
"koa": "1", | ||
"mocha": "^2.3.3", | ||
"should": "3", | ||
"mocha": "1", | ||
"supertest": "0", | ||
"istanbul-harmony": "0" | ||
"supertest": "0" | ||
}, | ||
@@ -27,9 +27,10 @@ "license": "MIT", | ||
"debug": "*", | ||
"mz": "^1.0.1" | ||
"mz": "^2.0.0", | ||
"resolve-path": "^1.2.1" | ||
}, | ||
"scripts": { | ||
"test": "mocha --harmony-generators --require should --reporter spec", | ||
"test-cov": "node --harmony-generators ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --require should", | ||
"test-travis": "node --harmony-generators ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- --require should" | ||
"test": "mocha --require should --reporter spec", | ||
"test-cov": "node ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --require should", | ||
"test-travis": "node ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- --require should" | ||
} | ||
} |
@@ -24,9 +24,10 @@ | ||
- `root` Root directory to restrict file access | ||
- `gzip` Try to serve the gzipped version of a file automatically when `gzip` is supported by a client and if the requested file with `.gz` extension exists. defaults to true. | ||
- `format` If true, format the path to serve static file servers and not require a trailing slash for directories, so that you can do both `/directory` and `/directory/` | ||
Note that the module will try to serve the gzipped version of a file automatically when `gzip` is supported by a client and if the requested file with `.gz` extension exists. | ||
## Root path | ||
Note that when `root` is _not_ used you __MUST__ provide an _absolute_ | ||
path, and this path must not contain "..", protecting developers from | ||
Note that `root` is required, defaults to `''` and will be resolved, | ||
removing the leading `/` to make the path relative and this | ||
path must not contain "..", protecting developers from | ||
concatenating user input. If you plan on serving files based on | ||
@@ -33,0 +34,0 @@ user input supply a `root` directory from which to serve from. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7836
4
90
3
109
1
+ Addedresolve-path@^1.2.1
+ Addeddepd@1.1.2(transitive)
+ Addedhttp-errors@1.6.3(transitive)
+ Addedinherits@2.0.3(transitive)
+ Addedmz@2.7.0(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedresolve-path@1.4.0(transitive)
+ Addedsetprototypeof@1.1.0(transitive)
+ Addedstatuses@1.5.0(transitive)
- Removedmz@1.3.0(transitive)
- Removednative-or-bluebird@1.2.0(transitive)
Updatedmz@^2.0.0