Skip to content

express-mime-sniff is a package for setting HTTP `Content-Type` headers for files by utilizing a *nix `file` program available on your system.

License

Notifications You must be signed in to change notification settings

dotnetCarpenter/express-mime-sniff

Repository files navigation

express-mime-sniff

Github CI

express-mime-sniff is an express middleware for setting HTTP Content-Type headers for files by utilizing a *nix file program available on your system. express-mime-sniff is meant to be used together and before express.static.

This approach is independent of file extension, unlike the default logic used by express.static and should therefore yield better results.

$ npm install express-mime-sniff --production --save

express-mime-sniff should be considered alpha at this point.

express-mime-sniff uses sanctuary, which by default does type checking. To disable type checking, and gain performance, you must set the environment variable: NODE_ENV=production.

Benchmark

Currently, version 0.4.0 is 77% slower than using express.static.

Requests/sec: 302.4 vs Requests/sec: 68.7 ~ 77% slower.

(68.7 - 302.4) / 302.4 * 100 = -77.28

npm run benchmark

OR

  1. cd benchmark
  2. ./server.mjs
  3. In another terminal run
    1. ./benchmark-express-static
    2. ./benchmark-mime-sniff

API


middleware

The middleware will add Content-Type and 'X-Content-Type-Options': 'nosniff' HTTP headers to all requests if successful. If an error occur, middleware will write to stderr and do nothing with the request but forward it to the next middleware function. If HTTP-headers are already sent to the client in a previous middleware function, express-mime-sniff will do nothing but burn CPU cycles.

Remember to use middleware before express.static.

import express        from 'express'
import { middleware } from 'express-mime-sniff'

const app = express ()
app.use (middleware ()) // important to use middleware before express.static
app.use (express.static('.'))
app.listen (8080)

serving content from another directory

If you configure express.static to serve content from another directory than your current working directory, you need to tell the middleware. That is done in the exact same way as with express.static.

const ROOT_PATH = 'specify/the/root/directory/from/which/to/serve/static/assets'
const app = express ()

app.use (middleware (ROOT_PATH))
app.use (express.static (ROOT_PATH))
app.listen (8080)

options.filters

middleware (ROOT_PATH, { filters })

Add an array of regular expressions to filter which files express-mime-sniff should handle. The RegExp will be tested against request.path.

const ROOT_PATH = 'spec/fixtures/'
const OPTIONS = { filters: [/\.txt$/, /\.png$/] }

app = express ()
app.use (middleware (ROOT_PATH, OPTIONS))
app.use (express.static (ROOT_PATH))
app.listen (8080)

Or you can use the built-in path filter in express. Notice that express requires that the RegExp matches the entire path to the file or the wrong path will be sent to express-mime-sniff.

const ROOT_PATH = 'spec/fixtures/'

app = express ()
app.use ([/.*\.txt$/, /.*\.png$/], middleware (ROOT_PATH))
app.use (express.static (ROOT_PATH))
app.listen (8080)

options.fallthrough

middleware (ROOT_PATH, { fallthrough: false })

The default value is true.

The fallthrough option is modeled after serve-static's fallthrough option, and tells the middleware to forward any error to express (like file not found), if it is set to false.

From the serve-static documentation:

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.

options.silent

middleware (ROOT_PATH, { silent: true })

The silence option will stop middleware from printing to stderr on error.

If silence is set to true and fallthough is set to false, then express will print the error to stderr, cancelling out the effect. But still useful, since you would else get the error message printed twice.

sniffer

If you are unhappy with the middleware you can write your own, using sniffer.

NOTE: sanctuary is not required but express-mime-sniff uses sanctuary, so it is included in the package, as a dependency.

import S from 'sanctuary'
import { sniffer } from 'express-mime-sniff'

/* @typedef sniffer
 * sniffer :: String Error, String MimeType, String Path => (Error -> void) -> (MimeType -> void) -> Path -> void
 * @param {{ (string: error):any }} errorHandler Function that will handle an error.
 * @param {{ (string: mimeType):any }} successHandler Function that will get mime-type for `path`.
 * @param {string} path Path to the file you want the mime-type for.
 * @returns {void}
 */

const test = sniffer
  (S.pipe ([console.error, () => process.exit(1)])) // error callback
  (console.log)                                     // success callback

// happy path
test ('spec/fixtures/fake.jpg') // -> "image/png charset=binary"

// sad path
test ('no-such-file.jpg')       // -> "ERROR: cannot stat `no-such-file.jpg' (No such file or directory)"

wrap sniffer in Promise

const promise = new Promise ((resolve, reject) => {
  sniffer (reject) (resolve) ('path/to/file')
})

*nix file program

Description: Recognize the type of data in a file using "magic" numbers The file command is "a file type guesser", a command-line tool that tells you in words what kind of data a file contains.

You can usually configure magic mime-types in either /etc/magic, /etc/magic.mime or add magic files to /usr/share/misc/magic/. More information with man magic or at https://www.darwinsys.com/file/.

About

express-mime-sniff is a package for setting HTTP `Content-Type` headers for files by utilizing a *nix `file` program available on your system.

Resources

License

Stars

Watchers

Forks

Packages

No packages published