Class: Protocol::Rack::Body::Enumerable

Inherits:
HTTP::Body::Readable
  • Object
show all
Defined in:
lib/protocol/rack/body/enumerable.rb

Overview

Wraps a Rack response body that responds to ‘each`. The body must only yield `String` values and may optionally respond to `close`. This class provides both streaming and buffered access to the response body.

Constant Summary collapse

CONTENT_LENGTH =

The content-length header key.

"content-length".freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(body, length) ⇒ Enumerable

Initialize the enumerable body wrapper.



38
39
40
41
42
43
# File 'lib/protocol/rack/body/enumerable.rb', line 38

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

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



46
47
48
# File 'lib/protocol/rack/body/enumerable.rb', line 46

def body
  @body
end

#lengthObject (readonly)

Returns the value of attribute length.



49
50
51
# File 'lib/protocol/rack/body/enumerable.rb', line 49

def length
  @length
end

#The total size of the response body in bytes.(totalsizeoftheresponsebody) ⇒ Object (readonly)



49
# File 'lib/protocol/rack/body/enumerable.rb', line 49

attr :length

Class Method Details

.wrap(body, length = nil) ⇒ Object

Wraps a Rack response body into an Protocol::Rack::Body::Enumerable instance. If the body is an Array, its total size is calculated automatically.



25
26
27
28
29
30
31
32
# File 'lib/protocol/rack/body/enumerable.rb', line 25

def self.wrap(body, length = nil)
  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

#call(stream) ⇒ Object

Stream the response body to the given stream. The body is automatically closed after streaming.



108
109
110
111
112
113
114
# File 'lib/protocol/rack/body/enumerable.rb', line 108

def call(stream)
  @body.call(stream)
rescue => error
  raise
ensure
  self.close(error)
end

#close(error = nil) ⇒ Object

Close the response body. If the body responds to ‘close`, it will be called.



71
72
73
74
75
76
77
78
79
80
# File 'lib/protocol/rack/body/enumerable.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

Enumerate the response body. Each chunk yielded must be a String. The body is automatically closed after enumeration.



88
89
90
91
92
93
94
# File 'lib/protocol/rack/body/enumerable.rb', line 88

def each(&block)
  @body.each(&block)
rescue => error
  raise
ensure
  self.close(error)
end

#empty?Boolean

Check if the response body is empty. A body is considered empty if its length is 0 or if it responds to ‘empty?` and is empty.



55
56
57
# File 'lib/protocol/rack/body/enumerable.rb', line 55

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

#inspectObject

Get a string representation of the body.



131
132
133
# File 'lib/protocol/rack/body/enumerable.rb', line 131

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

#readObject

Read the next chunk from the response body. Returns nil when there are no more chunks.



120
121
122
123
124
125
126
# File 'lib/protocol/rack/body/enumerable.rb', line 120

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

#ready?Boolean

Check if the response body can be read immediately. A body is ready if it’s an Array or responds to ‘to_ary`.



63
64
65
# File 'lib/protocol/rack/body/enumerable.rb', line 63

def ready?
  body.is_a?(Array) or body.respond_to?(:to_ary)
end

#stream?Boolean

Check if the body is a streaming response. A body is streaming if it doesn’t respond to ‘each`.



100
101
102
# File 'lib/protocol/rack/body/enumerable.rb', line 100

def stream?
  !@body.respond_to?(:each)
end

#The wrapped Rack response body.=(wrappedRackresponsebody. = (value)) ⇒ Object



46
# File 'lib/protocol/rack/body/enumerable.rb', line 46

attr :body