性懲りもなく、手を広げているTakuyaです。こんばんは。
WEBRickに手を出してしまいました。
るびまの記事に従いproxyサーバーを作ってみました。そして次に、プロキシにBASIC認証を書けてみました。
WEBRickサーバーは予想に反し、動作早いんだもの。いろんなことに使ってみたくなった。
BASIC認証付のWEBRick Proxyサーバー
認証パスは akiko/wada になる。
proxy-auth.rb
#!/usr/bin/env ruby KCODE='u' require 'webrick' require 'webrick/httpproxy' require 'stringio' require 'zlib' auth_proc = Proc.new(){|req,res| WEBrick::HTTPAuth.proxy_basic_auth(req,res,'proxy') do |user,pass| user == 'akiko' and pass == 'wada' #この部分で認証。 end } s = WEBrick::HTTPProxyServer.new({ :Port => 8080, :ProxyContentHandler => handler, :ProxyAuthProc => auth_proc, }) #SIGINIを補足する Signal.trap('INT') do #補足したらシャットダウン s.shutdown end #サーバー起動 s.start
あとは、このプロキシをとおしてWEBを閲覧すればいい。
さて、とても楽ちんなのですが。動作原理がイマイチ分からない。
結論から言えば、認証失敗したら例外を投げる。
- :ProxyAuthProcに登録された関数(Proc)はリクエスト処理前に実行される。
- WEBrick::HTTPAuth.proxy_basic_authは例外を投げる。
- 例外はWEBrick::HTTPStatus::ProxyAuthenticationRequiredである。
- Basic認証をブラウザに要求する。
この流れである。
特に例外を使ってレスポンスを書き換えるのが鮮やかな処理でWEBRickの設計に惚れた。が、同時にドキュメントがなく不親切、わかりにくいなと思った。
呼び出しの流れをFollowしてみよう。
- s.startでサーバーが起動する。
- WEBrick::HTTPProxyServerは親クラスのStartを継承している。
- HTTPProxyServerのstartが実行される。
- スレッド処理を行なう準備をする。
- 各スレッドがrunを実行する。HTTPProxyServer.serviceはrun内部で処理される。
- リクエストがやってくる。
- serviceに処理が渡る
- proxy_serviceに処理が渡る
- proxy_authが呼び出される
- 最初の呼び出しだと、認証に失敗するので例外をRaiseする。
- HTTPServer.run 68行目 "rescue HTTPStatus::Error => ex"でレスポンスをエラー内容に書き直す
- ブラウザにレスポンスを返す。