Skip to content

Instantly share code, notes, and snippets.

@pithyless
Created September 5, 2012 16:00
Show Gist options
  • Save pithyless/3639014 to your computer and use it in GitHub Desktop.
Save pithyless/3639014 to your computer and use it in GitHub Desktop.
Rails middleware to encode characters and avoid exploding controllers
# config/initializers/char_converter.rb
require 'uri'
module Support
class CharConverter
SANITIZE_ENV_KEYS = [
"HTTP_COOKIE", # bad cookie encodings kill rack: https://github.com/rack/rack/issues/225
"HTTP_REFERER",
"PATH_INFO",
"QUERY_STRING",
"REQUEST_PATH",
"REQUEST_URI",
]
def initialize(app)
@app = app
end
def call(env)
@app.call(sanitize_env(env))
end
def sanitize_env(env)
SANITIZE_ENV_KEYS.each do |key|
next unless value = env[key]
value = sanitize_string(URI.decode(value))
env[key] = URI.encode(value)
end
env
end
def sanitize_string(string)
return string unless string.is_a? String
# Try it as UTF-8 directly
cleaned = string.dup.force_encoding('UTF-8')
if cleaned.valid_encoding?
cleaned
else
# Some of it might be old Windows code page
string.encode(Encoding::UTF_8, Encoding::Windows_1250)
end
rescue EncodingError
# Force it to UTF-8, throwing out invalid bits
string.encode!('UTF-8', invalid: :replace, undef: :replace)
end
end
end
Rails.application.config.middleware.insert_before(0, Support::CharConverter)
@jlfenaux
Copy link

Great solution. Thanks

@phoet
Copy link

phoet commented Feb 1, 2013

just for cross reference, because you did not fork the gist: https://gist.github.com/1336754

@phoet
Copy link

phoet commented Mar 14, 2013

there is a mayor flaw in this implementation, as values from HTTP_COOKIE should not be url-encoded. i updated my version recently.

btw it's possible to fork gists instead to copy it.

@grosser
Copy link

grosser commented Sep 20, 2013

@entity1991
Copy link

There is one problem I have, when I used this module. My session data is reseting!

@yujingz
Copy link

yujingz commented Dec 17, 2013

@entity1991 you could skip session data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment