在阅读网页正文时,似乎Ruby的Net :: HTTP的方法全是或全无。我怎样才能读取身体的前100个字节?如何使用Net :: HTTP只读取身体的x个字节?
我试图从在响应的身体返回短错误消息,如果请求的文件不可用内容服务器来读取。我需要阅读足够的内容才能确定文件是否存在。这些文件是巨大的,所以我不想让整个机构检查文件是否可用。
在阅读网页正文时,似乎Ruby的Net :: HTTP的方法全是或全无。我怎样才能读取身体的前100个字节?如何使用Net :: HTTP只读取身体的x个字节?
我试图从在响应的身体返回短错误消息,如果请求的文件不可用内容服务器来读取。我需要阅读足够的内容才能确定文件是否存在。这些文件是巨大的,所以我不想让整个机构检查文件是否可用。
你不能。但为什么你需要?当然,如果页面只是说文件不可用,那么它不会是一个巨大的页面(即根据定义,文件不会在那里)?
确定的内容服务器只返回一个简短的错误页面?
不还设置HTTPResponse
适当的像404的东西在这种情况下你可以捕获HTTPClientError
派生的异常(最有可能HTTPNotFound
)的访问时Net::HTTP.value()
提高。
如果你得到一个错误,那么如果你得到200文件开始下载,你可以关闭连接您的文件是不存在。
要读取的块HTTP请求的身体,你需要使用Net::HTTPResponse#read_body
这样的:
http.request_get('/large_resource') do |response|
response.read_body do |segment|
print segment
end
end
试过这个。 request_get仍然希望在处理该块之前下载整个文件。 – bvanderw 2008-09-17 13:36:14
这对我的分块响应(使用`Transfer-Encoding:chunked`)有效,如果我在两个块(在两个“end”之前)都添加一个“break”以在获得第一个块之后停止。在这种情况下,使用带有`read_body`的块使Ruby不会读取完整的响应(甚至不会等待它)。但是,再次说明:我的回答大致是从一开始,而这些都是小块。我怀疑HTTP允许客户端明确请求分块响应,也不允许它建议最大块大小;如果服务器不返回(小)块,似乎应该使用`Range`头。 – Arjan 2015-05-01 12:49:09
你不应该只使用一个HTTP请求HEAD
(红宝石Net::HTTP::Head
方法),看是否资源是否存在,并且只有在获得2xx或3xx响应时才会继续?这假定您的服务器配置为在文档不可用时返回4xx错误代码。我会认为这是正确的解决方案。
另一种方法是请求HTTP头并查看结果中的content-length
标头值:如果您的服务器配置正确,您应该能够轻松地分辨出短消息和长文档之间的长度差异。另一种方法是:在请求中设置content-range
标头字段(它再次假定服务器的行为正确WRT HTTP规范)。
我不认为解决客户端之后之后发送GET请求的问题是一条可行之路:到那时,网络已经完成了繁重的工作,而且您不会真的节省浪费的资源。
试过,服务器发送一个OK响应和一个0的内容长度。这是Perforce的P4Web服务器。 – bvanderw 2008-09-17 13:34:43
嗯。如果你的供应商发送200 OK,当它真的意味着404没有找到时,你应该提高优先级bugrep! – 2008-09-17 14:49:35
我想做这一次,我能想到的唯一的事情就是猴子修补Net::HTTP#read_body
和Net::HTTP#read_body_0
方法接受一个长度参数,然后在前者只是通过长度参数写入read_body_0
方法,其中只能读取长度字节。
这是一个古老的线程,但如何通过Ruby的HTTP只读文件的一部分的问题仍然是根据我的研究大多是没有答案的。这是我想出了一个解决方案由猴子修补的Net :: HTTP一点:
require 'net/http'
# provide access to the actual socket
class Net::HTTPResponse
attr_reader :socket
end
uri = URI("http://www.example.com/path/to/file")
begin
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Get.new(uri.request_uri)
# calling request with a block prevents body from being read
http.request(request) do |response|
# do whatever limited reading you want to do with the socket
x = response.socket.read(100);
# be sure to call finish before exiting the block
http.finish
end
end
rescue IOError
# ignore
end
救援捕捉,当你调用过早那HTTP.finish抛出真实的IO错误。
仅供参考,HTTPResponse
对象中的插座是不是一个真正的IO
对象(这就是所谓的一个内部类),但它很容易猴补丁,也模仿你所需要的IO
方法。例如,我正在使用的另一个库(exifr)需要readchar
方法,该方法很容易添加:
class Net::BufferedIO
def readchar
read(1)[0].ord
end
end
这不是一个答案。这是你无法想象的东西可能是必要/有用/可取的,因为你个人还没有遇到过。谁在乎他为什么需要?谁在乎,如果你有这个问题的最终结果?问题是“如何使用Net :: HTTP只读取身体的x个字节?” “。你知不知道怎么?如果不是,你为什么要浪费每个人的带宽? – 2017-03-10 07:48:03