我正在使用net/http库调用read_body两次(IOError).我正在尝试下载文件并有效地使用http会话.寻求一些帮助或建议来解决我的问题.从我的调试消息中,它在我记录响应代码时出现,readbody = true.这就是为什么当我尝试以块的形式编写大文件时read_body被读取两次?
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>'
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
编辑:修改后的答案!
Net::HTTP#request,当没有阻挡地召唤时,将先发制人地阅读身体.文档对此并不清楚,但它通过建议在块传递时不读取正文来暗示它.
如果你想在不读取正文的情况下发出请求,你需要将一个块传递给请求调用,然后从中读取正文.也就是说,你想要这样的东西:
@http.request request do |response|
# ...
response.read_body do |chunk|
# ...
end
end
Run Code Online (Sandbox Code Playgroud)
这在实施中已经明确; Response#reading_body如果给出(来自#transport_request,从中调用#request),将首先产生对块的未读响应,然后无条件地读取主体.block参数#request使您有机会在读取正文之前拦截响应.
| 归档时间: |
|
| 查看次数: |
1686 次 |
| 最近记录: |