Class: Protocol::HTTP::Body::Rewindable

Inherits:
Wrapper show all
Defined in:
lib/protocol/http/body/rewindable.rb

Overview

A body which buffers all its contents as it is read.

As the body is buffered in memory, you may want to ensure your server has sufficient (virtual) memory available to buffer the entire body.

Instance Attribute Summary

Attributes inherited from Wrapper

#body

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Wrapper

#The wrapped body.=, #close, #discard, #length, #to_json

Methods inherited from Readable

#call, #close, #discard, #each, #finish, #join, #length, #stream?, #to_json

Constructor Details

#initialize(body) ⇒ Rewindable

Initialize the body with the given body.



33
34
35
36
37
38
# File 'lib/protocol/http/body/rewindable.rb', line 33

def initialize(body)
  super(body)
  
  @chunks = []
  @index = 0
end

Class Method Details

.wrap(message) ⇒ Object

Wrap the given message body in a rewindable body, if it is not already rewindable.



20
21
22
23
24
25
26
27
28
# File 'lib/protocol/http/body/rewindable.rb', line 20

def self.wrap(message)
  if body = message.body
    if body.rewindable?
      body
    else
      message.body = self.new(body)
    end
  end
end

Instance Method Details

#as_jsonObject

Convert the body to a hash suitable for serialization.



88
89
90
91
92
93
# File 'lib/protocol/http/body/rewindable.rb', line 88

def as_json(...)
  super.merge(
    index: @index,
    chunks: @chunks.size
  )
end

#bufferedObject

A rewindable body wraps some other body. Convert it to a buffered body. The buffered body will share the same chunks as the rewindable body.



53
54
55
# File 'lib/protocol/http/body/rewindable.rb', line 53

def buffered
  Buffered.new(@chunks)
end

#empty?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/protocol/http/body/rewindable.rb', line 41

def empty?
  (@index >= @chunks.size) && super
end

#inspectObject

Inspect the rewindable body.



98
99
100
# File 'lib/protocol/http/body/rewindable.rb', line 98

def inspect
  "#{super} | #<#{self.class} #{@index}/#{@chunks.size} chunks read>"
end

#readObject

Read the next available chunk. This may return a buffered chunk if the stream has been rewound, or a chunk from the underlying stream, if available.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/protocol/http/body/rewindable.rb', line 60

def read
  if @index < @chunks.size
    chunk = @chunks[@index]
    @index += 1
  else
    if chunk = super
      @chunks << -chunk
      @index += 1
    end
  end
  
  # We dup them on the way out, so that if someone modifies the string, it won't modify the rewindability.
  return chunk
end

#ready?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/protocol/http/body/rewindable.rb', line 46

def ready?
  (@index < @chunks.size) || super
end

#rewindObject

Rewind the stream to the beginning.



76
77
78
# File 'lib/protocol/http/body/rewindable.rb', line 76

def rewind
  @index = 0
end

#rewindable?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/protocol/http/body/rewindable.rb', line 81

def rewindable?
  true
end