jugyo.wordpress.com

Yet another jugyo's blog

プロキシサーバーによるファイルの"すり替え" by Webrick

leave a comment »

ファイルの”すり替え”を行う為のプロキシサーバーを Webrick で作ってみました。
というか、以下のページからアイデアをパクって自分なりに実装してみました。

最速インターフェース研究会 :: 萌ディタとSleipnirとWEBrickを使って人のサイトのCSSをリアルタイム編集するデモ

ソースは以下になります。

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'

def start_proxy(&handler)
  s = WEBrick::HTTPProxyServer.new(
    :BindAddress => '127.0.0.1',
    :Port => 8080,
    :ProxyContentHandler => handler
  )
  Signal.trap('INT') do
    s.shutdown
  end
  s.start
end

CONF = "conf.rb"
$rules = nil
$last_mtime = nil

start_proxy {|req, res|
  # 設定ファイル読み込み
  conf_mtime = File.mtime(CONF)
  unless $last_mtime == conf_mtime
    eval "$rules = #{File.read(CONF)}"
    $last_mtime = conf_mtime
    puts "load #{CONF}"
  end
  if site_rules = $rules[req.host]
    if replace_file_path = site_rules[req.path]
      if File.exist?(replace_file_path)
        # ファイルのすり替え
        mime_type = WEBrick::HTTPUtils::mime_type(
          replace_file_path,
          WEBrick::HTTPUtils::DefaultMimeTypes)
        res.header['content-type'] = mime_type
        res.body = File.read(replace_file_path)
        puts "before => #{req.host + req.path}, after => #{replace_file_path}, mime_type => #{mime_type}"
      end
    end
  end
}

動作させるには conf.rb という設定ファイルを用意する必要があります。
このファイルに”すり替え”のための設定を ruby のハッシュテーブルの形式で記述します。

例えば以下のように設定を記述すると、ホスト「jugyo.org」の「/images/jugyo.png」というファイルをローカルマシンの「/home/jugyo/test.png」というファイルにすり替えます。

{
  "jugyo.org" => {
    "/images/jugyo.png" => "/home/jugyo/test.png"
  }
}

設定ファイルが更新されると再読み込みします。

Firefox のアドオンでこういう機能を実現できるものって無いのかなぁ。

追記:
Windows 環境にて、ローカルのファイルを読み込むときに「バイナリモード」で読み込まないとうまくいかないケースがあったのでソースの該当部分を修正しました。
File オブジェクトの binmode メソッドを呼び出すことで、ファイルをバイナリモードで扱うことができるようになるようです。
追記: ていうか “rb” オプションつければいいだけですよね。当時の僕は何もわかってない。
あと、「mime type」をセットする処理を削除しました。
「mime type」が変わるようなケースってそうないかなぁ、と思ったので。
というか WEBrick::HTTPUtils::DefaultMimeTypes に定義されてない mime type について考えるのが面倒くさかったので。:-)

修正後のソースは以下になります。

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'

def start_proxy(&handler)
  s = WEBrick::HTTPProxyServer.new(
    :BindAddress => '127.0.0.1',
    :Port => 8080,
    :ProxyContentHandler => handler
  )
  Signal.trap('INT') do
    s.shutdown
  end
  s.start
end

CONF = "conf.rb"
$rules = nil
$last_mtime = nil

start_proxy {|req, res|
  # 設定ファイル読み込み
  conf_mtime = File.mtime(CONF)
  unless $last_mtime == conf_mtime
    eval "$rules = #{File.read(CONF)}"
    $last_mtime = conf_mtime
    puts "load #{CONF}"
  end
  if site_rules = $rules[req.host]
    if replace_file_path = site_rules[req.path]
      if File.exist?(replace_file_path)
        # ファイルのすり替え
        File.open(replace_file_path, "rb"){|f|
          res.body = f.read
        }
        puts "replace: before => #{req.host + req.path}, after => #{replace_file_path}"
      end
    end
  end
}

追記:
導入しやすいように ZIP で固めたものを置いておきます。

proxy.zip

どうぞご自由にお使いください。
用途に応じていろいろ改造するといいと思います。

以下のようにして実行します。

$ ruby proxy.rb

ブラウザでプロキシサーバーの設定を変更してください。

例:

こんな便利な Firefox アドオンもあります。

FoxyProxy :: Firefox Add-ons

FoxyProxy is an advanced proxy management tool that completely replaces Firefox’s proxy configuration.

サイトごとに個別にプロキシサーバーの設定を適用したりできます。

Advertisements

Written by jugyo

September 16, 2007 at 16:33

Posted in Uncategorized

Tagged with ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: