Rails 2's CookieStore produces invalid cookie data, causing tests to break

Posted . Visible to the public.

Note that this seems to affect only recent Rails 2 versions.

You will not encounter this until you are writing to the cookie more than once, but when doing so, integration tests (Cucumber) may break for you with this error:

You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[] (NoMethodError)

Background

The regular/short cucumber backtrace is not of any help but looking at the full trace reveals that ActionPack's action_controller/integration.rb is breaking while doing this:

cookies = @headers['Set-Cookie']
cookies = cookies.to_s.split("\n") unless cookies.is_a?(Array)
cookies.each do |cookie|
  name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
  @cookies[name] = value
end

This won't work when you there are empty lines in a cookie -- which is exactly what happened for me. That is how my cookie looked when debugging:

(rdb:1) puts headers['Set-Cookie']
remember_token=abcdef123456; path=/; expires=Mon, 31-Dec-2029 23:03:29 GMT

foo=23; path=/; expires=Thu, 30-Jan-2020 23:03:29 GMT

bar=42; path=/; expires=Thu, 30-Jan-2020 23:03:30 GMT
_some_session=foobarbaz; path=/; expires=Thu, 31-Dec-2020 23:03:30 GMT; HttpOnly

Solution

This seems to be a bug in Rails, the CookieStore (for sessions) or Rack::Utils.set_cookie_header -- I did not bother looking closer.

My problems went away when introducing an initializer that cleans up line breaks:

module ActionController
  module Session
    CookieStore.class_eval do

      def call_with_line_break_fix(*args)
        status, headers, body = call_without_line_break_fix(*args)
        headers['Set-Cookie'].gsub! "\n\n", "\n" if headers['Set-Cookie'].present?
        [ status, headers, body ]
      end

      alias_method_chain :call, :line_break_fix

    end
  end
end

Put that into a file like config/intializers/cookie_store_with_line_break_fix.rb and you are good to go.

If you don't feel like monkey-patching, you could also write a Rack middleware Show archive.org snapshot that tidys up your cookie data. I prefer doing API-stable patches, if possible.

Profile picture of Arne Hartherz
Arne Hartherz
Last edit
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2012-06-26 10:21)