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