Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding feature ignoreDuplicateSlashes with tests #270

Conversation

code-ape
Copy link
Contributor

@code-ape code-ape commented May 1, 2022

Overview

This is a PR for the feature discussed in #240 which relates to expected behavior for duplicate slashes in path. It was stated this would be a welcome PR and @mcollina directed me to PR #50 for reference of implementing a similar feature.

Related Issues & PRs

  1. Unexpected behavior on double slash in path #240
  2. Add support for ignoring trailing slashes #50

Changes

  1. Add support for config option ignoreDuplicateSlashes which will condense any continuous occurrence of / in the path into a single /.
  2. Add tests for ignoreDuplicateSlashes following pattens of existing tests for ignoreTrailingSlash.
  3. Basic documentation of this feature added to README.md.

Copy link
Collaborator

@ivan-tymoshenko ivan-tymoshenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for your contribution. I guess the main idea was to not match empty params, but not to remove duplicate slashes. I mean if someone decided to add a route with two slashes in a row we should match it.

Try to check if a parameter length is not equal to 0, how we check the maximum parameter length, and see if it works.

if (decoded.length > maxParamLength) {

index.js Outdated Show resolved Hide resolved
@code-ape
Copy link
Contributor Author

code-ape commented May 1, 2022

Hi @ivan-tymoshenko, thanks for the quick reply 😄

I think you may have misunderstood #240. I filed it a couple months ago and the desired functionality was to remove duplicate sequential /. This would be of great benefit to me and my team for projects using fastify as an optional config parameter. This is common behavior for web servers, for example this works: https://github.com/delvedor//////find-my-way

You can check the code example for my issue which has paths like /a///d as test cases. I was opening this PR based on the following comment which indicted it would be of interest: #240 (comment)

And thanks for the callout on regex! I will replace that with a proper loop shortly for better performance 🚀

@code-ape
Copy link
Contributor Author

code-ape commented May 2, 2022

I did a hand coding of the method for removing duplicate slashes and a benchmark to compare it to Regex. All work for that has been pushed to this branch. Both seem to perform well and the regex appears to do better in more "real world" examples. Below is a run from my M1 MacBook Pro.

Slowest performing scenario seems to be ~150ns / function call or ~500 CPU clock cycles for a 40 character string, which comes to ~10 CPU cycles per character. Also note that "no-op" scenarios where there are no duplicate slashes (which is presumably the majority of paths that would be processed in the real world) appears to only ~3 CPU cycles per character! 😄

$ node ./bench-duplicate.js
[/a/b]
removeDuplicateSlashes(0)      x 96,554,737 ops/sec ±0.21% (296 runs sampled)
removeDuplicateSlashesRegex(0) x 39,600,222 ops/sec ±0.10% (295 runs sampled)

[/api/v1/myNamespace/myObject/action1] 
removeDuplicateSlashes(1)      x 12,750,900 ops/sec ±0.41% (292 runs sampled)
removeDuplicateSlashesRegex(1) x 25,132,656 ops/sec ±0.29% (295 runs sampled)

[/a//b]
removeDuplicateSlashes(2)      x 35,200,687 ops/sec ±0.21% (297 runs sampled)
removeDuplicateSlashesRegex(2) x 18,131,065 ops/sec ±0.49% (289 runs sampled)

[/api/v1/myNamespace/myObject//action1]
removeDuplicateSlashes(3)      x 9,241,756 ops/sec ±0.31% (293 runs sampled)
removeDuplicateSlashesRegex(3) x 15,398,355 ops/sec ±0.36% (290 runs sampled)

[/a///////////////////////b]
removeDuplicateSlashes(4)      x 12,526,865 ops/sec ±0.32% (292 runs sampled)
removeDuplicateSlashesRegex(4) x 15,384,914 ops/sec ±0.20% (295 runs sampled)

[/api/v1/myNamespace/myObject///////////////////////action1]
removeDuplicateSlashes(5)      x 5,976,074 ops/sec ±0.32% (293 runs sampled)
removeDuplicateSlashesRegex(5) x 13,493,742 ops/sec ±0.21% (291 runs sampled)

[/api//v1//myNamespace//myObject//action1]
removeDuplicateSlashes(6)      x 6,328,285 ops/sec ±0.23% (294 runs sampled)
removeDuplicateSlashesRegex(6) x 6,712,087 ops/sec ±0.18% (295 runs sampled)

@ivan-tymoshenko
Copy link
Collaborator

Hmm, it looks like regex in that case works really faster. Can you provide npm run bench:cmp:ci command results?

@ivan-tymoshenko
Copy link
Collaborator

Another issue I'm worried about is that we shouldn't modify a wildcard part of the path. You can see that we return a wildcard param without trimming the last slash.

Copy link
Collaborator

@ivan-tymoshenko ivan-tymoshenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@code-ape Hi, do you need any help? Can you remove non-regexp implementation and provide benchmark results?

lib/duplicate-slashes.js Outdated Show resolved Hide resolved
bench-duplicate.js Outdated Show resolved Hide resolved
@ivan-tymoshenko ivan-tymoshenko force-pushed the issue-240/add-option-remove-duplicate-path-seperators branch from 687688d to 6d66fe1 Compare May 24, 2022 09:34
@ivan-tymoshenko
Copy link
Collaborator

Снимок экрана 2022-05-24 в 12 59 08

Copy link
Collaborator

@ivan-tymoshenko ivan-tymoshenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ivan-tymoshenko ivan-tymoshenko requested a review from mcollina May 24, 2022 10:01
Copy link
Collaborator

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants