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 Body must respond to each and must only yield String values. The Body itself should not be an instance of String, as this will break in Ruby 1.9. 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

Returns a new instance of Output.



54
55
56
57
58
59
# File 'lib/falcon/adapters/output.rb', line 54

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

Instance Attribute Details

#bodyObject (readonly)

The rack response body.



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

def body
  @body
end

#lengthObject (readonly)

The content length of the rack response body.



65
66
67
# File 'lib/falcon/adapters/output.rb', line 65

def length
  @length
end

Class Method Details

.wrap(status, headers, body) ⇒ Object

Wraps an array into a buffered body.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/falcon/adapters/output.rb', line 34

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



71
72
73
74
75
76
77
78
79
80
# File 'lib/falcon/adapters/output.rb', line 71

def close(error = nil)
  if @body and @body.respond_to?(:close)
    @body.close
  end
  
  @body = nil
  @chunks = nil
  
  super
end

#each(&block) ⇒ Object



82
83
84
85
86
# File 'lib/falcon/adapters/output.rb', line 82

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

#empty?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/falcon/adapters/output.rb', line 67

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

#inspectObject



96
97
98
# File 'lib/falcon/adapters/output.rb', line 96

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

#readObject



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

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