hapijs / hapijs/inert

`redirectToSlash` not being applied

Open
#146 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
236
Forks
48
PR merge metrics
No merged PRs in 30d

Description

#### Support plan

* *which support plan is this issue covered by?* (e.g. Community, Core, Plus, or Enterprise): Community
* *is this issue currently blocking your project?* (yes/no): No
* *is this issue affecting a production system?* (yes/no): Yes

#### Context

* *node version*: 12.18.2
* *module version with issue*: `"@hapi/hapi": "^19.1.1"`, `"@hapi/inert": "^6.0.1"`
* *last module version without issue*: IDK
* *environment* (e.g. node, browser, native): node
* *used with* (e.g. hapi application, another framework, standalone, ...): hapi application
* *any other relevant information*:

#### What are you trying to achieve or the steps to reproduce?

I'm defining a custom endpoint named `/docs/js` which would serve any file in the existent `/docs/js` directory located at the root path of my project, this is the output of my JSDoc automation routine, so an index.html is served from there and inner CSS/JS should be loaded upon the rendering of that index.

Similarly, I want to do the same to `swagger` and `test coverage`, so I would just replicate the same pattern.

Everything works fine, except the `redirectToSlash` functionality, I did some digging through the plugin source code and if I remove this snippet demonstrated below, the functionality works as expected.

![Anotação 2020-07-05 153447](https://user-images.githubusercontent.com/12788435/86539697-1520bd00-bed5-11ea-8fc2-801440c5bae2.jpg)

> app.js

```js
(async function () {

const appPort = process.env.APP_PORT || process.env.PORT || process.env.VCAP_APP_PORT || 8080;
const Hapi = require("@hapi/hapi");
const vision = require("@hapi/vision");
const inert = require("@hapi/inert");
const path = require("path");
const fs = require("fs");

let server = Hapi.server(
{
"port": appPort,
"tls": process.env.LOCAL_HTTPS ? {
"hostname": "localhost",
"agent": false,
"key": fs.readFileSync("./root/certificates/local/localhost-privkey.pem"),
"cert": fs.readFileSync("./root/certificates/local/localhost-cert.pem"),
"rejectUnauthorized": false
} : null,
}
);

await server.register(vision);
await server.register(inert);

server.route({
"method": "GET",
"path": "/docs/js/{param*}",
"handler": {
"directory": {
"path": path.join(__dirname, "/docs", "js"),
"redirectToSlash": true
}
},
});
}());
```

> Project structure

![Anotação 2020-07-05 154015](https://user-images.githubusercontent.com/12788435/86539800-dd664500-bed5-11ea-8b3c-ec8d6045d1a9.jpg)

> Equivalent express code

```js
const express = require("express");
const app = express();
let server = require("https").createServer(
{
"hostname": "localhost",
"agent": false,
"key": fs.readFileSync("./root/certificates/local/localhost-privkey.pem"),
"cert": fs.readFileSync("./root/certificates/local/localhost-cert.pem"),
"rejectUnauthorized": false
},
app
)

app.use("/docs/js", express.static(__dirname + "/docs/js"));
app.use("/docs/test", express.static(__dirname + "/docs/test/lcov-report"));
app.use("/docs/api", express.static(__dirname + "/docs/api/swagger-ui-dist"));
```

#### What was the result you got?

1. When I access `localhost:port/docs/js` I got the index.html and extra css/js can't be loaded.
2. When I access `localhost:port/docs/js/` I got the index.html and all extra css/js works smoothly.
3. When I access `localhost:port/docs/js` the requests are not redirected to `localhost:port/docs/js/`

#### What result did you expect?

1. Access `localhost:port/docs/js` and be redirected to `localhost:port/docs/js/` since the `redirectToSlash` option is set to true.

PS: I validated that:
1. That handler is being executed
2. No other handler is messing with this one
3. If I manually insert the `/` at the end, it works fine
4. I did some debugging in the `directory.js` code and if I remove/comment the snippet mentioned above, the slash is appended to the URL as expected.
5. No change was made to `stripTrailingSlash` configuration, the defaults are in place
6. I performed some console.log instructions and here is what I got

> inert/lib/directory.js line 123

```js
if (internals.isDirectory(error)) {
console.log(resource);
console.log(settings);
console.log(request.server.settings.router.stripTrailingSlash);
console.log(hasTrailingSlash);
// more code below
}
```

![Anotação 2020-07-05 154358](https://user-images.githubusercontent.com/12788435/86539883-890f9500-bed6-11ea-86bf-792787b78d9e.jpg)

6. Finally, even though the console.log is showing `/docs/js/`, the request in the browser (and also using curl) is not being redirected as expected, as demonstrated below.

![Anotação 2020-07-05 154930](https://user-images.githubusercontent.com/12788435/86539951-2e2a6d80-bed7-11ea-8161-457313b664a6.jpg)

![Anotação 2020-07-05 154938](https://user-images.githubusercontent.com/12788435/86539952-2f5b9a80-bed7-11ea-9dc2-44c10bb4bb86.jpg)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.