Change `ActionDispatch::Response#content_type` returning Content-Type header as it is

Since #35709, `Response#conten_type` returns only MIME type correctly.
It is a documented behavior that this method only returns MIME type, so
this change seems appropriate.
39de7fac05/actionpack/lib/action_dispatch/http/response.rb (L245-L249)

But unfortunately, some users expect this method to return all
Content-Type that does not contain charset. This seems to be breaking
changes.

We can change this behavior with the deprecate cycle.
But, in that case, a method needs that include Content-Type with
additional parameters. And that method name is probably the
`content_type` seems to properly.

So I changed the new behavior to more appropriate `media_type` method.
And `Response#content_type` changed (as the method name) to return Content-Type
header as it is.

Fixes #35709.

[Rafael Mendonça França & Yuuji Yaginuma ]
This commit is contained in:
yuuji.yaginuma 2019-04-17 15:37:16 +09:00
parent d3e87efedb
commit ea5f509643
23 changed files with 171 additions and 120 deletions

View File

@ -148,7 +148,7 @@ module ActionController
attr_internal :response, :request
delegate :session, to: "@_request"
delegate :headers, :status=, :location=, :content_type=,
:status, :location, :content_type, to: "@_response"
:status, :location, :content_type, :media_type, to: "@_response"
def initialize
@_request = nil

View File

@ -205,7 +205,7 @@ module ActionController #:nodoc:
yield collector if block_given?
if format = collector.negotiate_format(request)
if content_type && content_type != format
if media_type && media_type != format
raise ActionController::RespondToMismatchError
end
_process_format(format)

View File

@ -157,7 +157,7 @@ module ActionController
json = json.to_json(options) unless json.kind_of?(String)
if options[:callback].present?
if content_type.nil? || content_type == Mime[:json]
if media_type.nil? || media_type == Mime[:json]
self.content_type = Mime[:js]
end

View File

@ -73,7 +73,7 @@ module ActionController
end
def _set_rendered_content_type(format)
if format && !response.content_type
if format && !response.media_type
self.content_type = format.to_s
end
end

View File

