Created
January 22, 2010 13:16
-
-
Save stephank/283755 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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