Skip to content

Instantly share code, notes, and snippets.

@stephank
Created January 22, 2010 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stephank/283755 to your computer and use it in GitHub Desktop.
Save stephank/283755 to your computer and use it in GitHub Desktop.
# A monkey-patch for ActionPack, which takes into account a POST's encoding.
# Browsers may specify this using a hidden _charset_ field, or in the Content-Type.
# Briefly tested on Rails 2.3.5 and Ruby 1.9.1p376.
class ActionController::Request < Rack::Request
# This is copied from Rack::Request. Rails overrides content_type, which the original relies on,
# thus breaking it, unfortunately. Instead, this version uses @env['CONTENT_TYPE'].
def media_type_params
return {} if @env['CONTENT_TYPE'].nil?
@env['CONTENT_TYPE'].split(/\s*[;,]\s*/)[1..-1].
collect { |s| s.split('=', 2) }.
inject({}) { |hash,(k,v)| hash[k.downcase] = v ; hash }
end
# Our override for handling charset. (Indirectly affects #params)
def POST_with_url_encoded_form_charset
handle_url_encoded_form_charset(self.POST_without_url_encoded_form_charset)
end
alias_method_chain :POST, :url_encoded_form_charset
alias_method :request_parameters, :POST
private
def handle_url_encoded_form_charset(form)
# FIXME: have a default charset setting?
# FIXME: check for x-www-form-urlencoded? Only that format allows the _charset_ field
encoding = content_charset || form['_charset_']
if encoding
recursively_force_encoding(form, encoding)
else
form
end
rescue ArgumentError
# The client specified an encoding we do not understand.
form
end
# A recursive variant of String#force_encoding, which works with Hashes and Arrays too.
def recursively_force_encoding(value, encoding)
case value
when Hash
h = {}
value.each { |k, v| h[k] = recursively_force_encoding(v, encoding) }
h
when Array
value.map { |e| recursively_force_encoding(e, encoding) }
when String
value.force_encoding(encoding)
else
value
end
end
end
module ActionView::Helpers::FormTagHelper
# Our override for adding the hidden _charset_ field.
def extra_tags_for_form_with_charset(html_options)
extra_tags_for_form_without_charset(html_options) +
tag(:input, :type => 'hidden', :name => '_charset_')
end
alias_method_chain :extra_tags_for_form, :charset
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment