Regex for using static middleware

2,105 views
Skip to first unread message

P.V.S.

unread,
Apr 1, 2011, 3:58:29 AM4/1/11
to Express
Hi,
I am trying to serve static files & handle other requests.
I am currently facing issues in serving out static files.

There are two kinds of static file requests

a. /static/js/hello.js ------->
this works with app.use("/static/", express.static(__dirname + "/
static/", {maxAge : oneYear}));

b. /static/v123.21/js/hello.js ------->
This is mainly used for clearing client's cache. Here is what i am
doing
app.use(/^\/static\/v.+\/.+$/, express.static(__dirname + "/static/",
{maxAge : oneYear}));

This doesnt work for the above scenario.

statement 'b' comes before 'a' in code. I also tried by commenting out
a, just to be sure about any conflicts.

does regular expression work for static middleware?

Is there anything i am missing fundamentally?

--
Thanks,
P.V.S.
--
P.S.: i am new to node.js & express.

Laurie Harper

unread,
Apr 1, 2011, 10:40:45 AM4/1/11
to expre...@googlegroups.com

A regular expression will work for the 'static' middleware in the same was as for any other middleware or route; the problem, I think, is how 'static' maps the request path to the file system path. It's not a 'smart' mapping -- it essentially takes the URL path (/static/v123.21/... in your case (b)) and appends it to the filesystem static root -- producing /path/to/app/static/static/v123.21/...

I suspect your best bet for this use-case would be to write a wrapper/pre-processor middleware to rewrite the request URI and install that ahead of 'static', as in:

app.use(/regex/, rewrite, express.static(...))

TJ will probably have an easier solution, but failing that, this is where I'd start...
--
Laurie Harper
http://laurie.holoweb.net/

TJ Holowaychuk

unread,
Apr 1, 2011, 11:15:03 AM4/1/11
to expre...@googlegroups.com
If you need to get extremely specific, you can also utilize the middleware within the callback functions themselves, for example:

  var send = connect.static(__dirname + '/static');
  app.get(..., function(req, res, next){
    // strip "/static" from req.url if needed, etc
    send(req, res, function(err){
      // whatever, or simply pass next as the callback
    });
  });

the simplicity of middleware is very powerful, since it's not bound to anything but
the request / response, and in most cases you can even fake these objects to get
even crazier but it's usually an indication you are doing something wrong. 

typically people just add static() to the bottom so that say, "GET /main.css" will simply pass through the routes since none will match, and eventually hit static() where it does a stat(), and acts accordingly 

-- 
TJ Holowaychuk
--
You received this message because you are subscribed to the Google Groups "Express" group.
To post to this group, send email to expre...@googlegroups.com.
To unsubscribe from this group, send email to express-js+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/express-js?hl=en.

Laurie Harper

unread,
Apr 1, 2011, 6:13:57 PM4/1/11
to expre...@googlegroups.com
Yeah, that's probably more succinct than my suggestion. 

Interestingly, I usually put static at the top -- my stack looks something like favicon, logger, compiler, static, followed by all the request-processing/manipulating middleware, session, router, error-handler. That way, static files are served without all the additional overhead. 

L.

TJ Holowaychuk

unread,
Apr 1, 2011, 6:15:34 PM4/1/11
to expre...@googlegroups.com
nothing wrong with that Laurie, it's just a personal preference of mine to have it below routes so I can handle things if I want to, besides, that is why they are not locked to specific positions :) ultimate flexibility.

-- 
TJ Holowaychuk

Laurie Harper

unread,
Apr 1, 2011, 7:16:27 PM4/1/11
to expre...@googlegroups.com
Heh indeed :-)

P.V.S.

unread,
Apr 3, 2011, 5:10:54 AM4/3/11
to expre...@googlegroups.com
Thanks for the reply.
var st = express.static(
__dirname + app.set('path.static'), 
{ maxAge : app.set('static.expiry') }
);
app.get(/^\/static\/(v.+?\/)?(.+$)/, function (req, res, next) {
req.url = req.params[1];
st(req, res, next);
});

The above worked for me.

TJ Holowaychuk

unread,
Apr 3, 2011, 11:35:24 AM4/3/11
to expre...@googlegroups.com
you could use app.get('/static/:file(*)') and req.params.file within the route, "*" spans segments and :file() names the capture group

-- 
TJ Holowaychuk
--
Reply all
Reply to author
Forward
0 new messages