简体   繁体   English

为什么在Net :: HTTP.get_response中的content_length有时即使为良好结果也为零?

[英]why is content_length in Net::HTTP.get_response sometimes nil even on good results?

I have the following ruby code (was trying to write a simple http-ping) 我有以下红宝石代码(试图写一个简单的http-ping)

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 **<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< WHY**
res2.body[0..60]
=> "<!doctype html><html itemscope=\"\" itemtype=\"http://schema.org"

Why does res2 content_length does not show through? 为什么res2 content_length无法显示? Is it in some other attribute of res2 (how does one see those?) 它是否在res2的其他属性中(如何看到它们?)

I am a newcomer at ruby. 我是红宝石的新手。 Using irb 0.9.6 on AWS Linux 在AWS Linux上使用irb 0.9.6

Thanks a lot. 非常感谢。

It appears that the value returned is not necessarily the length of the body, but the fixed length of the content, when that fixed length is known in advance and stored in the content-length header. 看起来,返回的值不一定是主体的长度,而是内容的固定长度(当该固定长度预先已知并存储在content-length标头中时)。

See the source for the implementation of HTTPHeader#content_length (taken from http://ruby-doc.org/stdlib-2.3.1/libdoc/net/http/rdoc/Net/HTTPHeader.html ): 请参阅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

What this probably means in this case is that the response was a multi-part MIME response, and the content-length header is not used in this case. 在这种情况下,这可能意味着该响应是一个多部分的MIME响应,并且在这种情况下未使用content-length标头。

What you most likely want in this case is body.length , since that's the only real way to tell the actual length of the response body for a multi-part response. 在这种情况下,您最可能需要的是body.length ,因为这是告诉多部分响应的响应主体实际长度的唯一真实方法。

Note that may be performance implications by always using content.body to find the content length; 注意,始终使用content.body查找内容长度可能会对性能产生影响; you may choose to try the content_length approach first and if it's nil, fall back to body.length . 您可以选择先尝试使用content_length方法,如果没有,则退回到body.length

Here's an example modification to your code: 这是对代码的示例修改:

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"

or, better yet, capture the content_length and use the captured value for comparison: 或者更好的是,捕获content_length并将捕获的值用于比较:

res2_content_length = res2.content_length

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

Personally, I'd just stick with always checking body.length and deal with any potential performance issue if and when it arises. 就个人而言,我总是坚持检查body.length并在出现问题时处理任何潜在的性能问题。

This should reliably retrieve the actual length of the content for you, regardless of whether you received a simple response of a multi-part response. 无论您是否收到多部分响应的简单响应,这都应该为您可靠地检索内容的实际长度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM