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(router) fix trailing slash getting automatically appended #2315

Closed
wants to merge 2 commits into from

Conversation

bungle
Copy link
Member

@bungle bungle commented Mar 31, 2017

Summary

Trailing slashes get automatically appended to proxied uris and sometimes double (//) slashes. This PR is meant to follow the original request uri semantics regarding the trailing slash, and forward it as is the proxied service. Making the proxying more transparent.

Revert some of the changes introduced in #2115.

Issues resolved

Fix: #2211

@bungle bungle force-pushed the fix/trailing-slashes branch 2 times, most recently from dc46fd7 to 29f172b Compare April 3, 2017 09:36
@Tieske Tieske added this to the 0.10.2 milestone Apr 3, 2017
Copy link
Member

@thibaultcha thibaultcha left a comment

Choose a reason for hiding this comment

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

Apart from the few style issues, the biggest blocker is moving the tests to where they belong imho (the unit suite where some already exists for this URI behavior). Additionally, I believe a small perf improvement could be done as well. It's all in the comments! :)

if upstream_path then
if new_uri == "/" then
new_uri = upstream_path
else
Copy link
Member

Choose a reason for hiding this comment

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

style: could we add the missing line jump before that else?

Copy link
Member Author

Choose a reason for hiding this comment

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

I can do that, is it so that we are basically using new style on new code (or changes) even if the rest of the file is in other style?

if new_uri_slash and not req_uri_slash and new_uri ~= "/" then
new_uri = sub(new_uri, 1, -2)
elseif not new_uri_slash and req_uri_slash and uri ~= "/" then
new_uri = new_uri .. "/"
Copy link
Member

Choose a reason for hiding this comment

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

Could we enclose this whole block in such a condition:

if new_uri ~= "/" then
  local req_uri_slash =
  local new_uri_slash =
  -- ...
end

It seems like this is not necessary in such a case, and additionally, we avoid repeating the and new_uri ~= "/" condition (which apparently has a typo on L.618 btw?).

Copy link
Member Author

@bungle bungle Apr 4, 2017

Choose a reason for hiding this comment

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

It is not a typo, so this cannot be done.

local new_uri_slash = sub(new_uri, -1) == "/"
if new_uri_slash and not req_uri_slash and new_uri ~= "/" then
new_uri = sub(new_uri, 1, -2)
elseif not new_uri_slash and req_uri_slash and uri ~= "/" then
Copy link
Member

Choose a reason for hiding this comment

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

style: missing line jump prior to this elseif statement

Copy link
Member Author

Choose a reason for hiding this comment

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

ok.


local req_uri_slash = sub(uri, -1) == "/"
local new_uri_slash = sub(new_uri, -1) == "/"
if new_uri_slash and not req_uri_slash and new_uri ~= "/" then
Copy link
Member

Choose a reason for hiding this comment

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

style: a line jump before such statements if complex is also preferred for readability. The only exception is for testing nil out of a recently retrieved value, such as:

local upstream_path = ...
if upstream_path then

end

or the famous:

local ok, err = thing()
if not ok then

end

Copy link
Member Author

Choose a reason for hiding this comment

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

ok, i will make a change.

Copy link
Member

Choose a reason for hiding this comment

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

maybe add one final commit with all the style changes, updating the entire file?

Copy link
Member Author

@bungle bungle Apr 4, 2017

Choose a reason for hiding this comment

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

@Tieske I once asked @coopr, and he said that we don't intently have boy scout practices in place. And I believe I will end down to a rabbit hole with this patch, if I try. As the style guide is for me mostly a fuzzy logic with many many exceptions like the above. Even the above comment makes me think, what is "complex".

E.g. is a function call with many arguments a complex?

local api_t = find_api(method, uri, req_host)

What about:

local api_t = find_api(method, uri, {
    something = 1
})

(is that still simple?)

Copy link
Member

Choose a reason for hiding this comment

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

I think @thibaultcha meant

  local req_uri_slash = sub(uri,     -1) == "/"
  local new_uri_slash = sub(new_uri, -1) == "/"

  if new_uri_slash and not req_uri_slash and new_uri ~= "/" then

just a line jump, to make it visually easier to read

it(config .. " is not appended to upstream uri " .. args[1] .. space .. " when requesting " .. args[2],
check(unpack(args)))
end
end)
Copy link
Member

@thibaultcha thibaultcha Apr 4, 2017

