ruby - 如何取消 Ruby Net::HTTP 请求?

标签 ruby

如何让 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 calling head, but then you're using it again as a block parameter.

Just check the content type before you call request_get, conditional on content_type.

关于ruby - 如何取消 Ruby Net::HTTP 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2180183/

相关文章:

ruby - 您如何确定特定 Ruby Gem 的旧版本是什么?

ruby-on-rails - 关于 Rails 和 Node.js 的说明

ruby - 引用自身内部的哈希项

javascript - 浏览器已完成加载, capybara 仍无法通过测试

ruby - 我如何测试我是否正确地与 mixin 接口(interface)?

ruby - 我如何枚举我们的 Redis 数据库中的所有键?

ruby-on-rails - 如何在 Ruby 中从 Savon 调用此安全 Web 服务 WSDL?

ruby - 用于调试目的的 gem native 扩展的输出

ruby - 如何使用 rspec 测试 CLI 的标准输入

java - Ruby web 开发的良好框架