Rack限定ならむかし rack-spyup というものを書いた。自分で使ってみたけどJSON APIのデバッグとかだと革命的に便利だと思う。
ただ、Rackに到達する前にリクエストがお亡くなりになったりとか、そもそもサーバルビーじゃないしとかあると思うので、もっと汎用的な感じでダンプする手順をメモしてみる。
リクエストが来たら内容を全部ダンプするHTTPサーバを作る
Rubyに標準添付されている、WEBrickの基本的な機能で割と簡単に作れる。
# -*- coding: utf-8 -*-
require 'optparse'
require 'webrick'
require 'json'
options = ARGV.getopts("p:", "port:")
# The :monkey: raises
# cf. http://d.hatena.ne.jp/vividcode/20110505/1304618393
class WEBrick::HTTPServlet::ProcHandler
alias do_PUT do_POST
alias do_DELETE do_POST
end
HORIZON = "\e[31m" + ("#" * 72) + "\e[0m"
def dump_http_request(req)
puts HORIZON
puts req.request_line
puts req.raw_header
puts
if body = req.body
puts body.lines.map{|line| line.gsub /[[:cntrl:]]/, '' }
else
puts "\e[35m*** Empty request body (maybe it is GET) ***\e[0m"
end
puts HORIZON
puts
end
srv = WEBrick::HTTPServer.new(
:BindAddress => "0.0.0.0",
:Port => (options["p"] || options["port"] || raise("Need option -p=PORT")).to_i,
)
srv.mount_proc "/" do |req, res|
dump_http_request(req)
res.content_type = "application/json"
res.body = {return: "OK"}.to_json
end
Signal.trap('INT') { srv.shutdown }
srv.start
dump_http_request
が冗長だが(しょうがない)、WEBrick自体は簡単に扱えることが分かると思う。
これをターミナル(1)で起動しとく:
$ ruby http-dumper.rb -p 3002
リクエストをクローンして二つのサーバに送りつけるひとを作る
かっこ良くGoの gor を使おうとしたが、Macだとちゃんと動かない感じがする。
今回は手軽さ重視で kage を使い、gor
コマンドと同じようなことをさせてみる。 gem install kage
した後:
require 'optparse'
require 'kage'
options = ARGV.getopts("p:", "port:", "backend-port:", "dumper-port:")
Kage::ProxyServer.start do |server|
server.port = (options["p"] || options["port"] || raise("Need option -p=PORT")).to_i
server.host = '0.0.0.0'
server.debug = false
server.add_master_backend(:dev, 'localhost', options["backend-port"])
server.add_backend(:dump, 'localhost', options["dumper-port"])
server.on_select_backends do |request, headers|
# アセットまでdump serverに送るのはうざったいので適当に振り分ける
is_asset = request[:path] =~ /\.(ico|js|css|gif|png|jpe?g)$/
is_asset ? [:dev] : [:dev, :dump]
end
puts "Server is listening 0.0.0.0:#{server.port}"
end
これもターミナル(2)で立ち上げ。
$ ruby kage-front.rb -p 3000 --backend-port=3001 --dumper-port=3002
あとは分かるな
検査したいアプリを 3001
番ポートでターミナル(3)に立ち上げること。Railsなら rails s -p 3001
アクセスする
http://localhost:3000
にいつも通りアクセスする。そうすると、いつも通りのウェブサービスが見える...
一方で、ターミナル(1)ではリクエストの内容がダンプされているのであった!
Usage
普通HTTPリクエストがそもそも壊れてるって少ないと思うけど、今回はジャバを触っていたらどうも壊れてしまっていたのでこういう感じでチェックしていた。参考にしてください。
ブラウザならデベロッパツールでいいけど、HTTPってやっぱいろんなクライアントから叩くと思うんで...。
FAQ
ngrep
でいいじゃん
そうですね。tcpflowも便利でいいですね。
ただまあ、一応、そもそも「HTTPリクエストをクローンする」というのが便利かなと思ったのでメモがてら書いてみた感じでござる。あと、APIならともかくWebサービスだとアセットへのアクセスも全部出てしまってノイズっぽいし、このやりかただと正規表現などで適当に絞れると思う。
追記
gemの形でインストールできるようにした ので、bundlerなど使って入れてみて利用できるようになりました(rubygems.org には置かない予定です)。