LoginSignup
0
0

More than 5 years have passed since last update.

escape_utilsとweb-consoleの組み合わせにて

Posted at

Rails開発を行っていますが、標記の2つを組み合わせると思わぬ挙動となってしまいました。

escape_utilsとは

RailsのようなWebアプリでは、あちこちで文字列のエスケープ処理が必要となりますが、基本的にはRuby内部で正規表現マッチにより行っています。brianmario/escape_utilsは、そのような定型的なエスケープ処理をC言語で行うことで、数十倍に高速化するためのgemです。

使い方

読み込んだだけでは適用されないので、config/initializers/以下でモンキーパッチを適用する必要があります。

config/initializers/escape_utils.rb
begin
  ######### あとで解説します
  EscapeUtils.html_secure = false
  ######### 今回の記事のポイント

  require 'escape_utils/html/rack' # to patch Rack::Utils
  require 'escape_utils/html/erb' # to patch ERB::Util
  require 'escape_utils/html/cgi' # to patch CGI
  require 'escape_utils/html/haml' # to patch Haml::Helpers

  # for patches in Rails 4.2 ActiveSupport
  if ActiveSupport.version.to_s.start_with?('4.')
    module ActiveSupport
      class SafeBuffer # :nodoc:
        private

          def html_escape_interpolated_argument(arg)
            return arg if !html_safe? || arg.html_safe?
            CGI.escapeHTML(arg.to_s)
          end
      end
    end
    class ERB
      module Util # :nodoc:
        def unwrapped_html_escape(s) # :nodoc:
          s = s.to_s
          if s.html_safe?
            s
          else
            CGI.escapeHTML(s)
          end
        end

        singleton_class.__send__(:remove_method, :unwrapped_html_escape)
        module_function :unwrapped_html_escape
      end
    end
  end
rescue LoadError
  Rails.logger.info 'Escape_utils is not in the gemfile'
end

なお、Rails 4では一部のルーチンについて自前実装しているので、別個でモンキーパッチをかける必要がありました(if文を見ての通り、Rails 5の場合には不要です)。

web-console

Rails開発者にはもはや説明不要かもしれませんが、Web上でRailsのコンソールにアクセスできるという、開発には欠かせない一品です(rails/web-console)。

2つ組み合わせてみると

開発環境でこの2つを合わせて使っていたのですが、コンソールに何を打ち込んでもuntranslated ja.errors.unacceptable_requestのようなメッセージが出るようになってしまいました。

Chromeのほうのコンソールを開いて追いかけてみると、web consoleが投げたリクエストに406を返していました。ヘッダを見てみると、Accept: application.vnd.web-console.v2と、実体参照をそのまま投げていました。

答え合わせ

実際に吐かれたJavaScript上で実体参照となってしまった箇所のソースを探してみると、/lib/web_console/templates/console.js.erbの中にありました(リンク)。そして、ふつうであればスラッシュのエスケープはされないところ、escape_utilsが気を利かせてスラッシュまでエスケープしてくれるために、ここまでエンコードされてしまった、ということでした。

これがweb-console側でIssuになるかはわからないですが(標準状態では問題にならないので)、とりあえずモンキーパッチ前にEscapeUtils.html_secure = falseとして、スラッシュのエスケープを止めることで、とりあえず動くようになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0