Class: Falcon::Adapters::Output
- Inherits:
-
Protocol::HTTP::Body::Readable
- Object
- Protocol::HTTP::Body::Readable
- Falcon::Adapters::Output
- Defined in:
- lib/falcon/adapters/output.rb
Overview
Wraps the rack response body.
The `rack` body must respond to `each` and must only yield `String` values. If the body responds to `close`, it will be called after iteration. If the body is replaced by a middleware after action, the original body must be closed first, if it responds to `close`. If the body responds to `to_path`, it must return a String identifying the location of a file whose contents are identical to that produced by calling `each`; this may be used by the server as an alternative, possibly more efficient way to transport the response. The body commonly is an `Array` of strings, the application instance itself, or a `File`-like object.
Constant Summary collapse
- CONTENT_LENGTH =
'content-length'.freeze
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
The rack response body.
-
#length ⇒ Object
readonly
The content length of the rack response body.
Class Method Summary collapse
-
.wrap(status, headers, body, request = nil) ⇒ Object
Wraps an array into a buffered body.
Instance Method Summary collapse
-
#close(error = nil) ⇒ Object
Close the response body.
-
#each(&block) ⇒ Object
Enumerate the response body.
-
#empty? ⇒ Boolean
Whether the body is empty.
-
#initialize(body, length) ⇒ Output
constructor
Initialize the output wrapper.
- #inspect ⇒ Object
-
#read ⇒ Object
Read the next chunk from the response body.
-
#ready? ⇒ Boolean
Whether the body can be read immediately.
Constructor Details
#initialize(body, length) ⇒ Output
Initialize the output wrapper.
79 80 81 82 83 84 |
# File 'lib/falcon/adapters/output.rb', line 79 def initialize(body, length) @length = length @body = body @chunks = nil end |
Instance Attribute Details
#body ⇒ Object (readonly)
The rack response body.
87 88 89 |
# File 'lib/falcon/adapters/output.rb', line 87 def body @body end |
#length ⇒ Object (readonly)
The content length of the rack response body.
90 91 92 |
# File 'lib/falcon/adapters/output.rb', line 90 def length @length end |
Class Method Details
.wrap(status, headers, body, request = nil) ⇒ Object
Wraps an array into a buffered body.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/falcon/adapters/output.rb', line 38 def self.wrap(status, headers, body, request = nil) # In no circumstance do we want this header propagating out: if length = headers.delete(CONTENT_LENGTH) # We don't really trust the user to provide the right length to the transport. length = Integer(length) end # If we have an Async::HTTP body, we return it directly: if body.is_a?(::Protocol::HTTP::Body::Readable) # warn "Returning #{body.class} as body is falcon-specific and may be removed in the future!" return body end # Otherwise, we have a more typical response body: if status == 200 and body.respond_to?(:to_path) begin # Don't mangle partial responses (206) return ::Protocol::HTTP::Body::File.open(body.to_path).tap do body.close if body.respond_to?(:close) # Close the original body. end rescue Errno::ENOENT # If the file is not available, ignore. end end # If we have a streaming body, we hijack the connection: unless body.respond_to?(:each) return Async::HTTP::Body::Hijack.new(body, request&.body) end if body.is_a?(Array) length ||= body.sum(&:bytesize) return self.new(body, length) else return self.new(body, length) end end |
Instance Method Details
#close(error = nil) ⇒ Object
Close the response body.
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/falcon/adapters/output.rb', line 103 def close(error = nil) if @body and @body.respond_to?(:close) @body.close end @body = nil @chunks = nil super end |
#each(&block) ⇒ Object
Enumerate the response body.
117 118 119 120 121 |
# File 'lib/falcon/adapters/output.rb', line 117 def each(&block) @body.each(&block) ensure self.close($!) end |
#empty? ⇒ Boolean
Whether the body is empty.
93 94 95 |
# File 'lib/falcon/adapters/output.rb', line 93 def empty? @length == 0 or (@body.respond_to?(:empty?) and @body.empty?) end |
#inspect ⇒ Object
133 134 135 |
# File 'lib/falcon/adapters/output.rb', line 133 def inspect "\#<#{self.class} length=#{@length.inspect} body=#{@body.class}>" end |
#read ⇒ Object
Read the next chunk from the response body.
125 126 127 128 129 130 131 |
# File 'lib/falcon/adapters/output.rb', line 125 def read @chunks ||= @body.to_enum(:each) return @chunks.next rescue StopIteration return nil end |
#ready? ⇒ Boolean
Whether the body can be read immediately.
98 99 100 |
# File 'lib/falcon/adapters/output.rb', line 98 def ready? body.is_a?(Array) or body.respond_to?(:to_ary) end |