Ruby Net::HTTP not decoding gzip?

2019-05-06 22:47发布

I have ruby-1.9.3-p327 with zlib installed. localhost:80 is the nginx simple test page.

require "net/http"
=> true
Net::HTTP::HAVE_ZLIB
=> true

res = Net::HTTP.start("localhost", "80") do |http|
  req = Net::HTTP::Get.new "/"
  req["accept-encoding"] = "gzip"
  http.request req
end
=> #<Net::HTTPOK 200 OK readbody=true>

res.get_fields "content-encoding"
=> ["gzip"]
res.body
=> "\x1F\x8B\b\x00\x00\x00\x00\x00\x00\x03\xEC\xBDi..."

The body was not decoded. Why?

标签: ruby nginx gzip
4条回答
干净又极端
2楼-- · 2019-05-06 23:10

For anyone, who get problem with code worked on ruby 1.9 and failed to work on upgrade to ruby 2.0, just include that code to your project.

module HTTPResponseDecodeContentOverride
  def initialize(h,c,m)
    super(h,c,m)
    @decode_content = true
  end
  def body
    res = super
    if self['content-length']
      self['content-length']= res.bytesize
    end
    res
  end
end
module Net
  class HTTPResponse
    prepend HTTPResponseDecodeContentOverride
  end
end
查看更多
祖国的老花朵
3楼-- · 2019-05-06 23:13

If you use http.get it should decode it automaticlly, but it looks like request might not do it for you.

There clearly is code to decompress the gzip request here, but only for the get method: https://github.com/ruby/ruby/blob/v1_9_3_327/lib/net/http.rb#L1031

查看更多
孤傲高冷的网名
4楼-- · 2019-05-06 23:21

I think it does not do it automatically.

To decode, try the following snippet (assuming the response is a StringIO):

begin
  Zlib::GzipReader.new(response).read
rescue Zlib::GzipFile::Error, Zlib::Error # Not gzipped
  response.rewind
  response.read
end
查看更多
我只想做你的唯一
5楼-- · 2019-05-06 23:24

Based on my experiments, at least one reason this happens is because of the right_http_connection gem. I tested versions 1.3.0 and 1.4.0. This gem monkey patches Net::HTTP and causes problems with decoding GZipped responses.

You can read more about this problem in this GitHub issue.

查看更多
登录 后发表回答