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



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



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



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

def rewindable?
	true
end