Require content-type 'application/json' for appropriate requests in Rails
<p>I have an API that handles almost exclusively <code>application/json</code> in Rails. A few endpoints can handle <code>application/x-www-form-urlencoded</code> for file-uploads.</p>
<p>I want to enforce the content-types: when a client adds anything other than <code>application/json</code> I want to send an 406 - not acccepted error back, in my <code>ApplicationController</code></p>
<pre><code>before_action :require_content_type_json

def require_content_type_json
  return if request.content_type == Mime::JSON.to_s
  head status: 406
end
</code></pre>
<p>However, <a href="https://www.rfc-editor.org/rfc/rfc7231#section-3.1.1.5" rel="nofollow noreferrer">RFC 7231 (http)</a> states that:</p>
<blockquote>
<p>A sender that generates a message containing a payload body SHOULD
generate a Content-Type header field in that message unless the
intended media type of the enclosed representation is unknown to the
sender.  If a Content-Type header field is not present, the recipient
MAY either assume a media type of &quot;application/octet-stream&quot;
([RFC2046], Section 4.5.1) or examine the data to determine its type.</p>
</blockquote>
<p>I roughtly interpret that as &quot;when the request comes with a body, the content-type must be provided by the client, else the server should assume &quot;application/octet-stream&quot;.</p>
<p>Since I cannot handle octet-stream, I want to return 406 - not accepted too, there. In other words: when there is a body, a header setting the content-type to &quot;application/json&quot; should be present. Always.</p>
<p>So, how do I detect whether a user should have sent a content-type header along? Is it enough to simply check for <code>!request.body.empty?</code>: body is not empty?</p>
<p>Or should I assume that only GET/OPTIONS/HEAD requests have no body and all others do and should require a content-type?</p>
<p>Does Rails have any helpers or classes in place to deal with this?</p>