Class: Falcon::Adapters::Output

Inherits:
Protocol::HTTP::Body::Readable
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(body, length) ⇒ Output

Initialize the output wrapper.



61
62
63
64
65
66
# File 'lib/falcon/adapters/output.rb', line 61

def initialize(body, length)
  @length = length
  @body = body
  
  @chunks = nil
end

Instance Attribute Details

#bodyObject (readonly)

The rack response body.



69
70
71
# File 'lib/falcon/adapters/output.rb', line 69

def body
  @body
end

#lengthObject (readonly)

The content length of the rack response body.



72
73
74
# File 'lib/falcon/adapters/output.rb', line 72

def length
  @length
end

Class Method Details

.wrap(status, headers, body) ⇒ 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
# File 'lib/falcon/adapters/output.rb', line 38

def self.wrap(status, headers, body)
  # 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 body.is_a?(::Protocol::HTTP::Body::Readable)
    return body
  elsif status == 200 and body.respond_to?(:to_path)
    # Don't mangle partial responsese (206)
    return ::Protocol::HTTP::Body::File.open(body.to_path)
  elsif 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.



85
86
87
88
89
90
91
92
93
94
# File 'lib/falcon/adapters/output.rb', line 85

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.



99
100
101
102
103
# File 'lib/falcon/adapters/output.rb', line 99

def each(&block)
  @body.each(&block)
ensure
  self.close($!)
end

#empty?Boolean

Whether the body is empty.

Returns:

  • (Boolean)


75
76
77
# File 'lib/falcon/adapters/output.rb', line 75

def empty?
  @length == 0 or (@body.respond_to?(:empty?) and @body.empty?)
end

#inspectObject



115
116
117
# File 'lib/falcon/adapters/output.rb', line 115

def inspect
  "\#<#{self.class} length=#{@length.inspect} body=#{@body.class}>"
end

#readObject

Read the next chunk from the response body.



107
108
109
110
111
112
113
# File 'lib/falcon/adapters/output.rb', line 107

def read
  @chunks ||= @body.to_enum(:each)
  
  return @chunks.next
rescue StopIteration
  return nil
end

#ready?Boolean

Whether the body can be read immediately.

Returns:

  • (Boolean)


80
81
82
# File 'lib/falcon/adapters/output.rb', line 80

def ready?
  true
end