10

I'm trying to create a route with Sinatra that only accepts POST with an Content-type: application/json without success.

My approach is as follows:

post '/dogs', :provides => :json do
  # returns here a json response
end

Testing with curl, I have seen that :provides => :json configures the route to respond with an Content-Type: application/json.

That's right because I want also to respond with a JSON message to the POST request but I really need that this route only respond to POST requests with a Content-Type: application/json and not, for example, to others (e.g. Content-Type: application/xml).

Is there any way in Sinatra to restrict the route to only accept requests with a certain Content-Type?

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
jfcalvo
  • 459
  • 1
  • 5
  • 16

3 Answers3

12

Requests do not contain "Content-Type" header, but rather have "Accept". Sinatra should basically only respond to requests with "Accept" containing "application/json". Just to make sure:

post '/gods', :provides => :json do
  pass unless request.accept? 'application/json'
...
end
phil pirozhkov
  • 4,740
  • 2
  • 33
  • 40
  • 3
    Phil I don't think so, in fact it is a good idea to provide both a `Content-Type` and `Accept` at a POST header HTTP request. For example you could have `Content-Type: application/json` and in the next line of the POST header `Accept: application/json`. – jfcalvo Nov 23 '11 at 14:00
  • All in the case of course that you are providing a JSON content in the POST request and waiting a response in JSON format too. – jfcalvo Nov 23 '11 at 14:12
  • There's no such thing as "Content-Type" for a request. Read this http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.3 – phil pirozhkov Nov 23 '11 at 20:53
  • And there's no option to understand what kind of data was provided in POST except for agreement. – phil pirozhkov Nov 23 '11 at 20:59
  • You are right Phil, in the HTTP 1.1 RFC there is not a `Content-Type` option header for requests. I will try to validate the body content as a valid JSON and send an error if `Accept` not contains a `application\json`. – jfcalvo Nov 24 '11 at 08:31
  • what does "pass" mean? there is no this keyword in Ruby. – Alan Coromano Feb 05 '13 at 13:36
  • @AlanDert this [is coming](http://www.sinatrarb.com/intro.html#Passing) from Sinatra – phil pirozhkov Feb 05 '13 at 21:28
  • 14
    Content-type actually comes under the Entity section, http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html. It is a valid header on a request or response to correct the above. "Accept" is used to define what you as the client as willing to recieve back (you can define more than one). "Content-type" is what the request/response is made up of. Ie, if I'm POSTing json to an endpoint, the content-type needs to be application/json – Bealer May 03 '13 at 22:30
11

Read this

http://rack.rubyforge.org/doc/classes/Rack/Request.html

request.content_type will tell you

Phil might be right regarding RFC but in reality many things put a content-type in a POST request, therefore it is useful to know what it is.

Geoff
  • 111
  • 2
0

i would think it is something like:

pass unless request.accept? == 'application/json'
Mischa Molhoek
  • 164
  • 1
  • 9