-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Conversation
dc46fd7
to
29f172b
Compare
There was a problem hiding this 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! :)
kong/core/router.lua
Outdated
if upstream_path then | ||
if new_uri == "/" then | ||
new_uri = upstream_path | ||
else |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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?
kong/core/router.lua
Outdated
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 .. "/" |
There was a problem hiding this comment.
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?).
There was a problem hiding this comment.
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.
kong/core/router.lua
Outdated
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.
kong/core/router.lua
Outdated
|
||
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?)
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 thecheck()
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 thecheck()
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).
There was a problem hiding this comment.
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.
6822d93
to
1045892
Compare
(The router has always been written with the new code style) |
I don't think any of those components are touching the URI. Testing with unit tests is a huge benefit for us because of the speed. Ideally this should be tested in both places. Modifying the router is dangerous and be able to do so and simply progress with the quick unit tests is very valuable, hence why the router is mainly tested with unit tests.
… On Apr 4, 2017, at 2:32 AM, Aapo Talvensaari ***@***.***> wrote:
@bungle commented on this pull request.
In spec/02-integration/05-proxy/01-router_spec.lua:
> + for _, args in ipairs(checks) do
+
+ local config = "(strip_uri = n/a)"
+
+ if args[4] == true then
+ config = "(strip_uri = on) "
+ elseif args[4] == false then
+ config = "(strip_uri = off)"
+ end
+
+ local space = string.sub(args[1], -1) == "/" and "" or " "
+
+ it(config .. " is not appended to upstream uri " .. args[1] .. space .. " when requesting " .. args[2],
+ check(unpack(args)))
+ end
+ end)
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.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
On my machine the added tests run in 250 ms, while the router tests in total take 11,570 ms. |
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. |
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... |
1045892
to
7ba162c
Compare
Tests added to unit test suite as well. |
7ba162c
to
54ce75d
Compare
…xtensive testing suite Triggers #2334 (01-router_spec.lua)
Very cool! I just merged this in |
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