如何让 Ruby 的 Net::HTTP 模块取消请求?
下面对 http.finish
的调用会引发错误。我的印象是响应对象不知道连接已关闭,并且仍然需要更多数据。
我想避免发出 HEAD 请求。因此,发出 GET 请求,除非 content-type 是 HTML,否则取消请求。
Net::HTTP.start(uri.host, uri.port) do |http|
http.request_get(uri.path) do |response|
unless response['content-type'] =~ /html/i
http.finish
end
end
end
/usr/lib/ruby/1.8/net/http.rb:2241:in `stream_check': attempt to read body out of block (IOError)
from /usr/lib/ruby/1.8/net/http.rb:2171:in `read_body'
from /usr/lib/ruby/1.8/net/http.rb:2198:in `body'
from /usr/lib/ruby/1.8/net/http.rb:2137:in `reading_body'
from /usr/lib/ruby/1.8/net/http.rb:1052:in `request'
from /usr/lib/ruby/1.8/net/http.rb:948:in `request_get'
from net.rb:9
from /usr/lib/ruby/1.8/net/http.rb:543:in `start'
from /usr/lib/ruby/1.8/net/http.rb:440:in `start'
from net.rb:7
最佳答案
重新编辑,原答案在底部
我不认为你在你的粘贴中的第一个代码片段中闲置。尝试以下操作来了解我的意思:
h = Net::HTTP.new uri.host,uri.port
h.set_debug_output $stderr
h.start do |http|
http.request_get(uri.path) do |response|
end
end
发生的情况是,通过发出GET
,您的客户端有义务从套接字读取整个文档,无论您是否实际上对其进行了任何操作。这只是 HTTP 规范的一部分。
如果您不调用response.read_body,则会阻止代码将响应读入内存,但在从套接字读取所有数据之前,该 block 不会返回。您的带有 break
调用的 block 会在最终 read
之前中断,这旨在使您的代码符合 HTTP 规范,即使您决定不将响应读入内存也是如此。 I edited your pastie指出最终读取发生的位置。
您恰好正在读取一个很大的 ISO 文件,因此看起来您正在闲置。
简短的回答是,如果您不打算按照 HTTP 规范中的规定读取整个文档,则应该发出 HEAD
请求。
复杂的答案是,如果您发出指定的字节范围 here,则可以发出部分 GET
,但我不确定 ruby http 客户端库是否支持这种操作模式。
通过调用http.finish
,您可以提前关闭 tcp 套接字,这可以让您脱离代码块,但会在调用代码时引发异常,因为您“不应该”这样做。如果您愿意捕获异常,但您没有很好地使用 HTTP,欢迎您调用 finish
。
original answer
You shouldn't be calling
finish
, the connection will get closed when the block exits. Documentation here.The exception is being thrown from this code
If you really want to force the socket to close early, just catch the IOError.
I just noticed that you're initializing
response
to the result of callinghead
, but then you're using it again as a block parameter.Just check the content type before you call
request_get
, conditional oncontent_type
.
关于ruby - 如何取消 Ruby Net::HTTP 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2180183/