トップ «前日 最新 翌日» 編集
RSS feed

ただのにっき


2013-09-18(水) [長年日記]

HTTPリクエストの圧縮をサポートする

HTTPクライアントから大きなデータをPOSTするときに圧縮可能ならそうして欲しい場合があって(もちろんブラウザはそんなことしてくれないので専用クライアントを使う前提)、サーバアプリは圧縮・未圧縮の状況にかかわりなく書きたいので、その部分だけRackミドルウェアにしてみた。ちなみにリクエストではなくてレスポンスなら普通の話なので何も考えずにRack::Deflaterを使えば良い。

最初、Rackでリクエストのbodyを操作する方法がわからなくてTwitterでつぶやいたら@moroが教えてくれたので解決。いつもいつも助かります(^^;

require 'zlib'
module Rack
class UnknownCompressMethod < StandardError; end
class RequestDecompressor
def initialize(app)
@app = app
end
def call(env)
req = Rack::Request.new(env)
env['rack.input'] = decompress(req.body, env['HTTP_CONTENT_ENCODING'])
@app.call(env)
end
def decompress(body, method)
case method
when 'gzip'
Zlib::GzipReader.wrap(StringIO.new body.read)
when 'deflate'
StringIO.new(Zlib::Inflate.inflate(body.read))
when nil
body
else # unknown compressing method
raise Rack::UnknownCompressMethod.new("unknown compress method '#{method}'.")
end
end
end
end

こんな感じで使える:

require 'rack/request_decompressor'
use Rack::RequestDecompressor

クライアントはContent-Encodingヘッダを追加してPOSTすればよろしい。

Tags: rack http
本日のツッコミ(全3件) [ツッコミを入れる]
hsbt (2013-09-19(木) 02:28)

これは便利そう

ただただし (2013-09-19(木) 06:56)

「大きなデータ」と言いつつ全部オンメモリで処理してるあたりがまだアレだけど。

ただただし (2013-09-19(木) 21:18)

gem化した: https://github.com/tdtds/rack-request_decompressor


トップ «前日 最新 翌日» 編集
RSS feed