Choose a reason for hiding this comment

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

I feel like this test suite is quite complicated to maintain. Maybe more that just "quite", even.

Couldn't we come up with something more descriptive, like:

local checks = {
{
  api = {
    uris = { "/", "/foo/bar" },
    upstream_url = "http://localhost:9999/",
  },
  -- request_uri    expected_upstream_uri
  { "/",         "/" },
  { "/foo/",     "/foo/" },
},
{
  api = {
    uris = { "/foo/bar/" },
    upstream_url = "http://localhost:9999/foo",
  },
  -- request_uri    expected_upstream_uri
  { "/foo/",    "/foo/" },
  { "/foo",      "/foo" },
}
}

(with better alignment of the comments of course).

Also, let's note that an API with uris=/,/foo/bar does not really make sense in those tests since we are focusing on post-matching behavior. We should probably only declare APIs with uris=/foo/bar or uris=/foo/bar/ with both strip_uri=true|false for the sake of simplicity?

Structuring the tests this way would have the benefits of:

  • grouping APIs declaration, input values and expected outputs together.
  • adding a comment header to each value of the table that has declarative tests input/output values, so we know what they refer to.
  • avoid the i = i + n logic in the check() closure, which is asks for a lot of cognitive load when debugging.
  • we can still build a nice loop that generates tests and messages as already done
  • it's easier to separate the use cases per API in the the checks table (currently they are all grouped together and we don't know which test belongs to which API without reading the check() closure.

Additionally, I strongly believe those tests should be part of the 01-unit test suite, as per the router tests. They should most probably be moved in the router_spec tests over there, which already mocks the ngx object and allows for testing of the newly set URI (as currently already tested there). Since this feature extends the same part of the code, the tests should be over there. They will also be much faster, and avoid the need for extending the custom_nginx.template file (which was a quick fix but should be avoided as much as possible for now).

Copy link
Member Author

Choose a reason for hiding this comment

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

Just a quick note, router specs are not going through the whole pipeline to the API/service, hence it really does not test that slash at the end really behaves correctly all the way to the end. Router is just a one component in this equation. There are Nginx configs, proxy etc. in addition.

@thibaultcha thibaultcha added pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. and removed pr/status/needs review labels Apr 4, 2017
@bungle bungle force-pushed the fix/trailing-slashes branch 4 times, most recently from 6822d93 to 1045892 Compare April 4, 2017 13:40
@bungle bungle added pr/status/needs review and removed pr/changes requested Changes were requested to this PR by a maintainer. Please address them and ping back once done. labels Apr 4, 2017
@thibaultcha
Copy link
Member

(The router has always been written with the new code style)

@thibaultcha
Copy link
Member

thibaultcha commented Apr 4, 2017 via email

@bungle
Copy link
Member Author

bungle commented Apr 4, 2017

On my machine the added tests run in 250 ms, while the router tests in total take 11,570 ms.

@thibaultcha
Copy link
Member

Regardless, such tests belong to the router unit tests considering they are the tests for this component and all of the other features of the router (except this one) are being tested there.

@thibaultcha
Copy link
Member

Not doing so would make future contributors having to run both tests suites now. It also is slower to iterate with it in the sense that the integration test suite needs a running DB, a running Kong instance, migrations to be run before the test, etc...

@bungle bungle force-pushed the fix/trailing-slashes branch from 1045892 to 7ba162c Compare April 4, 2017 17:55
@bungle
Copy link
Member Author

bungle commented Apr 4, 2017

Tests added to unit test suite as well.

@bungle bungle force-pushed the fix/trailing-slashes branch from 7ba162c to 54ce75d Compare April 4, 2017 18:16
@Tieske Tieske mentioned this pull request Apr 5, 2017
…xtensive testing suite

Triggers #2334 (01-router_spec.lua)
@bungle
Copy link
Member Author

bungle commented Apr 5, 2017

@thibaultcha

The latest commit:
62e0091

  • has performance tunings
  • enhances readability of router.lua
  • has more extensive testing suite

But, it will also trigger a bug in a router, possibly related to #2334.

@bungle bungle dismissed thibaultcha’s stale review April 7, 2017 13:08

It is already done, as requested.

@thibaultcha
Copy link
Member

Very cool! I just merged this in master for a 0.10.2 release, with minor changes in the commit messages and a few conflicts fixed. Thank you @bungle!

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