Express 4.0 Routing fallback 404

796 views
Skip to first unread message

Martin Beaudet

unread,
Nov 18, 2014, 4:30:14 PM11/18/14
to expre...@googlegroups.com
Hi,

I'm building a website having a secure area, but static file are not secured.

Here is the structure : 

---------------------------------------------------------------------------
     public\
        |- javascript\
        |- fonts\
        |- images\
        |- stylesheets\
        - some files at the root of public folder....
     routes\
        - some files at the root of routes folder....
     views\
        - layout\
        - some files at the root of views folder....     
---------------------------------------------------------------------------

Now, I would like to provide a 404 error handling for the static file that is execute before the middleware routing of my secure area.

Here is what I have : 

//...
var express = require('express');
//...

// Initialize express engine
var expressApp = express();
expressApp.set('port', httpPort);
expressApp.set('views', path.join(__dirname, 'views'));
expressApp.set('view engine', 'ejs');
expressApp.use(favicon(__dirname + '/public/images/favicon.ico'));
//...
expressApp.use(express.static(path.join(__dirname, 'public')));

// If static file has not been found, than issue a 404 response and stop routing here
expressApp.get(['/public', '/public/*'], function (req, res) {
    res.send(404, 'Resource not found !');
});

// Give EJS view access to request object
expressApp.use(function (req, res, next) {
    res.locals.request = req;
    next();
});

// Function to test if the user is authenticated before routing it to any page other than login
var loginPage = require("./routes/login");
expressApp.use(["/login", "/login/*"], loginPage);
var ensureUserAuthenticated = function (req, res, next) {
    if (!req.session.user) {
        // ...
    }
    else {
        
        // Evaluate next route
        next();
    }
};

// Configure all page routing
expressApp.use("/", ensureUserAuthenticated, require("./routes/index"));
expressApp.use("/home", ensureUserAuthenticated, require("./routes/home"));

// Route page not found (LAST MIDDLEWARE)
expressApp.use(function (req, res, next) {
    res.status(404).send('404 - Page Not Found !');
});

This is really annoying because if I'm asking for a static file that does not exists, the middleware that catch it is the (LAST MIDLEWARE).

Why the one I've created after setting the middleware express static is not catching it ? I've tried many thing but now I'm out of idea...

Best regards
Martin

Ryan Schmidt

unread,
Dec 1, 2014, 5:21:28 AM12/1/14
to expre...@googlegroups.com
On Nov 18, 2014, at 3:30 PM, Martin Beaudet wrote:
>
> expressApp.use(express.static(path.join(__dirname, 'public')));

This "public" refers to the directory on your server's disk, not parts of the URLs used to access these files through that server.

For example, if you have the following structure on disk:

public/
javascripts/
something.js

then the URL to access something.js on your server, given that you've used express.static as shown above, is:

http://localhost:3000/javascripts/somethings.js

The string "public" is not in the URL.

If you want to use a particular prefix on all your static URLs, in order to determine in advance if a request is meant to be static or not, you could do that. You could also define a separate hostname for static requests.

If you don't do something like that, then the question becomes: how, given a request for a file and route that does not exist on your server, do you propose to determine if the request was meant to be static or not?


> // If static file has not been found, than issue a 404 response and stop routing here
> expressApp.get(['/public', '/public/*'], function (req, res) {
> res.send(404, 'Resource not found !');
> });

I am not familiar with this notation of passing an array as the first argument to the get() function. I couldn't find that described in the express documentation.

If that is valid syntax, then the problem is that the URLs used to access your static resources do not contain the string "/public", so the route does not match.

If that is not valid syntax, then that's the problem.

Kevin Whinnery

unread,
Dec 1, 2014, 2:01:05 PM12/1/14
to expre...@googlegroups.com
To piggyback on the previous (correct) response, the problem is that "public" is not part of the URL used to serve your static assets.  If you must render a 404 before evaluating the rest of your routes, you would probably want to "mount" the static middleware on a URL prefix:

var express = require('express');
var app = express();

// Mount static middleware
app.use('/static', express.static(__dirname+'/public'));

// If we fall through here, no resource was found in __dirname/public
app.get('/static/*', function(request, response) {
    // If we reach here we have a 404
    response.status(404).send('Page not found.')
});

app.listen(3000);

In the browser (any client) you'll need to use the /static/ prefix for the CSS/JS/whatever, but you'd get the effect you're looking for.


--
You received this message because you are subscribed to the Google Groups "Express" group.
To unsubscribe from this group and stop receiving emails from it, send an email to express-js+...@googlegroups.com.
To post to this group, send email to expre...@googlegroups.com.
Visit this group at http://groups.google.com/group/express-js.
For more options, visit https://groups.google.com/d/optout.



--
Kevin Whinnery
@kevinwhinnery
Reply all
Reply to author
Forward
0 new messages