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

fix(path): correctly encode delimiters and relative paths #108

Merged
merged 17 commits into from
Apr 22, 2021

Conversation

luqven
Copy link
Contributor

@luqven luqven commented Apr 6, 2021

Do not merge until rebased on #103 and #104

Description

This PR adds a sanitize_path method to path.rb, related tests, and build improvements.

Tests

Using gem 'minitest-reporters', miniTest output logs now behave similarly to rSpec's, with color formatting and better diffing.

Test suite logging example:

SrcsetTest::SrcsetMinMaxWidths
  test_srcset_generates_width_pairs                               PASS (0.00s)
  test_only_max                                                   PASS (0.00s)
  test_srcset_pair_values                                         PASS (0.00s)
  test_negative_max_emits_error                                   PASS (0.00s)
...

Finished in 0.03846s
91 tests, 620 assertions, 0 failures, 0 errors, 0 skips

Diffing example:

test_resetting_defaults                                         FAIL (0.00s)
        --- expected
        +++ actual
        @@ -1 +1 @@
        -"https://demo.imgix.net/images/demo.png?w=200&s=da421114ca238d1f4a927b889f67c34e"
        +"https://demo.imgix.netfalse?w=200&s=59a2133b87f1b07792f54601d0988c77"
        /Users/Luis/Documents/imgix/libraries/imgix-rb/test/units/path_test.rb:23:in `test_resetting_defaults'

Tests can also be run in VSCode as the default test task, SHIFT + COMMAND + T in my system for example.

Up for discussion

One of the ways this code base could be improved would be to re-name a lot of the methods. This library exposes a to_url method instead of a build_url method like some of the others for example. Moreover, the logic for path encoding is separate from the rest of the library, but that's not how the projects are organized elsewhere.

@luqven luqven self-assigned this Apr 6, 2021
@commit-lint
Copy link

commit-lint bot commented Apr 6, 2021

Chore

  • vscode: add test task (034f461)
  • minitest: add reporters gem (a9dfa33)
  • vscode: make test task default (2954cab)
  • utf8: remove unused helper fn (0c0c6ff)
  • sanitizePath: make method private and call it in to_url (bb4674e)
  • encodeURI: refactor and add comments for clarity (efc732f)

Tests

  • minitest: use reporters gem to create human readbale output (d0dd15e)
  • path: add delimiter & relative path tests (7b7bce8)
  • unicode: ensure unicode chars are encoded (6d416df)
  • change reserved delimiters to resolvable url (40ec089)
  • remove comment and duplicated import (3fd79ce)

Bug Fixes

  • path: correctly encode reserved chars (701020f)

Styles

Contributors

luqven

Commit-Lint commands

You can trigger Commit-Lint actions by commenting on this PR:

  • @Commit-Lint merge patch will merge dependabot PR on "patch" versions (X.X.Y - Y change)
  • @Commit-Lint merge minor will merge dependabot PR on "minor" versions (X.Y.Y - Y change)
  • @Commit-Lint merge major will merge dependabot PR on "major" versions (Y.Y.Y - Y change)
  • @Commit-Lint merge disable will desactivate merge dependabot PR
  • @Commit-Lint review will approve dependabot PR
  • @Commit-Lint stop review will stop approve dependabot PR

Copy link
Contributor

@sherwinski sherwinski left a comment

Choose a reason for hiding this comment

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

LGTM! And I'm glad to see some much needed improvements to the test runner.
To try and address some of your other points and questions:

This library exposes a to_url method instead of a build_url method like some of the others for example.

Unfortunately, we can't do much about this inconsistency since it is a part of the library's public API. But for anything else (like helper and private methods), feel free to refactor them to make the naming consistent across the kit.

Moreover, the logic for path encoding is separate from the rest of the library, but that's not how the projects are organized elsewhere.

Fun fact, imgix-rb was the first of the imgix SDK libraries. As a result, it's a lot unlike the other projects in most cases (Client -> path -> to_url). Like I just mentioned, we're open to reorganizing things so long as it's unnoticeable to end users.

def to_url(opts = {})
@path = sanitize_path(@path)
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Will this cause multiple encoding issues if to_url is called multiple times on the same Path? Perhaps a different ivar name and ||= sanitize_path(@path) could be used instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great suggestion 💯 , I'll try this out locally and push the change if all looks good.

@sherwinski
Copy link
Contributor

Oh also another note, #105 #103 introduced some performance benchmarks which I think we should extend and take advantage of. For example, you can try running all benchmarks in main and compare it to same benchmarks in this library to see if there are any noticeable performance regressions/improvements.
Eventually I'd like have this built into default tests but for now we can stick to running them manually.

# otherwise, encode only specific characters
return encode_URI(path)
end
end
Copy link
Contributor

Choose a reason for hiding this comment

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

In the Variant PR, which shifts a lot of this escaping/encoding work to application boot, this would ideally be done in the Variant initializer: https://github.com/imgix/imgix-rb/pull/104/files#diff-f7f33d40dff4d8a40100ac8a68f7fab2e082a98a683b678c8ee04c1bc930102aR8

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Haven't had a chance to dig into #104 too much, but loved what I saw so far. Will definitely keep this in mind.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion @stevehodgkiss. I could not find any encoding issues when to_url is called multiple times on the same Path, but I’m sure there will be edge cases that I haven’t thought of. Also, I think the ivar for sanitized_path creates a more predictable experience for the user.

I’ve implemented a solution based on your idea:

def to_url(opts = {})
sanitized_path ||= sanitize_path(@path)
prev_options = @options.dup
@options.merge!(opts)
current_path_and_params = path_and_params(sanitized_path)
url = @prefix + current_path_and_params
if @secure_url_token
url += (has_query? ? "&" : "?") + "s=#{signature(current_path_and_params)}"
end

Before these changes, @path was being modified in a way that was not explicit. There may be a case in the future where we want an @sanitized_path var or a santize_path! func, but for the purposes of this PR that is out of scope.

There are a lot of improvements needed in this file and the library throughout, but I felt these changes have to least potential for producing breaking changes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks good! I take back my previous comment about "this would ideally be done in the Variant initializer". This can't be done there since it's about the Path itself, not the Variant.

@luqven
Copy link
Contributor Author

luqven commented Apr 13, 2021

My apols, blew up the commit history locally without realizing. Never push before your first cup of coffee ☕ 😴

Copy link
Contributor

@ericdeansanchez ericdeansanchez left a comment

Choose a reason for hiding this comment

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

At minimum, I think we need to have the tests for those other two paths I mentioned, other than that, looks good 👍

lib/imgix/path.rb Outdated Show resolved Hide resolved
test/units/path_test.rb Outdated Show resolved Hide resolved
test/units/path_test.rb Show resolved Hide resolved
test/test_helper.rb Outdated Show resolved Hide resolved
end

def to_url(opts = {})
sanitized_path ||= sanitize_path(@path)
prev_options = @options.dup
@options.merge!(opts)
Copy link
Contributor

Choose a reason for hiding this comment

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

Not related to this PR, but it would be great if this state mutation could be removed by passing state in method calls, like you're doing with sanitized_path.

lib/imgix/path.rb Outdated Show resolved Hide resolved
luqven and others added 2 commits April 19, 2021 09:48
Copy link
Contributor

@ericdeansanchez ericdeansanchez left a comment

Choose a reason for hiding this comment

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

LGTM 👍

Copy link
Contributor

@sherwinski sherwinski left a comment

Choose a reason for hiding this comment

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

👍

@luqven luqven merged commit 363ccc2 into main Apr 22, 2021
@luqven luqven deleted the luis/pathEncoding branch April 22, 2021 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants