Socket
Socket
Sign inDemoInstall

serve-static

Package Overview
Dependencies
Maintainers
6
Versions
66
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

serve-static - npm Package Compare versions

Comparing version 1.9.3 to 1.10.0

25

HISTORY.md

@@ -0,1 +1,26 @@

1.10.0 / 2015-06-17
===================
* Add `fallthrough` option
- Allows declaring this middleware is the final destination
- Provides better integration with Express patterns
* Fix reading options from options prototype
* Improve the default redirect response headers
* deps: escape-html@1.0.2
* deps: send@0.13.0
- 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
- deps: fresh@0.3.0
- deps: on-finished@~2.3.0
- perf: enable strict mode
- perf: remove unnecessary array allocations
* perf: enable strict mode
* perf: remove argument reassignment
1.9.3 / 2015-05-14

@@ -2,0 +27,0 @@ ==================

173

index.js

@@ -5,25 +5,35 @@ /*!

* Copyright(c) 2011 TJ Holowaychuk
* Copyright(c) 2014 Douglas Christopher Wilson
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var escapeHtml = require('escape-html');
var merge = require('utils-merge');
var parseurl = require('parseurl');
var resolve = require('path').resolve;
var send = require('send');
var url = require('url');
var escapeHtml = require('escape-html')
var parseUrl = require('parseurl')
var resolve = require('path').resolve
var send = require('send')
var url = require('url')
/**
* @param {String} root
* @param {Object} options
* @return {Function}
* @api public
* Module exports.
* @public
*/
exports = module.exports = function serveStatic(root, options) {
module.exports = serveStatic
module.exports.mime = send.mime
/**
* @param {string} root
* @param {object} [options]
* @return {function}
* @public
*/
function serveStatic(root, options) {
if (!root) {

@@ -38,13 +48,12 @@ throw new TypeError('root path required')

// copy options object
options = merge({}, options)
var opts = Object.create(options || null)
// resolve root to absolute
root = resolve(root)
// fall-though
var fallthrough = opts.fallthrough !== false
// default redirect
var redirect = options.redirect !== false
var redirect = opts.redirect !== false
// headers listener
var setHeaders = options.setHeaders
delete options.setHeaders
var setHeaders = opts.setHeaders

@@ -56,17 +65,30 @@ if (setHeaders && typeof setHeaders !== 'function') {

// setup options for send
options.maxage = options.maxage || options.maxAge || 0
options.root = root
opts.maxage = opts.maxage || opts.maxAge || 0
opts.root = resolve(root)
// construct directory listener
var onDirectory = redirect
? createRedirectDirectoryListener()
: createNotFoundDirectoryListener()
return function serveStatic(req, res, next) {
if (req.method !== 'GET' && req.method !== 'HEAD') {
return next()
if (fallthrough) {
return next()
}
// method not allowed
res.statusCode = 405
res.setHeader('Allow', 'GET, HEAD')
res.setHeader('Content-Length', '0')
res.end()
return
}
var opts = merge({}, options)
var originalUrl = parseurl.original(req)
var path = parseurl(req).pathname
var hasTrailingSlash = originalUrl.pathname[originalUrl.pathname.length - 1] === '/'
var forwardError = !fallthrough
var originalUrl = parseUrl.original(req)
var path = parseUrl(req).pathname
if (path === '/' && !hasTrailingSlash) {
// make sure redirect occurs at mount
// make sure redirect occurs at mount
if (path === '/' && originalUrl.pathname.substr(-1) !== '/') {
path = ''

@@ -78,27 +100,5 @@ }

if (redirect) {
// redirect relative to originalUrl
stream.on('directory', function redirect() {
if (hasTrailingSlash) {
return next()
}
// add directory handler
stream.on('directory', onDirectory)
// append trailing slash
originalUrl.path = null
originalUrl.pathname = collapseLeadingSlashes(originalUrl.pathname + '/')
// reformat the URL
var target = url.format(originalUrl)
// send redirect response
res.statusCode = 303
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.setHeader('Location', target)
res.end('Redirecting to <a href="' + escapeHtml(target) + '">' + escapeHtml(target) + '</a>\n')
})
} else {
// forward to next middleware on directory
stream.on('directory', next)
}
// add headers listener

@@ -109,5 +109,18 @@ if (setHeaders) {

// forward non-404 errors
// add file listener for fallthrough
if (fallthrough) {
stream.on('file', function onFile() {
// once file is determined, always forward error
forwardError = true
})
}
// forward errors
stream.on('error', function error(err) {
next(err.status === 404 ? null : err)
if (forwardError || !(err.statusCode < 500)) {
next(err)
return
}
next()
})

@@ -121,11 +134,2 @@

/**
* Expose mime module.
*
* If you wish to extend the mime table use this
* reference to the "mime" module in the npm registry.
*/
exports.mime = send.mime
/**
* Collapse all leading slashes into a single slash

@@ -145,1 +149,46 @@ * @private

}
/**
* Create a directory listener that just 404s.
* @private
*/
function createNotFoundDirectoryListener() {
return function notFound() {
this.error(404)
}
}
/**
* Create a directory listener that performs a redirect.
* @private
*/
function createRedirectDirectoryListener() {
return function redirect() {
if (this.hasTrailingSlash()) {
this.error(404)
return
}
// get original URL
var originalUrl = parseUrl.original(this.req)
// append trailing slash
originalUrl.path = null
originalUrl.pathname = collapseLeadingSlashes(originalUrl.pathname + '/')
// reformat the URL
var loc = url.format(originalUrl)
var msg = 'Redirecting to <a href="' + escapeHtml(loc) + '">' + escapeHtml(loc) + '</a>\n'
var res = this.res
// send redirect response
res.statusCode = 303
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)
}
}
{
"name": "serve-static",
"description": "Serve static files",
"version": "1.9.3",
"version": "1.10.0",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",

@@ -9,6 +9,5 @@ "license": "MIT",

"dependencies": {
"escape-html": "1.0.1",
"escape-html": "1.0.2",
"parseurl": "~1.3.0",
"send": "0.12.3",
"utils-merge": "1.0.0"
"send": "0.13.0"
},

@@ -15,0 +14,0 @@ "devDependencies": {

@@ -44,4 +44,4 @@ # serve-static

- `'allow'` No special treatment for dotfiles.
- `'deny'` Send a 403 for any request for a dotfile.
- `'ignore'` Pretend like the dotfile does not exist and call `next()`.
- `'deny'` Deny a request for a dotfile and 403/`next()`.
- `'ignore'` Pretend like the dotfile does not exist and 404/`next()`.

@@ -60,2 +60,21 @@ ##### etag

##### fallthrough
Set the middleware to have client errors fall-through as just unhandled
requests, otherwise forward a client error. The difference is that client
errors like a bad request or a request to a non-existent file will cause
this middleware to simply `next()` to your next middleware when this value
is `true`. When this value is `false`, these errors (even 404s), will invoke
`next(err)`.
Typically `true` is desired such that multiple physical directories can be
mapped to the same web address or for routes to fill in non-existent files.
The value `false` can be used if this middleware is mounted at a path that
is designed to be strictly a single file system directory, which allows for
short-circuiting 404s for less overhead. This middleware will also reply to
all methods.
The default value is `true`.
##### index

@@ -62,0 +81,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc