Created
April 21, 2015 20:27
-
-
Save vovimayhem/f7bc4b8f06fefa798374 to your computer and use it in GitHub Desktop.
TidyBytesInRequest Rack Middleware
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
require "active_support/core_ext/string/multibyte" | |
class TidyBytesInRequest | |
TIDY_BYTES_ENV_KEYS = %w( | |
HTTP_USER_AGENT | |
HTTP_REFERER | |
PATH_INFO | |
QUERY_STRING | |
REQUEST_PATH | |
REQUEST_URI | |
HTTP_COOKIE | |
).freeze | |
URI_ENCODABLE_ENV_KEYS = %w( | |
HTTP_REFERER | |
PATH_INFO | |
QUERY_STRING | |
REQUEST_PATH | |
REQUEST_URI | |
HTTP_COOKIE | |
).freeze | |
def initialize(app) | |
@app = app | |
end | |
def call(given_env) | |
@app.call(tidy_bytes_in_env given_env) | |
end | |
private | |
def tidy_bytes_in_env(given_env) | |
tidy_bytes_in_env_keys given_env | |
tidy_bytes_in_rack_input given_env | |
given_env | |
end | |
def tidy_bytes_in_env_keys(given_env) | |
TIDY_BYTES_ENV_KEYS.each do |key| | |
next unless value = given_env[key] | |
# Tidy Bytes unless value contains ascii caracters only: | |
given_env[key] = unless value.ascii_only? | |
tidied_value = value.mb_chars.tidy_bytes.to_s | |
# URI encode the tidied_value, to avoid Rack::Utils complaining about | |
# a regexp match against a UTF-8 string: | |
if URI_ENCODABLE_ENV_KEYS.include?(key) | |
URI.encode tidied_value | |
else | |
tidied_value | |
end | |
else | |
value | |
end | |
end | |
end | |
def tidy_bytes_in_rack_input(given_env) | |
case given_env['CONTENT_TYPE'] | |
when 'application/x-www-form-urlencoded' | |
value = given_env['rack.input'].read | |
# Tidy Bytes unless the rack input contains ascii caracters only: | |
unless value.ascii_only? | |
tidied_value = value.mb_chars.tidy_bytes.to_s | |
# URI encode the tidied_value, to avoid Rack::Utils complaining about | |
# a regexp match against a UTF-8 string: | |
given_env['rack.input'] = StringIO.new(URI.encode tidied_value) | |
end | |
# Rewind the string IO: | |
given_env['rack.input'].rewind | |
when 'multipart/form-data' | |
# Don't process the data since it may contain binary content | |
else | |
# Unknown content type. Leave it alone | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment