表示しているコンテンツを書き換えてみよう

表示しているコンテンツを書き換えてみよう

 HTTPProxyServerには、取得したコンテンツを書き換える機能が標準搭載されています。HTTPProxyServerの起動オプションであるProxyContentHandlerでHandlerを指定することで、そのHandler内で自由にコンテンツを書き換えることができます。

 サンプルとしては地味ですが「Think IT」を「THINK IT」に書き換えるプロキシを作ってみます。サンプルファイルのproxy2.rbのようになります。

 Handlerでは2つの引数を受け取ります。1つ目がリクエスト(WEBrick::HTTRequest)、2つ目がレスポンス(WEBrick::HTTPResponse)です。これは「第2回:基本機能の実装にチャレンジ!(http://www.thinkit.co.jp/article/117/2/)」のWEBrickを使ったHTTPサーバーと同じです。このHandlerが呼ばれた時には既にプロキシで取得したコンテンツがレスポンスに設定されています。

 本文の文字列を書き換えたい場合は、レスポンスのbodyを書き換えることで実現できます。また今回、書き換えたいのはHTMLファイルだけなので、Content-Typeがtext/htmlで始まるものだけ書き換えるようにします。

 以下を実行してみると、タイトルバーやコンテンツ上部の「Think IT」が「THINK IT」に書き換わっているのが分かると思います(図2の右)。

$ ruby proxy2.rb

 このまま、Googleで「think it」を検索してみましょう(図2の左)。検索結果のタイトルも「Think IT」が「THINK IT」に置換されています。

 同じようにYahoo! Japanでも「think it」も検索してみましょう(図2の中央)。今度は検索結果の「Think IT」がそのまま出ています。なぜか置換が行われていません。

 これは、Yahoo! Japanのページではコンテンツが圧縮して送出されているためです。通常Webブラウザではそれを自動で解凍して表示しているのですが、プロキシの時点では圧縮された形式のままです。よって「Think IT」も圧縮されているため、そのままではプロキシで置換することができません。この対策には複数の手段がありますが、今回は扱いません。興味のある方は、ブログ「WEBrickで自作プロキシ」(http://rucila.s43.xrea.com/memo/?date=20041020#p02)「WEBRickプロキシでgzipに対応するCommentsAdd Star」(http://d.hatena.ne.jp/hayori/20080205/1202189655)などを参考にしてみてください。

別の書き方

 ProxyContentHandlerを使うことで、コンテンツフィルターを容易に書くことができますが、プロキシでコンテンツを取得する前に処理を行いたいなどの、細かい設定は行うことができません。このようにもっと細かい処理を書くには、HTTPProxyServerを継承して新しいクラスを作り、メソッドを上書きしてカスタマイズします。

 この方法でproxy2.rbと同じ処理をする場合は、サンプルファイルのproxy3.rbのように書きます。

 OriginalHTTPProxyServerでは、HTTPProxyServerを継承して、proxy_serviceメソッドを上書きしています。proxy_serviceメソッドでは、その名の通りプロキシ先のコンテンツを取得する処理を行っています。ここを上書きし、まずsuperで元のproxy_serviceメソッドの処理を実行します。これで、目的のコンテンツがresに設定されます。

 この後は、先のHandlerの時と同じコードを書くことで、取得したコンテンツの書き換えが行えます。

 これを利用し、特定のWebサイトだけプロキシ経由でアクセスさせないようにすることができます。

 例えば、2ちゃんねる(http://www.2ch.net/)をブロックするには、リクエストのホストが.2ch.netである場合にプロキシ処理を行わないようにします。その代わりに、レスポンスボディーに「blocked」と表示させるようにしましょう。サンプルファイルproxy4.rbのようになります。

 proxy3.rbとは違い、superより前にリクエストのホスト(req.host)を見て、.2ch.netだった場合にはsuperを呼び出さずに、このメソッドでレスポンスボディー(res.body)にblockedを設定しています。ホストがそれ以外の場合には、superを呼び出すことでプロキシ処理を行うようにします。

 今回はホスト名だけを見ていますが、パス(req.path)も見ることで、特定のディレクトリ以下のコンテンツのみをブロックすることなども容易に実装できます。ぜひ自分でいろいろ試してみてください。

 次は仕事で使えるプロキシを作ってみましょう。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30