【问题标题】:Ruby http Get returning truncated responseRuby http Get 返回截断的响应
【发布时间】:2015-12-13 21:17:02
【问题描述】:

我尝试通过 Postman 向设备的 Restful API 发送 HTTP Get,它可以正常返回所有我期望的文本。 Postman 建议该请求的 Ruby 代码如下:

url = URI('http://192.168.1.5/rest/op/BD1FD3D893613E79')
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request.basic_auth 'admin', 'admin'
request["accept"] = 'Application/json'
response = http.request(request)
puts response.read_body

但是当我在我的代码中尝试这样做时,它返回了一个截断的响应(缺少行),我必须多次重新发送相同的 Get 以获得整个文本响应响应。

上面的 Ruby 代码中是否缺少任何导致此截断响应的内容?

更新 1

我试过了

url = URI('http://192.168.1.5/rest/op/BD1FD3D893613E79')
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request.basic_auth 'admin', 'admin'
request["accept"] = 'Application/json'
response = http.request(request)
puts response.read_body
response.read_body do |segment|
   puts segment.to_s
end

并且产生了这个错误

IOError (Net::HTTPOK#read_body called twice):

更新 2

我试过了

1073 url = URI('http://192.168.1.5/rest/op/BD1FD3D893613E79')
1074 http = Net::HTTP.new(url.host, url.port)
1075 request = Net::HTTP::Get.new(url.to_s)
1076 request.basic_auth 'admin', 'admin'
1077 request["accept"] = 'Application/json'
1078 response = http.request(request)
1079 response.read_body do |segment|
1080   puts segment.to_s
1081 end

得到了这个错误

IOError (Net::HTTPOK#read_body called twice):
  app/controllers/Apps_controller.rb:1079:in `block in get_config'
  app/controllers/Apps_controller.rb:1045:in `each'
  app/controllers/Apps_controller.rb:1045:in `get_config'

【问题讨论】:

  • 删除puts response.read_body这一行
  • 感谢@Aguardientico 的跟进。我尝试了更新 2 中显示的建议,但仍然没有运气
  • 您是否尝试在同一个服务器实例中同时运行 API 和客户端?你用的是什么服务器?
  • @Aguardientico :感谢您的跟进。客户端是我的 RoR 应用程序,服务器是第 3 方设备。我不知道那里正在运行什么服务器。我只有使用他们的 API 的说明,当我使用 Postman 时它工作正常,但我的应用程序如上所述失败。
  • @rh4games - 你解决了这个问题吗?

标签: http http-get postman


【解决方案1】:

我认为您必须先致电http.start,然后再致电http.request。 不知道为什么,但我也看到了。

【讨论】:

    【解决方案2】:

    我使用的是 OSX Sierra、rvm 和 ruby​​ 2.3.0

    更新我的 rvm、ruby 和 gems 似乎已经解决了我的问题

    【讨论】:

      【解决方案3】:

      看起来很相似....

      从 Bamboo 服务器中提取一组工件(zip 文件)并写入本地存储时,我们收到了截断的响应。它的发生不一致,仅在 8 台服务器中的一台上发生,而且并不总是相同的文件。似乎总是丢失文件的最后一部分。

      使用 Ruby 2.0.0p598 和 net/http。

      zip 文件的大小范围从 2 mb 到 34 mb。

      虽然我们还没有弄清楚响应正文被截断的原因,但我们的解决方法是将预期内容长度(在响应标头中)与响应正文大小进行比较。如果它们不匹配,请再试一次。示例代码:

      package = "packages/applicationname.zip"
      
      def retrieve(package)
      
        # generates the Bamboo url for the given package
        sourceURL = package_url package
      
        expectedLength = 0
        bodyLength = 1
      
        #  Try to catch the bad download and re-issue the GET request,
        while expectedLength != bodyLength do
      
          # add a counter if worried about getting stuck
      
          # issue the request to get the current package zip file
          response = my_request_wrapper sourceURL
      
          expectedLength = response['content-length'].to_i
          theBody = response.body
          bodyLength = theBody.size
      
          if expectedLength != bodyLength then
              puts "!!  SIZE MISMATCH   !!"
          else
              # the response body is good, process as needed
              open package, 'wb' do |io|
                io.write theBody
              end
          end
        end
      end
      
      def my_request_wrapper(url)
        uri = URI.parse(url)
        http = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
        req = Net::HTTP::Get.new(uri.request_uri)
        req.basic_auth("user", "pwd")
        return http.request req
      end
      

      【讨论】:

        【解决方案4】:

        基于:http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTPResponse.html#method-i-read_body

        read_body 将主体作为流返回,因此您应该对其进行迭代,例如:

        response.read_body do |segment|
          puts segment
        end
        

        如果你想获得完整的身体,只需使用:response.body

        【讨论】:

        • 感谢您的快速响应。我用 response.body 替换了 response.read_body 但这并没有改变我的问题。
        • 我唯一能想到的错误是您的第一行代码中缺少的' url = URI('http://192.168.1.5/rest/op/BD1FD3D893613E79) 应该是url = URI('http://192.168.1.5/rest/op/BD1FD3D893613E79')
        • 感谢@Aguardientico。我解决了这个问题,但仍然没有运气,并且您提出的代码“response.read_body do |segment| puts segment end”会生成此错误“IOError (Net::HTTPOK#read_body called two):”
        • 是的,它产生了这个错误“IOError(Net::HTTPOK#read_body 调用了两次):”
        • 你能用产生错误的代码更新问题吗?
        猜你喜欢
        • 2013-03-02
        • 2019-04-24
        • 2023-03-29
        • 1970-01-01
        • 2022-07-20
        • 2011-04-08
        • 1970-01-01
        • 2019-04-15
        • 2018-10-11
        相关资源
        最近更新 更多