visionmedia/express — pull request #1516 by michaelahlers (2013-02-24 19:08:12+00:00)
Title: Fix Dotted Relative Redirects in Applications Mounted on Nested Paths

In order to cope with visitors to nested applications, where the path is missing the trailing slash, and serve static resources it is helpful to redirect to the canonical resource so the browser will then resolve relative resources at the correct location. (For background, see [*Relative URLs and trailing slashes*](http://stackoverflow.com/questions/5457885/relative-urls-and-trailing-slashes) on Stack Overflow, and [this discussion](http://stackoverflow.com/questions/10867052/cannot-serve-static-files-with-express-routing-and-no-trailing-slash) about serving static resources under those conditions.)

In other words, if the user visits `http://localhost:3000/foo/bear/leaf`, and the markup rendered for that location references a file called `styles.css`, the browser will attempt to resolve that file to `http://localhost:3000/foo/bear/styles.css`. Obviously, [`req.path`](http://expressjs.com/api.html#req.path) is of little use, as it is scoped to the path at which the application is mounted (it will contain `/`).

That issue would be easily solved with `res.redirect('./index')` in a route for `/`, but the destination URL is [computed incorrectly by the current version of `res.location`](https://github.com/visionmedia/express/blob/a4b2e48dfea095f722a17b6b6d89e0a2ccee3fad/lib/response.js#L637) (again, it uses the application's mount point).

To illustrate this problem, start with the following setup and assume `server` is the listening Express application.

```javascript
var foo = express()
server.use('/foo', foo)

var bear = express()
foo.use('/bear', bear)

var leaf = express()
bear.use('/leaf', leaf)

leaf.get('/', function (req, res) {
res.redirect('./index')
})

leaf.get('/index', function (req, res) {
res.send('Sending /index...')
})
```

We can use cURL to see the incorrect redirection.

```
$ curl localhost:3000/foo/bear/leaf
Moved Temporarily. Redirecting to //./index
```

The problem is further exacerbated by the redundant `//` (the browser interprets this as a terminator for the URL protocol, then tries to resolve the path to `http://.index`).

My fix is simple: as the documentation specifies this type of redirect is relative to the *path* and not the *mount point*, we should rely on [`req.originalUrl`](http://expressjs.com/api.html#req.originalUrl) to compute the redirect, and check if `req.originalUrl` has a trailing slash before appending another one between it and the relative redirection target.

With this change in place, you'll see we get the correct redirection.

```
$ curl localhost:3000/foo/bear/leaf
Moved Temporarily. Redirecting to /foo/bear/leaf/./index
```

See also: my comments in the patch.