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

JSON endpoints accept 'text/plain' in JSON format #726

Closed
cmaitchison opened this issue Aug 18, 2014 · 13 comments
Closed

JSON endpoints accept 'text/plain' in JSON format #726

cmaitchison opened this issue Aug 18, 2014 · 13 comments

Comments

@cmaitchison
Copy link

According to the Grape documentation, this endpoint should only accept JSON requests, and all other formats should result in a 406 response code.

The following API will only respond to the JSON content-type and will not parse any other input than application/json, application/x-www-form-urlencoded, multipart/form-data, multipart/related and multipart/mixed. All other requests will fail with an HTTP 406 error code.

class Twitter::API < Grape::API
  format :json
  default_format :json
end

I am finding that posting text/plain in JSON format does not result in a 406. Debugging within the endpoint shows that env['CONTENT_TYPE'] is indeed text/plain.

@dblock dblock added the bug? label Aug 18, 2014
@dm1try
Copy link
Member

dm1try commented Aug 21, 2014

The following API will only respond to the JSON content-type and will not parse any other input than application/json, application/x-www-form-urlencoded, multipart/form-data, multipart/related and multipart/mixed. All other requests will fail with an HTTP 406 error code.

class Twitter::API < Grape::API
  format :json
end

When the content-type is omitted, Grape will return a 406 error code unless default_format is specified. The following API will try to parse any data without a content-type using a JSON parser.

class Twitter::API < Grape::API
  format :json
  default_format :json
end

This is definitely a bug. Those two cases described in README are not valid anymore if the request content-type is omitted. Also if default_format is present the provided content type is ignored.

@cmaitchison Could you try to fix this or maybe write some specs? Thanks!

@dm1try dm1try added confirmed bug and removed bug? labels Aug 21, 2014
@cmaitchison
Copy link
Author

Can do! Thanks for taking a look.

@dblock
Copy link
Member

dblock commented Dec 16, 2014

Bump @cmaitchison, would love some help.

@Morred
Copy link
Contributor

Morred commented Jan 4, 2015

Added a spec for the described issue. Seems like this only happens when default_format is set? When I comment it out, the spec will pass.
(Sorry for the double commit reference, the second one is relevant.)

@rodzyn
Copy link
Contributor

rodzyn commented Jan 5, 2015

@Morred this behaviour is by design I guess

It's described few paragraphs above in README

GET /hello.xls with an Accept: text/plain header has an unrecognized extension and an unrecognized Accept header, so it will respond with JSON (the default format).

So if we specified default_format, any unrecognized stuff will be treated as format defined by default_format (request/response headers).

The other thing is when we don't provide any Content-Type header at all and we didn't set default_format. Then, sadly we don't have any checks performed that could return 406. I've already made some changes that make it possible so PR is coming.

@Morred
Copy link
Contributor

Morred commented Jan 7, 2015

@rodzyn Thanks for clarifying, I assumed this part of the documentation means that default_format will only kick in if there is no content type specified and things with the wrong content type will still be rejected.

@dm1try
Copy link
Member

dm1try commented Aug 20, 2015

Honestly I have the same feelings as @Morred about this part of the documentation mentioned above.

Also some things are ambiguous to me in the current implementation with default_format.
For example
curl localhost:9292 -d '{}' -H "Content-Type: invalid/type"

class API < Grape::API
  format :json
  default_format :json

  post do
    request.content_type # invalid/type
    params               # but the input is parsed as JSON already
  end
end

@cmaitchison mentioned that thing in the first comment

endpoint shows that env['CONTENT_TYPE'] is indeed text/plain.

@dblock any thoughts?

@dblock
Copy link
Member

dblock commented Aug 20, 2015

So there're two sides of the story: what you supply as content-type for POSTed content and what you have in an Accept header in return. So I think we want this:

  • Content-type: invalid/type should fail with an error, default format or not.
  • no content-type should use the default parser via default format.
  • no Accept: ... should use the default formatter.
  • Accept: some/type that is not supported by the API should fail instead of default formatting.
  • Accept: some/type should decide which formatter to use by default.

This issue already is a confirmed bug (thx @dm1try), I'll take PRs in those lines with careful UPGRADING docs.

@richddr
Copy link

richddr commented Apr 28, 2016

is there any update on this issue?

@dblock
Copy link
Member

dblock commented Jan 14, 2017

There's a spec in #877 and no fix. Someone please contribute.

@Morred
Copy link
Contributor

Morred commented Jan 18, 2017

Ah, I wrote that spec, forever ago. Will have a look when I get a bit of free time this week!

@inclooder
Copy link
Contributor

Hi, I'd like contribute if no one else is working on that.

inclooder pushed a commit to netguru/grape that referenced this issue Mar 9, 2017
@dblock dblock closed this as completed in 132f232 Mar 10, 2017
dblock added a commit that referenced this issue Mar 10, 2017
@dblock
Copy link
Member

dblock commented Mar 10, 2017

Please try HEAD from #1589, thanks @inclooder!

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

No branches or pull requests

7 participants