@ -243,8 +243,13 @@ module ActionDispatch # :nodoc:
end
# Content type of response.
# It returns just MIME type and does NOT contain charset part.
def content_type
type = super
type&.empty? ? nil : type
end
# Media type of response.
def media_type
parsed_content_type_header.mime_type
end
@ -458,7 +463,7 @@ module ActionDispatch # :nodoc:
end
def assign_default_content_type_and_charset!
return if content_type
return if media_type
ct = parsed_content_type_header
set_content_type(ct.mime_type || Mime[:html].to_s,

View File

@ -14,7 +14,7 @@ module ActionDispatch
include Rails::Dom::Testing::Assertions
def html_document
@html_document ||= if @response.content_type.to_s.end_with?("xml")
@html_document ||= if @response.media_type.to_s.end_with?("xml")
Nokogiri::XML::Document.parse(@response.body)
else
Nokogiri::HTML::Document.parse(@response.body)

View File

@ -19,7 +19,7 @@ module ActionDispatch
end
def response_parser
@response_parser ||= RequestEncoder.parser(content_type)
@response_parser ||= RequestEncoder.parser(media_type)
end
end
end

View File

@ -66,68 +66,68 @@ class ContentTypeTest < ActionController::TestCase
def test_render_defaults
get :render_defaults
assert_equal "utf-8", @response.charset
assert_equal Mime[:text], @response.content_type
assert_equal Mime[:text], @response.media_type
end
def test_render_changed_charset_default
with_default_charset "utf-16" do
get :render_defaults
assert_equal "utf-16", @response.charset
assert_equal Mime[:text], @response.content_type
assert_equal Mime[:text], @response.media_type
end
end
# :ported:
def test_content_type_from_body
get :render_content_type_from_body
assert_equal Mime[:rss], @response.content_type
assert_equal Mime[:rss], @response.media_type
assert_equal "utf-8", @response.charset
end
# :ported:
def test_content_type_from_render
get :render_content_type_from_render
assert_equal Mime[:rss], @response.content_type
assert_equal Mime[:rss], @response.media_type
assert_equal "utf-8", @response.charset
end
# :ported:
def test_charset_from_body
get :render_charset_from_body
assert_equal Mime[:text], @response.content_type
assert_equal Mime[:text], @response.media_type
assert_equal "utf-16", @response.charset
end
# :ported:
def test_nil_charset_from_body
get :render_nil_charset_from_body
assert_equal Mime[:text], @response.content_type
assert_equal Mime[:text], @response.media_type
assert_equal "utf-8", @response.charset, @response.headers.inspect
end
def test_nil_default_for_erb
with_default_charset nil do
get :render_default_for_erb
assert_equal Mime[:html], @response.content_type
assert_equal Mime[:html], @response.media_type
assert_nil @response.charset, @response.headers.inspect
end
end
def test_default_for_erb
get :render_default_for_erb
assert_equal Mime[:html], @response.content_type
assert_equal Mime[:html], @response.media_type
assert_equal "utf-8", @response.charset
end
def test_default_for_builder
get :render_default_for_builder
assert_equal Mime[:xml], @response.content_type
assert_equal Mime[:xml], @response.media_type
assert_equal "utf-8", @response.charset
end
def test_change_for_builder
get :render_change_for_builder
assert_equal Mime[:html], @response.content_type
assert_equal Mime[:html], @response.media_type
assert_equal "utf-8", @response.charset
end
@ -148,22 +148,22 @@ class AcceptBasedContentTypeTest < ActionController::TestCase
def test_render_default_content_types_for_respond_to
@request.accept = Mime[:html].to_s
get :render_default_content_types_for_respond_to
assert_equal Mime[:html], @response.content_type
assert_equal Mime[:html], @response.media_type
@request.accept = Mime[:js].to_s
get :render_default_content_types_for_respond_to
assert_equal Mime[:js], @response.content_type
assert_equal Mime[:js], @response.media_type
end
def test_render_default_content_types_for_respond_to_with_template
@request.accept = Mime[:xml].to_s
get :render_default_content_types_for_respond_to
assert_equal Mime[:xml], @response.content_type
assert_equal Mime[:xml], @response.media_type
end
def test_render_default_content_types_for_respond_to_with_overwrite
@request.accept = Mime[:rss].to_s
get :render_default_content_types_for_respond_to
assert_equal Mime[:xml], @response.content_type
assert_equal Mime[:xml], @response.media_type
end
end

View File

@ -522,11 +522,11 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
with_test_route_set do
get "/get", headers: { "Accept" => "application/json" }, xhr: true
assert_equal "application/json", request.accept
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
get "/get", headers: { "HTTP_ACCEPT" => "application/json" }, xhr: true
assert_equal "application/json", request.accept
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
end
end
@ -986,7 +986,7 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
def test_encoding_as_json
post_to_foos as: :json do
assert_response :success
assert_equal "application/json", request.content_type
assert_equal "application/json", request.media_type
assert_equal "application/json", request.accepts.first.to_s
assert_equal :json, request.format.ref
assert_equal({ "foo" => "fighters" }, request.request_parameters)
@ -1025,7 +1025,7 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
post_to_foos as: :wibble do
assert_response :success
assert_equal "/foos_wibble", request.path
assert_equal "text/wibble", request.content_type
assert_equal "text/wibble", request.media_type
assert_equal "text/wibble", request.accepts.first.to_s
assert_equal :wibble, request.format.ref
assert_equal Hash.new, request.request_parameters # Unregistered MIME Type can't be parsed.

View File

@ -43,6 +43,6 @@ class LocalizedTemplatesTest < ActionController::TestCase
I18n.locale = :it
get :hello_world
assert_equal "Ciao Mondo", @response.body
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
end

View File

@ -38,13 +38,13 @@ class RenderersMetalTest < ActionController::TestCase
get :one
assert_response :success
assert_equal({ a: "b" }.to_json, @response.body)
assert_equal "application/json", @response.content_type
assert_equal "application/json", @response.media_type
end
def test_render_xml
get :two
assert_response :success
assert_equal(" ", @response.body)
assert_equal "text/plain", @response.content_type
assert_equal "text/plain", @response.media_type
end
end

View File

@ -423,12 +423,12 @@ class RespondToControllerTest < ActionController::TestCase
def test_using_defaults
@request.accept = "*/*"
get :using_defaults
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "Hello world!", @response.body
@request.accept = "application/xml"
get :using_defaults
assert_equal "application/xml", @response.content_type
assert_equal "application/xml", @response.media_type
assert_equal "<p>Hello world!</p>\n", @response.body
end
@ -449,12 +449,12 @@ class RespondToControllerTest < ActionController::TestCase
def test_using_defaults_with_type_list
@request.accept = "*/*"
get :using_defaults_with_type_list
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "Hello world!", @response.body
@request.accept = "application/xml"
get :using_defaults_with_type_list
assert_equal "application/xml", @response.content_type
assert_equal "application/xml", @response.media_type
assert_equal "<p>Hello world!</p>\n", @response.body
end
@ -468,7 +468,7 @@ class RespondToControllerTest < ActionController::TestCase
def test_using_non_conflicting_nested_js_then_js
@request.accept = "*/*"
get :using_non_conflicting_nested_js_then_js
assert_equal "text/javascript", @response.content_type
assert_equal "text/javascript", @response.media_type
assert_equal "JS", @response.body
end
@ -499,12 +499,12 @@ class RespondToControllerTest < ActionController::TestCase
def test_custom_types
@request.accept = "application/fancy-xml"
get :custom_type_handling
assert_equal "application/fancy-xml", @response.content_type
assert_equal "application/fancy-xml", @response.media_type
assert_equal "Fancy XML", @response.body
@request.accept = "text/html"
get :custom_type_handling
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "HTML", @response.body
end
@ -595,7 +595,7 @@ class RespondToControllerTest < ActionController::TestCase
@request.accept = "application/json"
get :json_with_callback
assert_equal "/**/alert(JS)", @response.body
assert_equal "text/javascript", @response.content_type
assert_equal "text/javascript", @response.media_type
end
def test_xhr
@ -605,13 +605,13 @@ class RespondToControllerTest < ActionController::TestCase
def test_custom_constant
get :custom_constant_handling, format: "mobile"
assert_equal "text/x-mobile", @response.content_type
assert_equal "text/x-mobile", @response.media_type
assert_equal "Mobile", @response.body
end
def test_custom_constant_handling_without_block
get :custom_constant_handling_without_block, format: "mobile"
assert_equal "text/x-mobile", @response.content_type
assert_equal "text/x-mobile", @response.media_type
assert_equal "Mobile", @response.body
end
@ -664,7 +664,7 @@ class RespondToControllerTest < ActionController::TestCase
assert_equal '<html><div id="html">Hello future from Firefox!</div></html>', @response.body
get :iphone_with_html_response_type, format: "iphone"
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
end
@ -672,7 +672,7 @@ class RespondToControllerTest < ActionController::TestCase
@request.accept = "text/iphone"
get :iphone_with_html_response_type
assert_equal '<html><div id="iphone">Hello iPhone future from iPhone!</div></html>', @response.body
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_invalid_format
@ -702,7 +702,7 @@ class RespondToControllerTest < ActionController::TestCase
def test_variant_with_implicit_template_rendering
get :variant_with_implicit_template_rendering, params: { v: :mobile }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "mobile", @response.body
end
@ -756,137 +756,137 @@ class RespondToControllerTest < ActionController::TestCase
def test_variant_with_format_and_custom_render
get :variant_with_format_and_custom_render, params: { v: :phone }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "mobile", @response.body
end
def test_multiple_variants_for_format
get :multiple_variants_for_format, params: { v: :tablet }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "tablet", @response.body
end
def test_no_variant_in_variant_setup
get :variant_plus_none_for_format
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "none", @response.body
end
def test_variant_inline_syntax
get :variant_inline_syntax
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "none", @response.body
get :variant_inline_syntax, params: { v: :phone }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
end
def test_variant_inline_syntax_with_format
get :variant_inline_syntax, format: :js
assert_equal "text/javascript", @response.content_type
assert_equal "text/javascript", @response.media_type
assert_equal "js", @response.body
end
def test_variant_inline_syntax_without_block
get :variant_inline_syntax_without_block, params: { v: :phone }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
end
def test_variant_any
get :variant_any, params: { v: :phone }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
get :variant_any, params: { v: :tablet }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "any", @response.body
get :variant_any, params: { v: :phablet }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "any", @response.body
end
def test_variant_any_any
get :variant_any_any
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "any", @response.body
get :variant_any_any, params: { v: :phone }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
get :variant_any_any, params: { v: :yolo }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "any", @response.body
end
def test_variant_inline_any
get :variant_any, params: { v: :phone }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
get :variant_inline_any, params: { v: :tablet }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "any", @response.body
get :variant_inline_any, params: { v: :phablet }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "any", @response.body
end
def test_variant_inline_any_any
get :variant_inline_any_any, params: { v: :phone }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
get :variant_inline_any_any, params: { v: :yolo }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "any", @response.body
end
def test_variant_any_implicit_render
get :variant_any_implicit_render, params: { v: :tablet }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "tablet", @response.body
get :variant_any_implicit_render, params: { v: :phablet }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phablet", @response.body
end
def test_variant_any_with_none
get :variant_any_with_none
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "none or phone", @response.body
get :variant_any_with_none, params: { v: :phone }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "none or phone", @response.body
end
def test_format_any_variant_any
get :format_any_variant_any, format: :js, params: { v: :tablet }
assert_equal "text/javascript", @response.content_type
assert_equal "text/javascript", @response.media_type
assert_equal "tablet", @response.body
end
def test_variant_negotiation_inline_syntax
get :variant_inline_syntax_without_block, params: { v: [:tablet, :phone] }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
end
def test_variant_negotiation_block_syntax
get :variant_plus_none_for_format, params: { v: [:tablet, :phone] }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
end
def test_variant_negotiation_without_block
get :variant_inline_syntax_without_block, params: { v: [:tablet, :phone] }
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
assert_equal "phone", @response.body
end
end

View File

@ -26,7 +26,7 @@ class RenderJSTest < ActionController::TestCase
def test_render_vanilla_js
get :render_vanilla_js_hello, xhr: true
assert_equal "alert('hello')", @response.body
assert_equal "text/javascript", @response.content_type
assert_equal "text/javascript", @response.media_type
end
def test_should_render_js_partial

View File

@ -80,7 +80,7 @@ class RenderJsonTest < ActionController::TestCase
def test_render_json_nil
get :render_json_nil
assert_equal "null", @response.body
assert_equal "application/json", @response.content_type
assert_equal "application/json", @response.media_type
end
def test_render_json_render_to_string
@ -91,7 +91,7 @@ class RenderJsonTest < ActionController::TestCase
def test_render_json
get :render_json_hello_world
assert_equal '{"hello":"world"}', @response.body
assert_equal "application/json", @response.content_type
assert_equal "application/json", @response.media_type
end
def test_render_json_with_status
@ -103,31 +103,31 @@ class RenderJsonTest < ActionController::TestCase
def test_render_json_with_callback
get :render_json_hello_world_with_callback, xhr: true
assert_equal '/**/alert({"hello":"world"})', @response.body
assert_equal "text/javascript", @response.content_type
assert_equal "text/javascript", @response.media_type
end
def test_render_json_with_custom_content_type
get :render_json_with_custom_content_type, xhr: true
assert_equal '{"hello":"world"}', @response.body
assert_equal "text/javascript", @response.content_type
assert_equal "text/javascript", @response.media_type
end
def test_render_symbol_json
get :render_symbol_json
assert_equal '{"hello":"world"}', @response.body
assert_equal "application/json", @response.content_type
assert_equal "application/json", @response.media_type
end
def test_render_json_with_render_to_string
get :render_json_with_render_to_string
assert_equal '{"hello":"partial html"}', @response.body
assert_equal "application/json", @response.content_type
assert_equal "application/json", @response.media_type
end
def test_render_json_forwards_extra_options
get :render_json_with_extra_options
assert_equal '{"a":"b"}', @response.body
assert_equal "application/json", @response.content_type
assert_equal "application/json", @response.media_type
end
def test_render_json_calls_to_json_from_object

View File

@ -92,11 +92,11 @@ class RenderXmlTest < ActionController::TestCase
def test_should_render_xml_but_keep_custom_content_type
get :render_xml_with_custom_content_type
assert_equal "application/atomsvc+xml", @response.content_type
assert_equal "application/atomsvc+xml", @response.media_type
end
def test_should_use_implicit_content_type
get :implicit_content_type, format: "atom"
assert_equal Mime[:atom], @response.content_type
assert_equal Mime[:atom], @response.media_type
end
end

View File

@ -73,7 +73,7 @@ class RenderersTest < ActionController::TestCase
assert_raise ActionView::MissingTemplate do
get :respond_to_mime, format: "csv"
end
assert_equal Mime[:csv], @response.content_type
assert_equal Mime[:csv], @response.media_type
assert_equal "", @response.body
end
@ -83,7 +83,7 @@ class RenderersTest < ActionController::TestCase
end
@request.accept = "text/csv"
get :respond_to_mime, format: "csv"
assert_equal Mime[:csv], @response.content_type
assert_equal Mime[:csv], @response.media_type
assert_equal "c,s,v", @response.body
ensure
ActionController::Renderers.remove :csv

View File

@ -76,7 +76,7 @@ module ShowExceptions
@app = ShowExceptionsOverriddenController.action(:boom)
get "/", headers: { "HTTP_ACCEPT" => "application/json" }
assert_response :internal_server_error
assert_equal "application/json", response.content_type.to_s
assert_equal "application/json", response.media_type
assert_equal({ status: 500, error: "Internal Server Error" }.to_json, response.body)
end
@ -84,7 +84,7 @@ module ShowExceptions
@app = ShowExceptionsOverriddenController.action(:boom)
get "/", headers: { "HTTP_ACCEPT" => "application/xml" }
assert_response :internal_server_error
assert_equal "application/xml", response.content_type.to_s
assert_equal "application/xml", response.media_type
assert_equal({ status: 500, error: "Internal Server Error" }.to_xml, response.body)
end
@ -92,7 +92,7 @@ module ShowExceptions
@app = ShowExceptionsOverriddenController.action(:boom)
get "/", headers: { "HTTP_ACCEPT" => "text/csv" }
assert_response :internal_server_error
assert_equal "text/html", response.content_type.to_s
assert_equal "text/html", response.media_type
end
end
@ -106,7 +106,7 @@ module ShowExceptions
get "/", headers: { "HTTP_ACCEPT" => "text/json" }
assert_response :internal_server_error
assert_equal "text/plain", response.content_type.to_s
assert_equal "text/plain", response.media_type
ensure
middleware.instance_variable_set(:@exceptions_app, @exceptions_app)
$stderr = STDERR

View File

@ -208,7 +208,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_response 500
assert_no_match(/<header>/, body)
assert_no_match(/<body>/, body)
assert_equal "text/plain", response.content_type
assert_equal "text/plain", response.media_type
assert_match(/RuntimeError\npuke/, body)
Rails.stub :root, Pathname.new(".") do
@ -222,31 +222,31 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
get "/not_found", headers: xhr_request_env
assert_response 404
assert_no_match(/<body>/, body)
assert_equal "text/plain", response.content_type
assert_equal "text/plain", response.media_type
assert_match(/#{AbstractController::ActionNotFound.name}/, body)
get "/method_not_allowed", headers: xhr_request_env
assert_response 405
assert_no_match(/<body>/, body)
assert_equal "text/plain", response.content_type
assert_equal "text/plain", response.media_type
assert_match(/ActionController::MethodNotAllowed/, body)
get "/unknown_http_method", headers: xhr_request_env
assert_response 405
assert_no_match(/<body>/, body)
assert_equal "text/plain", response.content_type
assert_equal "text/plain", response.media_type
assert_match(/ActionController::UnknownHttpMethod/, body)
get "/bad_request", headers: xhr_request_env
assert_response 400
assert_no_match(/<body>/, body)
assert_equal "text/plain", response.content_type
assert_equal "text/plain", response.media_type
assert_match(/ActionController::BadRequest/, body)
get "/parameter_missing", headers: xhr_request_env
assert_response 400
assert_no_match(/<body>/, body)
assert_equal "text/plain", response.content_type
assert_equal "text/plain", response.media_type
assert_match(/ActionController::ParameterMissing/, body)
end
@ -257,37 +257,37 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_response 500
assert_no_match(/<header>/, body)
assert_no_match(/<body>/, body)
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
assert_match(/RuntimeError: puke/, body)
get "/not_found", headers: { "action_dispatch.show_exceptions" => true }, as: :json
assert_response 404
assert_no_match(/<body>/, body)
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
assert_match(/#{AbstractController::ActionNotFound.name}/, body)
get "/method_not_allowed", headers: { "action_dispatch.show_exceptions" => true }, as: :json
assert_response 405
assert_no_match(/<body>/, body)
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
assert_match(/ActionController::MethodNotAllowed/, body)
get "/unknown_http_method", headers: { "action_dispatch.show_exceptions" => true }, as: :json
assert_response 405
assert_no_match(/<body>/, body)
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
assert_match(/ActionController::UnknownHttpMethod/, body)
get "/bad_request", headers: { "action_dispatch.show_exceptions" => true }, as: :json
assert_response 400
assert_no_match(/<body>/, body)
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
assert_match(/ActionController::BadRequest/, body)
get "/parameter_missing", headers: { "action_dispatch.show_exceptions" => true }, as: :json
assert_response 400
assert_no_match(/<body>/, body)
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
assert_match(/ActionController::ParameterMissing/, body)
end
@ -298,7 +298,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_response 500
assert_match(/<header>/, body)
assert_match(/<body>/, body)
assert_equal "text/html", response.content_type
assert_equal "text/html", response.media_type
assert_match(/puke/, body)
end
@ -307,7 +307,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
get "/index.xml", headers: { "action_dispatch.show_exceptions" => true }
assert_response 500
assert_equal "application/xml", response.content_type
assert_equal "application/xml", response.media_type
assert_match(/RuntimeError: puke/, body)
end
@ -321,7 +321,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
get "/index", headers: { "action_dispatch.show_exceptions" => true }, as: :wibble
assert_response 500
assert_equal "application/json", response.content_type
assert_equal "application/json", response.media_type
assert_match(/RuntimeError: puke/, body)
ensure

View File

@ -290,8 +290,8 @@ class ResponseTest < ActiveSupport::TestCase
resp.to_a
assert_equal("utf-16", resp.charset)
assert_equal(Mime[:xml], resp.content_type)
assert_equal(Mime[:xml], resp.media_type)
assert_equal("application/xml; charset=utf-16", resp.content_type)
assert_equal("application/xml; charset=utf-16", resp.headers["Content-Type"])
end
@ -503,8 +503,8 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest
assert_response :success
assert_equal("utf-16", @response.charset)
assert_equal(Mime[:xml], @response.content_type)
assert_equal(Mime[:xml], @response.media_type)
assert_equal("application/xml; charset=utf-16", @response.content_type)
assert_equal("application/xml; charset=utf-16", @response.headers["Content-Type"])
end
@ -519,8 +519,8 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest
assert_response :success
assert_equal("utf-16", @response.charset)
assert_equal(Mime[:xml], @response.content_type)
assert_equal(Mime[:xml], @response.media_type)
assert_equal("application/xml; charset=utf-16", @response.content_type)
assert_equal("application/xml; charset=utf-16", @response.headers["Content-Type"])
end
@ -553,7 +553,26 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest
assert_response :success
assert_equal("text/csv; charset=utf-16; header=present", @response.headers["Content-Type"])
assert_equal("text/csv", @response.content_type)
assert_equal("text/csv; charset=utf-16; header=present", @response.content_type)
assert_equal("text/csv", @response.media_type)
assert_equal("utf-16", @response.charset)
end
test "response Content-Type with optional parameters that set before charset" do
@app = lambda { |env|
[
200,
{ "Content-Type" => "text/csv; header=present; charset=utf-16" },
["Hello"]
]
}
get "/"
assert_response :success
assert_equal("text/csv; header=present; charset=utf-16", @response.headers["Content-Type"])
assert_equal("text/csv; header=present; charset=utf-16", @response.content_type)
assert_equal("text/csv", @response.media_type)
assert_equal("utf-16", @response.charset)
end
@ -570,7 +589,8 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest
assert_response :success
assert_equal('text/csv; header=present; charset="utf-16"', @response.headers["Content-Type"])
assert_equal("text/csv", @response.content_type)
assert_equal('text/csv; header=present; charset="utf-16"', @response.content_type)
assert_equal("text/csv", @response.media_type)
assert_equal("utf-16", @response.charset)
end
end

View File

@ -1003,14 +1003,14 @@ class RenderTest < ActionController::TestCase
def test_render_xml
get :render_xml_hello
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
assert_equal "application/xml", @response.content_type
assert_equal "application/xml", @response.media_type
end
# :ported:
def test_render_xml_as_string_template
get :render_xml_hello_as_string_template
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
assert_equal "application/xml", @response.content_type
assert_equal "application/xml", @response.media_type
end
# :ported:
@ -1039,7 +1039,7 @@ class RenderTest < ActionController::TestCase
def test_rendered_format_without_format
get :inline_rendered_format_without_format
assert_equal "test", @response.body
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_partials_list
@ -1077,7 +1077,7 @@ class RenderTest < ActionController::TestCase
def test_accessing_local_assigns_in_inline_template
get :accessing_local_assigns_in_inline_template, params: { local_name: "Local David" }
assert_equal "Goodbye, Local David", @response.body
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_should_implicitly_render_html_template_from_xhr_request
@ -1264,13 +1264,13 @@ class RenderTest < ActionController::TestCase
def test_partial_only
get :partial_only
assert_equal "only partial", @response.body
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_should_render_html_formatted_partial
get :partial
assert_equal "partial html", @response.body
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_render_html_formatted_partial_even_with_other_mime_time_in_accept
@ -1279,20 +1279,20 @@ class RenderTest < ActionController::TestCase
get :partial_html_erb
assert_equal "partial.html.erb", @response.body.strip
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_should_render_html_partial_with_formats
get :partial_formats_html
assert_equal "partial html", @response.body
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_render_to_string_partial
get :render_to_string_with_partial
assert_equal "only partial", @controller.instance_variable_get(:@partial_only)
assert_equal "Hello: david", @controller.instance_variable_get(:@partial_with_locals)
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_render_to_string_with_template_and_html_partial
@ -1300,21 +1300,21 @@ class RenderTest < ActionController::TestCase
assert_equal "**only partial**\n", @controller.instance_variable_get(:@text)
assert_equal "<strong>only partial</strong>\n", @controller.instance_variable_get(:@html)
assert_equal "<strong>only html partial</strong>\n", @response.body
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_render_to_string_and_render_with_different_formats
get :render_to_string_and_render_with_different_formats
assert_equal "<strong>only partial</strong>\n", @controller.instance_variable_get(:@html)
assert_equal "**only partial**\n", @response.body
assert_equal "text/plain", @response.content_type
assert_equal "text/plain", @response.media_type
end
def test_render_template_within_a_template_with_other_format
get :render_template_within_a_template_with_other_format
expected = "only html partial<p>This is grand!</p>"
assert_equal expected, @response.body.strip
assert_equal "text/html", @response.content_type
assert_equal "text/html", @response.media_type
end
def test_partial_with_counter

View File

@ -215,6 +215,10 @@ Please refer to the [Changelog][action-pack] for detailed changes.
### Notable changes
* Change `ActionDispatch::Response#content_type` returning Content-Type
header as it is.
([Pull Request](https://github.com/rails/rails/pull/36034))
* Raise an `ArgumentError` if a resource param contains a colon.
([Pull Request](https://github.com/rails/rails/pull/35236))

View File

@ -1144,7 +1144,7 @@ test "ajax request" do
get article_url(article), xhr: true
assert_equal 'hello world', @response.body
assert_equal "text/javascript", @response.content_type
assert_equal "text/javascript", @response.media_type
end
```

View File

@ -134,6 +134,28 @@ Action Cable JavaScript API:
+ ActionCable.logger.enabled = false
```
### `ActionDispatch::Response#content_type` now returned Content-Type header as it is.
Previously, `ActionDispatch::Response#content_type` returned value does NOT contain charset part.
This behavior changed to returned Content-Type header containing charset part as it is.
If you want just MIME type, please use `ActionDispatch::Response#media_type` instead.
Before:
```ruby
resp = ActionDispatch::Response.new(200, "Content-Type" => "text/csv; header=present; charset=utf-16")
resp.content_type #=> "text/csv; header=present"
```
After:
```ruby
resp = ActionDispatch::Response.new(200, "Content-Type" => "text/csv; header=present; charset=utf-16")
resp.content_type #=> "text/csv; header=present; charset=utf-16"
resp.media_type #=> "text/csv"
```
### Autoloading
The default configuration for Rails 6