Skip to content

Commit d8a887b

Browse files
authored
Merge pull request #12 from firstandthird/hapi17
Hapi17
2 parents 1512c41 + d75c62a commit d8a887b

File tree

6 files changed

+174
-227
lines changed

6 files changed

+174
-227
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
language: node_js
22
node_js:
33
- "8"
4-
- "6"

index.js

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@
22
const useragent = require('useragent');
33
const wreck = require('wreck');
44

5-
module.exports = (server, options, allDone) => {
5+
const register = async (server, options) => {
66
options = options || {};
77
if (!options.method) {
8-
return allDone(new Error('hapi-trailing-slash plugin registered without specifiying which method to use'));
8+
throw new Error('hapi-trailing-slash plugin registered without specifiying which method to use');
99
}
1010
options.statusCode = options.statusCode || 301;
1111

12-
const redirectExists = (redirectPath, callback) => {
12+
const redirectExists = async (redirectPath) => {
1313
if (!options.checkIfExists) {
14-
return callback(true);
14+
return Promise.resolve(true);
15+
}
16+
try {
17+
const { res, payload } = await wreck.request('head', redirectPath);
18+
return Promise.resolve(res.statusCode < 400);
19+
} catch (e) {
20+
return Promise.resolve(false);
1521
}
16-
wreck.request('head', redirectPath, {}, (err, res) => {
17-
if (err) {
18-
return callback(false);
19-
}
20-
return callback(res.statusCode < 400);
21-
});
2222
};
2323

24-
const doRedirect = (path, request, reply) => {
24+
const doRedirect = (path, request, h) => {
2525
const redirectTo = request.url.search ? path + request.url.search : path;
2626
if (options.verbose) {
2727
server.log(['hapi-trailing-slash', 'redirect'], {
@@ -34,15 +34,21 @@ module.exports = (server, options, allDone) => {
3434
to: redirectTo
3535
});
3636
}
37-
return reply.redirect(redirectTo).code(options.statusCode);
37+
const response = h.redirect(redirectTo)
38+
// redirects in hapi 17 are either permanent() or temporary()
39+
if (options.statusCode === 301) {
40+
return response.permanent();
41+
}
42+
else {
43+
return response.temporary();
44+
}
3845
};
3946

40-
// if (options.method === 'append') {
41-
server.ext('onPreResponse', (request, reply) => {
47+
server.ext('onPreResponse', async(request, h) => {
4248
const statusCode = request.response.output ? request.response.output.statusCode : request.response.statusCode;
4349
// if the route was already found by hapi then just ignore it:
4450
if (statusCode !== 404) {
45-
return reply.continue();
51+
return h.continue;
4652
}
4753
const method = request.method.toLowerCase();
4854
// pick a condition checker based on either 'append' or 'remove' mode:
@@ -51,25 +57,25 @@ module.exports = (server, options, allDone) => {
5157
// see if we need to do a redirect for either slashed/slashless path:
5258
if (['get', 'head'].indexOf(method) !== -1 && condition()) {
5359
if (request.path.indexOf('.') !== -1) {
54-
return reply.continue();
60+
return h.continue;
5561
}
5662
// pick a redirection based on either 'append' or 'remove' mode:
5763
const redirectPath = options.method === 'append' ? `${request.path}/` : request.path.replace(/\/$/, '');
58-
return redirectExists(redirectPath, (exists) => {
59-
if (exists) {
60-
doRedirect(redirectPath, request, reply);
61-
} else {
62-
return reply.continue();
63-
}
64-
});
64+
const exists = await redirectExists(redirectPath);
65+
if (exists) {
66+
return doRedirect(redirectPath, request, h);
67+
} else {
68+
return h.continue;
69+
}
6570
}
6671
// otherwise it really is a 404:
67-
return reply.continue();
72+
return h.continue;
6873
});
69-
allDone();
74+
return Promise.resolve();
7075
};
7176

72-
module.exports.attributes = {
73-
name: 'hapi-trailing-slash',
77+
exports.plugin = {
78+
register,
79+
once: true,
7480
pkg: require('./package.json')
7581
};

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
"eslint": "^3.9.1",
2626
"eslint-config-firstandthird": "^3.2.0",
2727
"eslint-plugin-import": "^2.1.0",
28-
"hapi": "^16.1.1",
29-
"lab": "^13.0.1"
28+
"hapi": "^17.0.1",
29+
"lab": "^15.1.2"
3030
},
3131
"dependencies": {
3232
"useragent": "^2.2.1",
33-
"wreck": "^12.0.0"
33+
"wreck": "^14.0.2"
3434
}
3535
}

test/append.test.js

Lines changed: 46 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -8,144 +8,122 @@ const theModule = require('../index.js');
88
lab.experiment('hapi-trailing-slash', () => {
99
let server;
1010

11-
lab.beforeEach((done) => {
11+
lab.beforeEach(async() => {
1212
server = new Hapi.Server();
13-
server.connection();
14-
1513
server.route([
1614
{
1715
method: 'GET',
1816
path: '/no/slash',
19-
handler: (request, reply) => {
20-
reply('welcome to the jungle');
17+
handler: (request, h) => {
18+
return 'welcome to the jungle';
2119
}
2220
},
2321
{
2422
method: 'GET',
2523
path: '/has/slash/',
26-
handler: (request, reply) => {
27-
reply('slither');
24+
handler: (request, h) => {
25+
return 'slither';
2826
}
2927
},
3028
{
3129
method: 'GET',
3230
path: '/has/slash/{band}/',
33-
handler: (request, reply) => {
31+
handler: (request, h) => {
3432
if (request.params.band === 'gnr') {
35-
reply('sweet child of mine ');
33+
return 'sweet child of mine ';
3634
} else if (request.params.band === 'velvet_revolver') {
37-
reply('slither');
35+
return 'slither';
3836
} else {
39-
reply('not found');
37+
return 'not found';
4038
}
4139
}
4240
}
4341
]);
4442

45-
server.register({
46-
register: theModule,
43+
const response = await server.register({
44+
plugin: theModule,
4745
options: {
4846
method: 'append',
4947
verbose: true
5048
}
51-
}, (err) => {
52-
if (err) {
53-
throw err;
54-
}
55-
server.start(done);
5649
});
50+
await server.start();
5751
});
5852

59-
lab.afterEach((done) => {
60-
server.stop(done);
53+
lab.afterEach(async() => {
54+
await server.stop();
6155
});
6256

63-
lab.test(' "append" /has/slash/ works normally', (done) => {
64-
server.inject({
57+
lab.test(' "append" /has/slash/ works normally', async() => {
58+
const result = await server.inject({
6559
method: 'get',
6660
url: '/has/slash/'
67-
}, (result) => {
68-
Code.expect(result.statusCode).to.equal(200);
69-
Code.expect(result.payload).to.equal('slither');
70-
done();
7161
});
62+
Code.expect(result.statusCode).to.equal(200);
63+
Code.expect(result.payload).to.equal('slither');
7264
});
73-
lab.test(' "append" /has/slash works normally if that route is specified', (done) => {
65+
lab.test(' "append" /has/slash works normally if that route is specified', async() => {
7466
server.route({
7567
path: '/has/slash',
7668
method: 'get',
77-
handler(request, reply) {
78-
return reply('slither');
69+
handler(request, h) {
70+
return 'slither';
7971
}
8072
});
81-
server.inject({
73+
const result = await server.inject({
8274
method: 'get',
8375
url: '/has/slash'
84-
}, (result) => {
85-
Code.expect(result.statusCode).to.equal(200);
86-
Code.expect(result.payload).to.equal('slither');
87-
done();
8876
});
77+
Code.expect(result.statusCode).to.equal(200);
78+
Code.expect(result.payload).to.equal('slither');
8979
});
9080

91-
lab.test(' "append" GET /has/slash redirects to /has/slash/', (done) => {
92-
server.inject({
81+
lab.test(' "append" GET /has/slash redirects to /has/slash/', async() => {
82+
const result = await server.inject({
9383
method: 'get',
9484
url: '/has/slash'
95-
}, (result) => {
96-
Code.expect(result.statusCode).to.equal(301);
97-
Code.expect(result.headers.location).to.equal('/has/slash/');
98-
done();
9985
});
86+
Code.expect(result.statusCode).to.equal(301);
87+
Code.expect(result.headers.location).to.equal('/has/slash/');
10088
});
101-
lab.test(' "append" HEAD /has/slash redirects to /has/slash/', (done) => {
102-
server.inject({
89+
lab.test(' "append" HEAD /has/slash redirects to /has/slash/', async() => {
90+
const result = await server.inject({
10391
method: 'head',
10492
url: '/has/slash'
105-
}, (result) => {
106-
Code.expect(result.statusCode).to.equal(301);
107-
Code.expect(result.headers.location).to.equal('/has/slash/');
108-
done();
10993
});
94+
Code.expect(result.statusCode).to.equal(301);
95+
Code.expect(result.headers.location).to.equal('/has/slash/');
11096
});
111-
lab.test(' "append" /has/slash/ GET works with url params', (done) => {
112-
server.inject({
97+
lab.test(' "append" /has/slash/ GET works with url params', async() => {
98+
const result = await server.inject({
11399
method: 'get',
114100
url: '/has/slash/velvet_revolver/'
115-
}, (result) => {
116-
Code.expect(result.statusCode).to.equal(200);
117-
Code.expect(result.payload).to.equal('slither');
118-
done();
119101
});
102+
Code.expect(result.statusCode).to.equal(200);
103+
Code.expect(result.payload).to.equal('slither');
120104
});
121105

122-
lab.test(' "append" /has/slash GET redirects with url params ', (done) => {
123-
server.inject({
106+
lab.test(' "append" /has/slash GET redirects with url params ', async() => {
107+
const result = await server.inject({
124108
method: 'get',
125109
url: '/has/slash/velvet_revolver?temp=hi'
126-
}, (result) => {
127-
Code.expect(result.statusCode).to.equal(301);
128-
Code.expect(result.headers.location).to.equal('/has/slash/velvet_revolver/?temp=hi');
129-
done();
130110
});
111+
Code.expect(result.statusCode).to.equal(301);
112+
Code.expect(result.headers.location).to.equal('/has/slash/velvet_revolver/?temp=hi');
131113
});
132-
lab.test(' "append" /has/slash POST redirect is ignored ', (done) => {
133-
server.inject({
114+
lab.test(' "append" /has/slash POST redirect is ignored ', async() => {
115+
const result = await server.inject({
134116
method: 'post',
135117
url: '/has/slash/velvet_revolver?temp=hi'
136-
}, (result) => {
137-
Code.expect(result.statusCode).to.equal(404);
138-
done();
139118
});
119+
Code.expect(result.statusCode).to.equal(404);
140120
});
141121

142-
lab.test(' "append" /has/slash.png redirect is ignored ', (done) => {
143-
server.inject({
122+
lab.test(' "append" /has/slash.png redirect is ignored ', async() => {
123+
const result = await server.inject({
144124
method: 'get',
145125
url: '/images/logo.png'
146-
}, (result) => {
147-
Code.expect(result.statusCode).to.equal(404);
148-
done();
149126
});
127+
Code.expect(result.statusCode).to.equal(404);
150128
});
151129
});

0 commit comments

Comments
 (0)