このコミットが含まれているのは:
@@ -15,26 +15,38 @@ class CountsExportDownload
|
||||
|
||||
# Rack body deliberately has no to_path: sendfile middleware must not bypass ACK.
|
||||
class ResponseBody
|
||||
def initialize(path, &state)
|
||||
File.open(path, 'rb') { |file| file.stat }
|
||||
@path = path
|
||||
@stream = nil
|
||||
def initialize body, &state
|
||||
@body = body
|
||||
@closed = false
|
||||
@state = state
|
||||
end
|
||||
|
||||
def each
|
||||
def each &block
|
||||
return enum_for(:each) unless block
|
||||
return if @closed
|
||||
|
||||
@stream = File.open(@path, 'rb')
|
||||
transmit(&block)
|
||||
end
|
||||
|
||||
def close
|
||||
return if @closed
|
||||
|
||||
@closed = true
|
||||
@body.close if @body.respond_to?(:close)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def transmit
|
||||
first = true
|
||||
while (chunk = @stream.read(64 * 1024))
|
||||
@body.each do |chunk|
|
||||
raise IOError, 'Download no longer authorised' unless @state.call('active')
|
||||
|
||||
yield chunk
|
||||
if first
|
||||
# This confirms yielding to Rack, never browser receipt or saving.
|
||||
@state.call('started')
|
||||
# Rack accepted a chunk; browser receipt and saving are not guaranteed.
|
||||
raise IOError, 'Download acknowledgement failed' unless @state.call('started')
|
||||
|
||||
first = false
|
||||
end
|
||||
end
|
||||
@@ -46,11 +58,6 @@ class CountsExportDownload
|
||||
ensure
|
||||
close
|
||||
end
|
||||
|
||||
def close
|
||||
@closed = true
|
||||
@stream.close if @stream && !@stream.closed?
|
||||
end
|
||||
end
|
||||
|
||||
def self.directory
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする