Class: Dis::ResponseBody
- Inherits:
-
Object
- Object
- Dis::ResponseBody
- Defined in:
- lib/dis/response_body.rb
Overview
Dis Response Body
Rack body that streams an open file and closes it once the response has been sent. The file may already be unlinked, so it is read through the open descriptor and never by path.
Streams only the given ranges when any are given, as a
multipart/byteranges payload if there is more than one.
Constant Summary collapse
- CHUNK_SIZE =
16_384
Instance Attribute Summary collapse
-
#boundary ⇒ String?
readonly
The multipart boundary, when multipart.
-
#ranges ⇒ Array<Range>
readonly
The ranges being streamed.
Instance Method Summary collapse
-
#abort ⇒ void
Releases the file.
-
#body ⇒ String
Returns the contents as a binary string.
-
#close ⇒ void
Signals that no more content will be written.
-
#each {|chunk| ... } ⇒ void
Yields the contents in chunks.
-
#initialize(file, ranges: nil, content_type: nil) ⇒ ResponseBody
constructor
A new instance of ResponseBody.
-
#length ⇒ Integer
Returns the number of bytes that will be written.
-
#multipart? ⇒ Boolean
Whether more than one range is being streamed.
-
#range ⇒ Range?
The range being streamed, unless multipart.
Constructor Details
#initialize(file, ranges: nil, content_type: nil) ⇒ ResponseBody
Returns a new instance of ResponseBody.
28 29 30 31 32 33 |
# File 'lib/dis/response_body.rb', line 28 def initialize(file, ranges: nil, content_type: nil) @file = file @ranges = Array(ranges) @content_type = content_type @boundary = SecureRandom.hex(16) if multipart? end |
Instance Attribute Details
#boundary ⇒ String? (readonly)
Returns the multipart boundary, when multipart.
23 24 25 |
# File 'lib/dis/response_body.rb', line 23 def boundary @boundary end |
#ranges ⇒ Array<Range> (readonly)
Returns the ranges being streamed.
20 21 22 |
# File 'lib/dis/response_body.rb', line 20 def ranges @ranges end |
Instance Method Details
#abort ⇒ void
This method returns an undefined value.
Releases the file. Rack's end-of-response close arrives here through ActionDispatch::Response#abort.
86 87 88 |
# File 'lib/dis/response_body.rb', line 86 def abort @file.close unless @file.closed? end |
#body ⇒ String
Returns the contents as a binary string.
58 59 60 |
# File 'lib/dis/response_body.rb', line 58 def body (+"").b.tap { |out| each { |chunk| out << chunk } } end |
#close ⇒ void
This method returns an undefined value.
Signals that no more content will be written. This does not release the file. ActionController::Live calls it as soon as the body is assigned, long before Rack iterates it.
78 79 80 |
# File 'lib/dis/response_body.rb', line 78 def close nil end |
#each {|chunk| ... } ⇒ void
This method returns an undefined value.
Yields the contents in chunks.
66 67 68 69 70 71 |
# File 'lib/dis/response_body.rb', line 66 def each(&) return stream(0, @file.size, &) if ranges.empty? return stream(range.begin, range.size, &) unless multipart? each_part(&) end |
#length ⇒ Integer
Returns the number of bytes that will be written.
48 49 50 51 52 53 |
# File 'lib/dis/response_body.rb', line 48 def length return @file.size if ranges.empty? return multipart_length if multipart? range.size end |
#multipart? ⇒ Boolean
Returns whether more than one range is being streamed.
36 37 38 |
# File 'lib/dis/response_body.rb', line 36 def multipart? ranges.length > 1 end |
#range ⇒ Range?
Returns the range being streamed, unless multipart.
41 42 43 |
# File 'lib/dis/response_body.rb', line 41 def range ranges.first unless multipart? end |