Express/connect middleware that does HTTP content negotiation for static files
Express/connect middleware for doing content negotiation with static files on disc. Heavily inspired by Apache's mod_negotiation.
req.url to the negotiated file name based on
these factors (in descending order of importance):
req.urlmatches a file name on disc exactly
- The value of a locale cookie (optional, specified by
... and of course the availability of suitable files on disc. If no
acceptable match is found,
req.url is left untouched.
express-negotiator interprets the extensions
of the files on disc as an unordered set. A file called
would be treated the same as one called
foo.fr.html except when the
request url specifies an exact match.
The negotiator middleware is intended to run right before
pointed at the same directory as
options.cookieName is specified, the
must also be in the middleware chain.
When the url is rewritten, negotiator sets the ETag header to the same
value as the
static middleware would
"<size>-<modificationTime>"), but with the negotiated Content-Type
and locale id bits suffixed. This prevents false positive 304
If-None-Match when the same client (or reverse proxy)
requests the same url later with different headers (eg. after a locale
cookie change). That would happen if the files happened to have the
same size and modification times.
If-Modified-Since header is removed since that would cause
static middleware to reply
304 Not Modified in similar
situations. ETags are a superior concept anyway.
$ npm install express-negotiator
var express = require'express'negotiator = require'express-negotiator'root = '/path/to/static/files'app = expresscreateServer;appuseexpresscookieParserusenegotiatorroot: root cookieName: 'mycookie'useexpressstaticrootlisten1337;
If the root dir contains the files
foo.png these example requests would be rewritten as follows:
GET / HTTP/1.1Accept: text/htmlAccept-Language: en=> /index.en.htmlResponse ETag: "<size>-<modificationTime>-text/html-en"
GET /?locale=da HTTP/1.1Accept: text/htmlAccept-Language: en=> /index.da.htmlResponse ETag: "<size>-<modificationTime>-text/html-da"
GET /index HTTP/1.1Cookie: mycookie=daAccept: text/htmlAccept-Language: en=> /index.da.htmlResponse ETag: "<size>-<modificationTime>-text/html-da"
GET /foo HTTP/1.1Accept: image/*=> /foo.pngResponse ETag: "<size>-<modificationTime>-image/png"
See the test suite for more examples.
express-negotiator is licensed under a standard 3-clause BSD license
-- see the
LICENSE file for details.