首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ruby /http‘`read_body':Net::HTTPOK#read_body调用两次(IOError)

ruby /http‘`read_body':Net::HTTPOK#read_body调用两次(IOError)
EN

Stack Overflow用户
提问于 2015-04-13 05:07:42
回答 1查看 2.5K关注 0票数 3

我正在使用net/http库调用read_body两次(IOError)。我正在努力下载文件并有效地使用http会话。寻求一些帮助或建议来解决我的问题。从我的调试消息中,当我记录响应代码readbody=true时,它就会出现。这就是为什么当我试着用块写大文件时,read_body会被读两次吗?

代码语言:javascript
复制
D, [2015-04-12T21:17:46.954928 #24741] DEBUG -- : #<Net::HTTPOK 200 OK readbody=true>
I, [2015-04-12T21:17:46.955060 #24741]  INFO -- : file found at http://hidden:8080/job/project/1/maven-repository/repository/org/project/service/1/service-1.zip.md5
/usr/lib/ruby/2.2.0/net/http/response.rb:195:in `read_body': Net::HTTPOK#read_body called twice (IOError)
    from ./deploy_application.rb:36:in `block in get_file'
    from ./deploy_application.rb:35:in `open'
    from ./deploy_application.rb:35:in `get_file'
    from ./deploy_application.rb:59:in `block in <main>'
    from ./deploy_application.rb:58:in `each'
    from ./deploy_application.rb:58:in `<main>'
代码语言:javascript
复制
require 'net/http'
require 'logger'

STAMP = Time.now.utc.to_i

@log = Logger.new(STDOUT)

# project , build, service remove variables above
project = "project"
build = "1"
service = "service"
version = "1"
BASE_URI = URI("http://hidden:8080/job/#{project}/#{build}/maven-repository/repository/org/#{service}/#{version}/")

# file pattern for application is zip / jar. Hopefully the lib in the zipfile is acceptable.
# example for module download /#{service}/#{version}.zip /#{service}/#{version}.zip.md5 /#{service}/#{version}.jar /#{service}/#{version}.jar.md5

def clean_exit(code)
  # remove temp files on exit
end

def get_file(file)
  puts BASE_URI 
  uri = URI.join(BASE_URI,file)
  @log.debug(uri)

  request = Net::HTTP::Get.new uri #.request_uri
  @log.debug(request)

  response = @http.request request
  @log.debug(response)

  case response
    when Net::HTTPOK
      size = 0
      progress = 0
      total = response.header["Content-Length"].to_i
      @log.info("file found at #{uri}")

      # need to handle file open error 
      Dir.mkdir "/tmp/#{STAMP}"
      File.open "/tmp/#{STAMP}/#{file}", 'wb' do |io|
        response.read_body do |chunk|
          size += chunk.size
          new_progress = (size * 100) / total

          unless new_progress == progress
             @log.info("\rDownloading %s (%3d%%) " % [file, new_progress])
          end

          progress = new_progress
          io.write chunk
        end
      end

    when 404
      @log.error("maven repository file #{uri} not found")
      exit 4

    when 500...600
      @log.error("error getting #{uri}, server returned #{response.code}")
      exit 5

    else
      @log.error("unknown http response code #{response.code}")
  end
end

@http = Net::HTTP.new(BASE_URI.host, BASE_URI.port)
files = [ "#{service}-#{version}.zip.md5", "#{service}-#{version}.jar", "#{service}-#{version}.jar.md5" ].each do |file| #"#{service}-#{version}.zip",
  get_file(file)
end
EN

回答 1

Stack Overflow用户

发布于 2015-04-13 05:20:45

编辑:修改后的答案!

Net::HTTP#request被调用时,如果没有阻塞,就会先发制人地读取身体.文献资料还不清楚这一点,但它暗示,如果一个块被传递,就不会读取身体。

如果您想在不读取主体的情况下发出请求,则需要将一个块传递给请求调用,然后从请求调用中读取主体。也就是说,你想要这样的东西:

代码语言:javascript
复制
@http.request request do |response|
  # ...
  response.read_body do |chunk|
  # ...
  end
end

实施中可以清楚地看到这一点;如果给定块(来自#transport_request,从#request调用),则Response#reading_body将首先生成未读取的响应,然后无条件地读取正文。#request的块参数为您提供了在读取主体之前拦截响应的机会。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29598196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档