2013年3月12日火曜日

【Ruby】WebrickのProxyContentHandlerとProcクラス



前々回の記事webrickでプロキシサーバをつくろうとしてデータを書き換えたりするために使っていた際、ハンドラのProxyContentHandlerにProcクラスを使っていたけれど これをどうにかして、別のクラスにして置き換えたいと思った。
  handler = Proc.new(){|req,res|

    if "#{req.host}#{req.path}" == REPALCE_TARGET
      res.body = REPLACE_CONTENT
    end
  }
Procについて調べてみて出てきた説明がこちら
ブロックをコンテキスト(ローカル変数のスコープやスタックフ レーム)とともにオブジェクト化した手続きオブジェクトです。
うむ、いまいちどうしたらいいのかわからなかったのでいろいろと試行錯誤しようとしたけれど、なかなかうまくいかなかった。そこで、とりあえず適当にクラスをつくって突っ込んでみる事にした。
class Handler  
  def initialize()
  end
end
これを
handler= Handler.new
として、プロキシを設定し、適当なページにアクセスすると以下の表示が帰ってきた。
Internal Server Error

undefined method `call' for #
WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20) at doc.ruby-lang.org:80
methodのcallが無いという事なので、Procの時に実装していた引数をもたせたcallというメソッドを実装
class Handler
  
  def initialize()
  end
  
  def call(req,res)
  end
  
end
すると、ページがきちんと表示された。よし、これにて一件落着。 といいたい所だけれども、とりあえずwebrickのhttpproxy.rbとproc.cを見てみた所、何となく、これでも問題なさそうだ。

https://github.com/ruby/ruby/blob/trunk/proc.c https://github.com/ruby/ruby/blob/trunk/lib/webrick/httpproxy.rb

 動くっちゃ動くけど、この実装はruby的にいいのかどうか。