In earlier versions, this would work:
ActionController::Renderers.add(:foo) do | data, options |
self.content_type = 'application/foo; bar=1'
end
In 4.2.4, this causes the Content-Type header to be blank. However, the following works, i.e., sets the Content-Type header to the string assigned to content_type:
ActionController::Renderers.add(:foo) do | data, options |
self.content_type = 'application/foo'
end
The other approach I know of, setting content_type on the render, seems to have no result anymore, i.e., render('foo', content_type: 'application/foo')
doesn't set the header (never mind trying application/foo; bar=1.)
The Content-Type representation header is used to indicate the original media type of the resource (prior to any content encoding applied for sending). In responses, a Content-Type header provides the client with the actual content type of the returned content.
If a Content-Type header field is not present, the recipient MAY either assume a media type of "application/octet-stream" ([RFC2046], Section 4.5. 1) or examine the data to determine its type. It means that the Content-Type HTTP header should be set only for PUT and POST requests.
Since (by validity of the input spec) there are no content types for GET requests, you will always default to application/json .
2.2. By default, if you use the :plain option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the layout: true option and use the . text. erb extension for the layout file.
First take a look at the documentation (Section 2.2.13.1):
http://guides.rubyonrails.org/layouts_and_rendering.html#using-render
The example they give there uses your alternative approach, setting content_type
when using render
:
render file: filename, content_type: "application/rss"
I tested this strategy in a vanilla Rails 4.2.4 application. This is how I defined the controller:
class WelcomeController < ApplicationController
def index
render inline: 'Hello World', content_type: 'application/foo; bar=1'
end
end
And here is what I see in Chrome's network inspector when I hit that action, note the Content-Type
under Response Headers:
General
Remote Address:[::1]:3000
Request URL:http://localhost:3000/
Request Method:GET
Status Code:200 OK
Response Headers
Cache-Control:max-age=0, private, must-revalidate
Connection:Keep-Alive
Content-Length:11
Content-Type:application/foo; bar=1; charset=utf-8
Date:Tue, 29 Sep 2015 02:53:39 GMT
Etag:W/"b10a8db164e0754105b7a99be72e3fe5"
Server:WEBrick/1.3.1 (Ruby/2.2.2/2015-04-13)
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:3825d446-44dc-46fa-8aed-630dc7f001ae
X-Runtime:0.022774
X-Xss-Protection:1; mode=block
Sean Huber is correct and the code in the question is correct. Except in the case of having registered a MIME type and then rendering files of that type, e.g.,
Mime::Type.register('application/foobar', :foobar)
render('view') # where view is actually view.foobar.jbuilder
In this case, the type string registered appears to always override the approaches available for setting content type explicitly. This can lead to thinking that the media type parameters are being stripped because, coincidentally, ParamsParser selection appears to "break" when media type parameters are specified for a default parser, i.e., a parser registered for 'application/foo; bar=1' will not parse content provided with that content type, leading one to use a parameterless string for the mime type string and then attempting to override with one including the parameters.
So, to get around that in 4.2, I've removed the ParamsParser and Render registrations and moved to a before_filter on a parent controller and the content type header to an after_filter, e.g.,
class BaseController < ApplicationController
before_filter :parse_body
after_filter :set_content_type
attr_accessor :parsed
def parse_body
self.parsed = JSON.load(request.body)
end
def set_content_type
self.content_type = "application/foo; bar=1; charset=utf-8"
end
end
Note: this is quite the hack/workaround; not recommended for long-term use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With