簡単なProxyを作ってみた

参考資料


参考資料ではSimpleHTTPServer.SimpleHTTPRequestHandlerのdo_GETをオーバーライドしていますが、必要なものはdo_GETとcopyfileだけなのでBaseHTTPServer.BaseHTTPRequestHandlerでいいや、と思ったのでした。

# -*- coding: euc-jp -*-
import BaseHTTPServer
import os
import shutil
import StringIO
import urllib

class ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  def encode(self, s, c):
    for i in ('euc-jp', 'sjis', 'utf-8'):
      try:
        return unicode(s, i).encode(c), i
      except:
        pass
    return s, None

  def do_GET(self):
    print 'get...', self.path
    f = urllib.urlopen(self.path)
    if 'text' in f.info().gettype() and os.path.splitext(self.path)[1] in ('', '.htm', '.html', '.cgi', '.php'):
      s, e = self.encode(f.read(), 'euc-jp')
      if e:
        s = s.replace('。', '(笑')
        f = StringIO.StringIO(self.encode(s, e)[0])
    shutil.copyfileobj(f, self.wfile)

port = 3128
print 'proxy at', port
BaseHTTPServer.HTTPServer(('', port), ProxyHandler).serve_forever()

使い方

  • python proxy.py で起動
  • ブラウザの設定をいじって起動したproxyに繋ぐ
    • こんな感じ 
  • 日本語のページを見たときに '。' が '(笑' に書き換わってイラッとする


ときどき書き換わらなかったりするのは仕様です。嘘です。よくわかりません。


処理の流れ

  • ブラウザが何かをGETしようとするとdo_GETが呼ばれて、self.pathにブラウザがGETしようとしているURLが入る
  • urllib.urlopenでself.pathをGET
  • GETした結果得られるものはファイルオブジェクトっぽいものなのでreadで文字列だけを取り出して書き換える
  • StringIOで文字列からファイルオブジェクトっぽいものに変換
  • 変換したファイルオブジェクトっぽいものをshutil.copyfileobjでself.wfileにコピー
  • 最終的にブラウザに表示されるものはself.wfileの中身