rob
rob

Reputation: 10119

More sophisticated static file serving under Express

Best explained by an example. Say I have a directory /images, where I have images a.png, b.png, and c.png.

Then I have a directory /foo/images, which has an image b.png, which is different than the b.png in /images.

I want it so if a request comes in for http://mydomain.com/foo/images/a.png, it will serve the image /images/a.png. But if a request comes in for http://mydomain.com/foo/images/b.png, it will get the version of b.png in /foo/images. That is, it first checks foo/images/ and if there is not file by that name, it falls back on /images.

I could do this using res.sendfile(), but I'd prefer use built-in functionality if it exists, or someone's optimized module, while not losing the benefits (caching, etc) that might be provided by the middleware.

Upvotes: 3

Views: 1263

Answers (1)

Kato
Kato

Reputation: 40582

This would intercept requests to /foo/images/ and redirect them if the file doesn't exist, still using static middleware and caching appropriately

var imageProxy = require('./imageProxy.js');

// intercept requests before static is called and change the url
app.use( imageProxy );

// this will still get cached
app.use( express.static(__dirname + '/public') );

And inside imageProxy.js:

var url = require('url');
var fs  = require('fs');
var ROOT = process.execPath + '/public';

exports = function(req, res, next) {
   var parts = url.parse(req.url);
   // find all urls beginnig with /foo/images/
   var m = parts.pathname.match(/^(\/foo(\/images\/.*))/);
   if( m ) {
      // see if the override file exists
      fs.exists(ROOT+m[1], function (exists) {
         if( !exists ) { req.url = ROOT+m[2]; }
         // pass on the results to the static middleware
         next();
      });
   }
 });

If you wanted to access the original URL for some reason, it's still available at req.originalUrl

Upvotes: 3

Related Questions