Skip to content

Commit f3e02c4

Browse files
committed
BREAKING CHANGE: Handle non-trailing slashes correctly (#1512)
* router - remove do not merge double slashes by default * use server.pre(restify.plugins.pre.dedupeSlashes()) to deal with double slashes * refactor test to cover multiple slashes cases
1 parent af2c9f4 commit f3e02c4

File tree

3 files changed

+69
-35
lines changed

3 files changed

+69
-35
lines changed

lib/router.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ function compileURL(options) {
101101
return false;
102102
}
103103

104-
pattern += '\\/+';
104+
pattern += '\\/';
105105

106106
if (frag.charAt(0) === ':') {
107107
var label = frag;
@@ -131,7 +131,7 @@ function compileURL(options) {
131131
}
132132

133133
if (!options.strict) {
134-
pattern += '[\\/]*';
134+
pattern += '[\\/]?';
135135
}
136136

137137
if (pattern === '^') {

test/plugins/dedupeSlashes.test.js

+27-23
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,23 @@ describe('dedupe forward slashes in URL', function() {
7676
});
7777
});
7878

79-
it(
80-
'should remove duplicate slashes ' + 'including trailing slashes',
81-
function(done) {
82-
CLIENT.get('//foo//bar//', function(err, _, res, data) {
83-
assert.ifError(err);
84-
assert.equal(res.statusCode, 200);
85-
assert.equal(data, '/foo/bar/');
86-
done();
87-
});
88-
}
89-
);
79+
// eslint-disable-next-line
80+
it('should remove duplicate slashes including trailing slashes', function(done) {
81+
CLIENT.get('//foo//bar//', function(err, _, res, data) {
82+
assert.ifError(err);
83+
assert.equal(res.statusCode, 200);
84+
assert.equal(data, '/foo/bar/');
85+
done();
86+
});
87+
});
88+
it('should merge multiple slashes', function(done) {
89+
CLIENT.get('//////foo///bar///////', function(err, _, res, data) {
90+
assert.ifError(err);
91+
assert.equal(res.statusCode, 200);
92+
assert.equal(data, '/foo/bar/');
93+
done();
94+
});
95+
});
9096
});
9197

9298
describe('strict routing', function() {
@@ -131,24 +137,22 @@ describe('dedupe forward slashes in URL', function() {
131137
});
132138

133139
it('should remove duplicate slashes', function(done) {
134-
CLIENT.get('//foo//bar//', function(err, _, res, data) {
140+
CLIENT.get('//////foo///bar///////', function(err, _, res, data) {
135141
assert.ifError(err);
136142
assert.equal(res.statusCode, 200);
137143
assert.equal(data, '/foo/bar/');
138144
done();
139145
});
140146
});
141147

142-
it(
143-
'should remove duplicate slashes ' + 'including trailing slashes',
144-
function(done) {
145-
CLIENT.get('//foo//bar//', function(err, _, res, data) {
146-
assert.ifError(err);
147-
assert.equal(res.statusCode, 200);
148-
assert.equal(data, '/foo/bar/');
149-
done();
150-
});
151-
}
152-
);
148+
// eslint-disable-next-line
149+
it('should remove duplicate slashes including trailing slashes', function(done) {
150+
CLIENT.get('//foo//bar//', function(err, _, res, data) {
151+
assert.ifError(err);
152+
assert.equal(res.statusCode, 200);
153+
assert.equal(data, '/foo/bar/');
154+
done();
155+
});
156+
});
153157
});
154158
});

test/router.test.js

+40-10
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,31 @@ test('Strict routing distinguishes trailing slash', function(t) {
205205
server.get('/no-trailing', noop);
206206

207207
var trailing = server.router.routes.GET[0];
208-
t.ok(trailing.path.test('/trailing/'));
209-
t.notOk(trailing.path.test('/trailing'));
208+
t.ok(trailing.path.test('/trailing/'), 'Single trailing slash is ok');
209+
t.notOk(trailing.path.test('/trailing'), 'No trailing slash is not ok');
210+
t.notOk(
211+
trailing.path.test('/trailing//'),
212+
'Double trailing slash is not ok'
213+
);
214+
t.notOk(
215+
trailing.path.test('//trailing/'),
216+
'Double heading slash is not ok'
217+
);
210218

211219
var noTrailing = server.router.routes.GET[1];
212-
t.ok(noTrailing.path.test('/no-trailing'));
213-
t.notOk(noTrailing.path.test('/no-trailing/'));
220+
t.ok(noTrailing.path.test('/no-trailing', 'No trailing slash is ok'));
221+
t.notOk(
222+
noTrailing.path.test('/no-trailing/'),
223+
'Single trailing slash is not ok'
224+
);
225+
t.notOk(
226+
noTrailing.path.test('/no-trailing//'),
227+
'Double trailing slash is not ok'
228+
);
229+
t.notOk(
230+
noTrailing.path.test('//no-trailing'),
231+
'Double heading slash is not ok'
232+
);
214233

215234
t.end();
216235
});
@@ -223,14 +242,25 @@ test('Default non-strict routing ignores trailing slash(es)', function(t) {
223242
server.get('/no-trailing', noop);
224243

225244
var trailing = server.router.routes.GET[0];
226-
t.ok(trailing.path.test('/trailing/'));
227-
t.ok(trailing.path.test('//trailing//'));
228-
t.ok(trailing.path.test('/trailing'));
245+
t.ok(trailing.path.test('/trailing/', 'Single trailing slash is ok'));
246+
t.ok(trailing.path.test('/trailing'), 'No trailing slash is not ok');
247+
t.notOk(
248+
trailing.path.test('/trailing//'),
249+
'Double trailing slash is not ok'
250+
);
251+
t.notOk(trailing.path.test('//trailing'), 'Double heading slash is not ok');
229252

230253
var noTrailing = server.router.routes.GET[1];
231-
t.ok(noTrailing.path.test('/no-trailing'));
232-
t.ok(noTrailing.path.test('//no-trailing//'));
233-
t.ok(noTrailing.path.test('/no-trailing/'));
254+
t.ok(noTrailing.path.test('/no-trailing', 'No trailing slash is ok'));
255+
t.ok(noTrailing.path.test('/no-trailing/'), 'Single trailing slash is ok');
256+
t.notOk(
257+
noTrailing.path.test('/no-trailing//'),
258+
'Double trailing slash is not ok'
259+
);
260+
t.notOk(
261+
noTrailing.path.test('//no-trailing'),
262+
'Double heading slash is not ok'
263+
);
234264

235265
t.end();
236266
});

0 commit comments

Comments
 (0)