読者です 読者をやめる 読者になる 読者になる

RubyでHTTPクライアント→HTTPプロキシ→サーバの流れを実装してみる

Ruby

● HTTPクライアント (httpclient)
● HTTPプロキシ (webrick
● サーバ (CGI

を書いて、HTTP クライアントからプロキシ経由でリクエストを投げてサーバで受け取る、という一連の流れを実装してみようと思った時のメモ。
受け取り側のサーバだけ CGI を使っていて、 HTTP クライアントから POST で CGI サーバにファイルを飛ばしてみます。

HTTP クライアント

require 'httpclient'

proxy = 'http://127.0.0.1:8080'
client = HTTPClient.new(proxy)
boundary = 'boundary'
open('postfile.txt') do |file|
    postdata = {'file' => file}
    client.post_content(
        'http://192.168.99.99/cgi-bin/file.cgi', #ここに受け取り側サーバを指定
        postdata,
        'content-type' => 'multipart/form-data, boundary=#{boundary}'
    )
end

HTTP クライアントには、httpclient を使います。
このあたりの記事に Ruby の HTTP クライアントの比較について書かれています。

Ruby HTTPクライアントの比較表 - Qiita
Ruby の HTTP リクエストを送る方法の性能比較 - Qiita


HTTP プロキシ

require 'webrick'
require 'webrick/httpproxy'

class TestProxyServer < WEBrick::HTTPProxyServer
    def proxy_service(req, res)
        req.body =~ %r{filename=\"(.+?)\"} #受け取ったファイル名抽出
        puts $~[1]
        super #プロキシのメイン処理
    end
end

server = TestProxyServer.new(
    :BindAddress => '127.0.0.1',
    :Port => 8080,
    :Logger => nil,
)
Signal.trap('INT') do
    server.shutdown
end
server.start

プロキシには、webrick を使います。
今回はプロキシで処理したいことが特に思い浮かばなかったので、受け取ったファイル名を正規表現で抽出して出力しています。
ここには様々な処理を書くことが可能で、バナー広告等を除去するコンテンツフィルタを作ったり、開発用に特定の通信の接続先を書き換えたりする例を見つけたので載せておきます。

Rubyist Magazine - WEBrickでプロキシサーバを作って遊ぶ
開発用HTTPプロキシを簡単に立てる裏技 - Qiita


受け取り側サーバ

#! /usr/local/bin/ruby ここに ruby へのパス
require 'cgi'
cgi = CGI.new
cgi.out("type"=>"text/plain") {
  cgi["file"].read
}

こいつだけ CGI で書いています。 今回は Apache で動かしました。
ApacheCGI の連携は下の記事に簡潔に書いてあります。

Apache:CGIの利用設定をする - Qiita


おわり

あとは、HTTP プロキシと受け取り側サーバを起動して、HTTP クライアントを実行すれば、受け取り側サーバが送信ファイルの内容を出力するはずです。