为什么Net :: HTTP.get_response中的content_length有时甚至没有好结果?

时间:2016-05-03 21:20:02

标签: ruby irb

我有以下ruby代码(试图写一个简单的http-ping)

res2

为什么irb 0.9.6 content_length没有显示?它是否属于res2的其他属性(如何看待那些?)

我是红宝石的新人。在AWS Linux上使用i*j

非常感谢。

1 个答案:

答案 0 :(得分:1)

看来返回的值不一定是正文的长度,而是内容的固定长度,当预先知道该固定长度并存储在content-length标题中时。

请参阅HTTPHeader#content_length的实现来源(取自http://ruby-doc.org/stdlib-2.3.1/libdoc/net/http/rdoc/Net/HTTPHeader.html):

# File net/http/header.rb, line 262
def content_length
  return nil unless key?('Content-Length')
  len = self['Content-Length'].slice(/\d+/) or
      raise Net::HTTPHeaderSyntaxError, 'wrong Content-Length format'
  len.to_i
end

在这种情况下,这可能意味着响应是多部分MIME响应,在这种情况下不使用content-length标头。

在这种情况下,您最可能想要的是body.length,因为这是告诉多部分响应的响应正文长度的唯一真实方法。

请注意,始终使用content.body查找内容长度可能会影响性能;您可以选择首先尝试content_length方法,如果它没有,则回退到body.length

以下是您的代码的示例修改:

require 'net/http'
res1 = Net::HTTP.get_response 'www.google.com' , '/'
res2 = Net::HTTP.get_response 'www.google.com' , '/search?q=abc'

res1.code #200
res2.code #200
res1.content_length #5213
res2.content_length.nil? ? res2.body.length : res2.content_length #57315  **<<<<<<<<<<<<<<< Works now **
res2.body[0..60]
=> "<!doctype html><html itemscope=\"\" itemtype=\"http://schema.org"

或者更好的是,捕获content_length并使用捕获的值进行比较:

res2_content_length = res2.content_length

if res2_content_length.nil?
    res2_content_length = res2.body.length
end

就个人而言,我一直坚持不断检查body.length并在出现任何潜在的性能问题时处理。

无论您是否收到多部分响应的简单响应,都应该可靠地为您检索内容的实际长度。