1

My static file middleware calls are being overwritten by my routes, even though I'm running it in the correct order:

First I set my static files, like this:

app.use('/public/', express.static('/home/skerit/temp'));
app.use('/public/', express.static('/home/skerit/app/public'));

Then I add my route:

app.get('/:controller/:action', callback);

And now, when I try to get /public/empty.txt the route is executed. When I remove the route, it works just fine.

And I'm sure they happen in the correct order. (First app.use, then app.get)

So what could be wrong here?

Edit: Since I said I'm executing them in the correct order, here's some proof. I added simple log statements to the execution of the code:

[debug]   - [stages.js:186] Static middleware has been set!
[debug]   - [stages.js:191] Startin routes!
[debug]   - [routes.js:7] Setting controller routes
[info]    - [database.js:79] Database connection to default has been made
[info]    - [database.js:93] Stored procedures on MongoDB server default
[info]    - [database.js:120] Created connection to all datasources
[debug]   - [stages.js:202] Setting /:controller/:action

As you can see: 'Static middleware has been set' comes up first. Only then does it start setting the other routes.

Jelle De Loecker
  • 20,999
  • 27
  • 100
  • 142

1 Answers1

0

app.get is not what decides if a route is run before or after a middleware, it is app.use(app.router) that does that. you need app.use(app.router) to be after app.use(express.static);

here are two examples:

var http = require('http');
var express = require('express');
app = express();
app.use(app.router);
app.use('/public/', express.static('/home/skerit/temp'));
app.get('/:controller/:action', function (req, res) {
    res.send(req.params.controller);
});
var server = http.createServer(app);
server.listen(process.env.port || 3000);

this snippet doesn't work, when you run localhost:3000/public/somefile - you'll get "public" returned. however if you use the following snippet:

var http = require('http');
var express = require('express');
app = express();
app.use('/public/', express.static('/home/skerit/temp'));
app.get('/:controller/:action', function (req, res) {
    res.send(req.params.controller);
});
app.use(app.router);
var server = http.createServer(app);
server.listen(process.env.port || 3000);

localhost:3000/public/somefile should return the file's content. Note the location of app.use(app.router). (if you don't add it, by default it should be last).

Note also that if /home/skerit/temp/somefile doesn't exist, then the control will pass to the next middleware and it will look like express.static didn't work, so make sure your paths are correct.

EDIT:
Following a comment I've been informed that my original answer was incorrect, that is, that app.get does decide at what point in the middleware stack app.router is put.Namely at the first time either app.router is used or app.get is used.
In this case I would suspect that your problem is most likely due to the fact that you are using a url to a file that doesn't exist.

Alon Bar David
  • 1,757
  • 14
  • 15
  • 2
    `app.get` *does* decide if a route is run before or after middleware; once you use `app.get` (or `.post`, ...), the router middleware is inserted into the middleware stack ([here](https://github.com/visionmedia/express/blob/master/lib/application.js#L410)). Adding routes before other middleware will be the equivalent of adding `app.router` before that other middleware. – robertklep Apr 23 '13 at 06:35
  • Thank you, I was not aware of that, I'll change the comment accordingly. – Alon Bar David Apr 23 '13 at 07:34