Ruby Net::HTTP无法解码gzip压缩格式?

5

我安装了带有zlib的ruby-1.9.3-p327版本。 localhost:80 是nginx的简易测试页面。

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..."

身体没有解码。为什么?

切换到 ruby-head (2.0) 后它可以工作。 - puchu
4个回答

9

如果在升级到Ruby 2.0后,之前在Ruby 1.9中运行的代码出现问题,请将该代码包含在您的项目中。

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

1
你救了我的一天!谢谢。 - Matteo Alessani
这个问题的根本原因有什么想法吗? - Mark Nadig
Ruby 2.0代码在"@decode_content"设置为true之前不会执行gzip解码。 - datacompboy
@decode_content默认为false,而且不改变内容长度的情况下,解码后的长度与传输长度不相等--这就是我必须覆盖它的原因。 - datacompboy
这段代码救了我的命。太棒了,知道 Ruby 2.0 直到 @decode_content 设置为 true 才执行 gzip 解码。 - Richardsondx
显示剩余2条评论

6

3
根据我的实验,造成这种情况的原因之一是由于 right_http_connection gem。我测试了版本1.3.0和1.4.0。这个gem对Net::HTTP进行了monkey patch,并导致解码GZipped响应时出现问题。
你可以在这个GitHub issue中了解更多关于这个问题的信息。

是的,您应该先检查Gemfile。包括 right_awsright_http_connection 将会破坏 Net::HTTP。这些库已经不再维护且不支持2.0版本。使用 aws-sdk 是使用AWS的推荐方式。 - Arne Brasseur

1

我认为它不会自动执行。

要解码,请尝试以下代码片段(假设响应是StringIO):

begin
  Zlib::GzipReader.new(response).read
rescue Zlib::GzipFile::Error, Zlib::Error # Not gzipped
  response.rewind
  response.read
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接