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(admin) unsupported media type (415) error reported on issue #1182 #3077

Merged
merged 1 commit into from
Dec 14, 2017

Conversation

bungle
Copy link
Member

@bungle bungle commented Dec 7, 2017

Summary

Fixes issue when using empty body with supported content-types on POST / PUT / PATCH.

Issues resolved

Fix #1182

@bungle bungle force-pushed the fix/unsupported-media-type branch 4 times, most recently from 0f0c0ae to 8c51dda Compare December 7, 2017 21:27
@bungle
Copy link
Member Author

bungle commented Dec 7, 2017

One note:

  1. when using application/json content type
  2. empty body

This results:

{
    "message": "Cannot parse JSON body"
}

Not sure though, should we allow this to go through as we do with multipart/form-data and application/x-www-form-urlencoded (they don't error on parsing errors).

@bungle bungle force-pushed the fix/unsupported-media-type branch from 8c51dda to 1268c11 Compare December 7, 2017 22:02
@bungle
Copy link
Member Author

bungle commented Dec 7, 2017

This also contains (apart from added tests) fixes to 02-apis_routes_spec.lua which was bit strangely organized and was also flaky on my machine. The admin client is not happy to be reused on errors (it sometimes closes itself).

@bungle bungle force-pushed the fix/unsupported-media-type branch from 1268c11 to 59d315a Compare December 7, 2017 22:30
return responses.send_HTTP_UNSUPPORTED_MEDIA_TYPE()
if not NEEDS_BODY[ngx.req.get_method()] then
return
end
Copy link
Member

Choose a reason for hiding this comment

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

👏


if not content_length then
local _, err = ngx.req.socket()
if err == "no body" then
Copy link
Member

Choose a reason for hiding this comment

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

It seems to me like the check done by ngx_lua to return this error is the one we are already making above, L.100? See: https://github.com/openresty/lua-nginx-module/blob/master/src/ngx_http_lua_socket_tcp.c#L4371-L4375

Maybe we don't need this check?

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 think the first one checks client header and the other checks if there is no body even when the client didn't add content-length header. I may be wrong and have to recheck this. I assume client can set that header to say 1000, but still doesn't send body.

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 rechecked this and test is needed.

Copy link
Member

Choose a reason for hiding this comment

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

Hmmm, would you care to elaborate why? It seems to me that in our current code path (that is, not calling ngx.req.init_body(), not calling ngx_http_lua_create_fake_request, and not making a subrequest), the only place where content_length_n is set is: https://github.com/openresty/lua-nginx-module/blob/b122ed7ad2a6bf6f90d8d5c5939c0dd98a4ddbf7/src/ngx_http_lua_headers_in.c#L570 - in which case, the value is taken from the Content-Length header already. So when ngx.req.socket() returns "no body", it means it has did the same check as the one above, L.100 (actually, content_length_n <= 0).

Am I missing something?

Copy link
Member

Choose a reason for hiding this comment

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

This and the /apis endpoint concern are the last "blockers" for me. But feel free to dismiss if I just said non-sense above ^

Apart from those 2 points, this is GTM 👍

@@ -87,6 +88,54 @@ describe("Admin API #" .. kong_config.database, function()
end)

describe("errors", function()
it("returns 415 on invalid content-type", function()
Copy link
Member

Choose a reason for hiding this comment

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

Should we maybe not include those tests as part of the /apis route test suite, considering our recent work on the model and the uncertain future of this test suite?

Copy link
Member

Choose a reason for hiding this comment

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

Ping here as well - I would say this is concerning considering this endpoint (or its underlying implementation) may disappear soon?

@@ -259,6 +315,55 @@ describe("Admin API #" .. kong_config.database, function()
end
end)
describe("errors", function()
it("returns 415 on invalid content-type", function()
local res = assert(client:request {
method = "POST",
Copy link
Member

Choose a reason for hiding this comment

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

Are those tests duplicates of the above ones? Maybe the intent was to re-run them with PUT?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, a copy-paste-bug. Pushed a new version.

@@ -206,7 +260,7 @@ describe("Admin API #" .. kong_config.database, function()
--
-- Eventually, our Admin endpoint will follow a more appropriate
-- behavior for PUT.
local res = assert(client:send {
local res = assert(helpers.admin_client():send {
Copy link
Member

Choose a reason for hiding this comment

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

Curious: why not using client here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because the test generates 404 and it makes the client really flaky as you see it runs this it_content_types loop, so first time it works, but subsequently you start getting:

spec/02-integration/04-admin_api/02-apis_routes_spec.lua:263: closed

The client is really problematic, because you cannot really call :send multiple times without getting into issues. That's why. To make tests pass reliably.

Copy link
Member

Choose a reason for hiding this comment

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

Ohh I see - hmmm

path = "/apis",
headers = {["Content-Type"] = "application/json"}
})
assert.res_status(400, res)
Copy link
Member

Choose a reason for hiding this comment

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

When we are returning a 400 error here, I think a second assertion for the body should be added for explicitness, ensuring that it is a schema error from our DAO (and not a Lapis error or some other sort of error).

@thibaultcha
Copy link
Member

Not sure though, should we allow this to go through as we do with multipart/form-data and application/x-www-form-urlencoded (they don't error on parsing errors).

Good point. I would tend to say this behavior (reporting an invalid JSON payload) is fine. After all, a client would encounter the same error if they attempted to send an invalid JSON payload ({"hello":"world"), and it seems logical that the same error happen in both cases I think.

@thibaultcha thibaultcha added this to the 0.12.0 milestone Dec 8, 2017
@bungle bungle force-pushed the fix/unsupported-media-type branch 3 times, most recently from c4fb270 to 74e96f9 Compare December 14, 2017 18:38
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.

2 participants