From 773f71c8a0d61a01b8afcc7359e0364a1f2a1bce Mon Sep 17 00:00:00 2001
From: Jon Moss <me@jonathanmoss.me>
Date: Thu, 10 Nov 2016 14:24:24 -0500
Subject: Don't error on an empty CONTENT_TYPE

This commit prevents a possible issue wherein an empty CONTENT_TYPE
header is sent in a request to a Rails application, and then `request.content_mime_type`
would return `nil`. This is because the `has_content_type?` guard method
was not properly checking the validity of a request's content type; it
was only checking to see whether or not the header existed, not whether
it had a value stored inside.

Relatedly, after an internal discussion, it was determined that the
`has_content_type?` method is not meant to be part of the public API,
and is therefore changed to a `:nodoc:` method in this commit.

The test for this behavior is a little bit ugly, for two reasons. One is
that it was difficult to determine where to place the test... I figured
the best place would be with the rest of the ParamsWrapper stuff, since
that's where the original issue was. Also, we have to do some fancy
footwork in calling `dispatch` on the test's controller manually... this
is because `ActionController::TestCase` will throw an error if you try
and pass in a nil content type, which is exactly what we are trying to
test here... Because of that, we have to manually call in to the
controller, and bypass the `post` request helper.

Fixes #26912.

This is a regression in behavior between Rails versions 4.2.x and 5.0.x,
which was introduced via [this commit](https://github.com/rails/rails/commit/a9f28600e901b11a9222e34bfae8642bfb753186).
---
 actionpack/lib/action_dispatch/http/mime_negotiation.rb |  4 ++--
 actionpack/test/controller/params_wrapper_test.rb       | 10 ++++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

(limited to 'actionpack')

diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index d0c9413efa..e5f20003a3 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -29,8 +29,8 @@ module ActionDispatch
         content_mime_type && content_mime_type.to_s
       end
 
-      def has_content_type?
-        has_header? "CONTENT_TYPE"
+      def has_content_type? # :nodoc:
+        get_header "CONTENT_TYPE"
       end
 
       # Returns the accepted MIME type for the request.
diff --git a/actionpack/test/controller/params_wrapper_test.rb b/actionpack/test/controller/params_wrapper_test.rb
index 1549405fe7..e0dffc4be4 100644
--- a/actionpack/test/controller/params_wrapper_test.rb
+++ b/actionpack/test/controller/params_wrapper_test.rb
@@ -212,6 +212,16 @@ class ParamsWrapperTest < ActionController::TestCase
       )
     end
   end
+
+  def test_handles_empty_content_type
+    with_default_wrapper_options do
+      @request.env["CONTENT_TYPE"] = ''
+      _controller_class.dispatch(:parse, @request, @response)
+
+      assert_equal 200, @response.status
+      assert_equal '', @response.body
+    end
+  end
 end
 
 class NamespacedParamsWrapperTest < ActionController::TestCase
-- 
cgit v1.2.3