Rails ArgumentError: invalid %-encoding Rails ArgumentError: invalid %-encoding ruby-on-rails ruby-on-rails

Rails ArgumentError: invalid %-encoding


if you don't mind against monkeypatching Rack then create in config/initializers file (for example rack.rb) with this content:

module Rack  module Utils    if defined?(::Encoding)      def unescape(s, encoding = Encoding::UTF_8)        begin          URI.decode_www_form_component(s, encoding)        rescue ArgumentError          URI.decode_www_form_component(URI.encode(s), encoding)        end      end    else      def unescape(s, encoding = nil)        begin          URI.decode_www_form_component(s, encoding)        rescue ArgumentError          URI.decode_www_form_component(URI.encode(s), encoding)        end      end    end    module_function :unescape  endend

p.s. it works with passenger, but with Webrick and Thin it doesn't. It looks like both webrick and thin parse a request too, so the failure happens before initializer is loaded. For example with Thin error happens in thin-1.6.2/lib/thin/request.rb:84.


You could inject a middleware designed to detect these and fail gracefully. The basic idea is to just try to parse the query string, and if it fails, bail out with a HTTP 400. Otherwise, just allow the request through.

class RefuseInvalidRequest  def initialize(app)    @app = app  end  def call(env)    query = Rack::Utils.parse_nested_query(env['QUERY_STRING'].to_s) rescue :bad_query    if query == :bad_query      [400, {'Content-Type' => 'text/plain'}, "Bad Request"]    else      @app.call(env)    end  endend

I haven't tested this, but the concept should work.