Net::HTTPには空気を読んで自動的にHTTP compressionを有効にして通信する機能がある。
リクエストのヘッダーにaccept-encoding
やrange
を設定しなければ、自動的にaccept-encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
がセットされ、圧縮されたレスポンスは自動的に展開される。Net::HTTPを内部で使っているライブラリ(open-uriや、faradayのNet::HTTPのアダプターなど)もaccept-encoding
やrange
をセットしていなければHTTP Compressionに対応している。
ただし、1.9.3でこの機能が有効になるのはNet::HTTP#getを使用するときだけ。Net::HTTP.getやNet::HTTP::Get(open-uriはこれを使っている)などを使う場合は有効にならない。faradayのNet::HTTPアダプターは可能ならNet::HTTP#getを使うようになっている。2.0以降はすべての場合でHTTP Compressionが有効となる。
関連するコミットログとissue
- Automatically inflate gzip and deflate-encoded response bodies.
- Do not handle Content-Encoding when the user sets
- Feature #6494: Send Accept-Encoding for all HTTP requests - ruby-trunk - Ruby Issue Tracking System
- Feature #6492: Inflate all HTTP Content-Encoding: deflate, gzip, x-gzip responses by default - ruby-trunk - Ruby Issue Tracking System
ドキュメント
検証に使ったコード
require 'webrick'
require 'open-uri'
require 'thread'
require 'pp'
uri = URI("http://127.0.0.1:9292/")
Thread.new do
server = WEBrick::HTTPServer.new(BindAddress: uri.host, Port: uri.port)
server.mount_proc(uri.path) do |req, res|
pp req.raw_header
res.body = "foo"
end
server.start
end
sleep 1
header = {}
open(uri.to_s, header.merge("User-Agent" => "open-uri"))
Net::HTTP.start(uri.host, uri.port){|h|
h.get(uri.path, header.merge("User-Agent" => "Net::HTTP#get"))
}
This document is licensed under CC0.