为什么 content_length 在 Net::HTTP.get_response 中有时甚至是好的结果?
why is content_length in Net::HTTP.get_response sometimes nil even on good results?
我有以下 ruby 代码(试图编写一个简单的 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"
为什么res2
content_length不显示?它是否在 res2 的其他属性中(人们如何看待这些属性?)
我是 ruby 的新人。在 AWS Linux
上使用 irb 0.9.6
非常感谢。
看起来返回的值不一定是body的长度,而是内容的固定长度,当这个固定长度是预先知道的并存储在content-length
header.
参见 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
在这种情况下,这可能意味着响应是 multi-part MIME 响应,并且在这种情况下不使用 content-length
header。
在这种情况下,您最有可能想要的是 body.length
,因为这是判断 multi-part 响应的响应 body 实际长度的唯一真实方法。
请注意,始终使用 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
并在出现任何潜在的性能问题时处理它。
无论您是否收到 multi-part 响应的简单响应,这都应该为您可靠地检索内容的实际长度。
我有以下 ruby 代码(试图编写一个简单的 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"
为什么res2
content_length不显示?它是否在 res2 的其他属性中(人们如何看待这些属性?)
我是 ruby 的新人。在 AWS Linux
上使用irb 0.9.6
非常感谢。
看起来返回的值不一定是body的长度,而是内容的固定长度,当这个固定长度是预先知道的并存储在content-length
header.
参见 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
在这种情况下,这可能意味着响应是 multi-part MIME 响应,并且在这种情况下不使用 content-length
header。
在这种情况下,您最有可能想要的是 body.length
,因为这是判断 multi-part 响应的响应 body 实际长度的唯一真实方法。
请注意,始终使用 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
并在出现任何潜在的性能问题时处理它。
无论您是否收到 multi-part 响应的简单响应,这都应该为您可靠地检索内容的实际长度。