Skip to content

Instantly share code, notes, and snippets.

@vovimayhem
Created April 21, 2015 20:27
Show Gist options
  • Save vovimayhem/f7bc4b8f06fefa798374 to your computer and use it in GitHub Desktop.
Save vovimayhem/f7bc4b8f06fefa798374 to your computer and use it in GitHub Desktop.
TidyBytesInRequest Rack Middleware
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