miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

Webrick でサブドメインを吸収してみる

現在 WordPress MU の案件をお手伝いしている(短期のお手伝いなので細かいことは把握してない)のですが、これは複数のブログを持てるシステムで、それぞれのブログを

のようにサブドメインに割り当てる機能も持っています。管理画面からこの辺りの編集が行え、DNS サーバにもうまいこと情報を反映してくれる機能もあるようなのですが、開発環境では機能していないようで。

そのため、それぞれのサブドメインをにブラウザからアクセスしたい場合、hosts ファイルで

192.0.2.1 wpmu.example.com user1.wpmu.example.com user2.wpmu.example.com

のようにサブドメイン名をすべて追加してやる必要があります。(hosts ファイルではワイルドカード等は使えないようです。)

初めはこの運用で我慢していたんですが、途中で耐えられなくなりまして。うまいこと解決する方法を模索して・・・結局 WEBrick でやることにしました。

最終的なスクリプト

#!/usr/bin/env ruby
$KCODE = 'UTF-8'

require 'webrick'
require 'webrick/httpproxy'

class MyProxyServer < WEBrick::HTTPProxyServer
  # HTTP の場合はここで書き換え
  def proxy_service(req, res)
    # ホスト名の先頭部分を除去
    print "proxy_service: #{req.host} -> "
    req.host.sub!(/^[-0-9A-Za-z]+\.(?=wpmu\.example\.com)/, '')
    puts req.host
    
    # プロキシのメイン処理
    super
  end
  
  # HTTPS の場合はここで書き換え
  def proxy_connect(req, res)
    # ホスト名の先頭部分を除去
    print "proxy_connect: #{req.unparsed_uri} -> "
    req.unparsed_uri.sub!(/^[-0-9A-Za-z]+\.(?=wpmu\.example\.com)/, '')
    puts req.unparsed_uri
    
    # プロキシのメイン処理
    super
  end
end

config = {
  :BindAddress => '127.0.0.1',
  :Port => 8080,
  :Logger => WEBrick::Log.new($stderr),
  :ProxyContentHandler => nil,
  :ProxyVia => false,
}

s = MyProxyServer.new(config)

trap('INT') { s.shutdown }

s.start

*.wpmu.example.com へのアクセスについて、ヘッダ等の情報はそのままで実際の接続は wpmu.example.com に対して行う proxy です。wpmu.example.com の名前解決は自力でできる必要がありますが、それ以外のサブドメインは名前解決する必要がないということです。8080/tcp で起動するようになっているので、ブラウザで localhost:8080 を proxy として使うよう設定してやれば OK と。

元ネタ&ハマった点

ここで作ったやつをちょこっといじっただけです。

当初 HTTPS の画面でエラーになっていたので、webrick/https を使ったりしないとダメなのかな?といろいろ試したりもしたんですけど、webrick/httpsHTTPS サーバとして振舞う場合に必要なようで。

にあるように、HTTPS proxy として振舞いたい場合は普通の HTTP proxy でいい(CONNECT メソッドさえうまくハンドリングしてやればいい)みたいです。

その他遠回りっぷり

結局 HTTP っぽい proxy 十分対応できたんですが、HTTPS 対応 proxy という形で探すといくつか見つかりました。結局使っていないのですが、せっかく調べたのでメモ。