Module: Protocol::HTTP2::Continued

Included in:
ContinuationFrame, HeadersFrame, PushPromiseFrame
Defined in:
lib/protocol/http2/continuation_frame.rb

Overview

Module for frames that can be continued with CONTINUATION frames.

Constant Summary collapse

LIMIT =
8

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#continuationObject

Returns the value of attribute continuation.



78
79
80
# File 'lib/protocol/http2/continuation_frame.rb', line 78

def continuation
  @continuation
end

Instance Method Details

#continued?Boolean

Check if this frame has continuation frames.

Returns:

  • (Boolean)


25
26
27
# File 'lib/protocol/http2/continuation_frame.rb', line 25

def continued?
	!!@continuation
end

#end_headers?Boolean

Check if this is the last header block fragment.

Returns:

  • (Boolean)


31
32
33
# File 'lib/protocol/http2/continuation_frame.rb', line 31

def end_headers?
	flag_set?(END_HEADERS)
end

#initializeObject

Initialize a continuable frame.



17
18
19
20
21
# File 'lib/protocol/http2/continuation_frame.rb', line 17

def initialize(*)
	super
	
	@continuation = nil
end

#pack(data, **options) ⇒ Object

Pack data into this frame, creating continuation frames if needed.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/protocol/http2/continuation_frame.rb', line 83

def pack(data, **options)
	maximum_size = options[:maximum_size]
	
	if maximum_size and data.bytesize > maximum_size
		clear_flags(END_HEADERS)
		
		super(data.byteslice(0, maximum_size), **options)
		
		remainder = data.byteslice(maximum_size, data.bytesize-maximum_size)
		
		@continuation = ContinuationFrame.new
		@continuation.pack(remainder, maximum_size: maximum_size)
	else
		set_flags(END_HEADERS)
		
		super data, **options
		
		@continuation = nil
	end
end

#read(stream, maximum_frame_size, limit = LIMIT) ⇒ Object

Read the frame and any continuation frames from the stream.

There is an upper limit to the number of continuation frames that can be read to prevent resource exhaustion. If the limit is 0, only one frame will be read (the initial frame). Otherwise, the limit decrements with each continuation frame read.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/protocol/http2/continuation_frame.rb', line 42

def read(stream, maximum_frame_size, limit = LIMIT)
	super(stream, maximum_frame_size)
	
	unless end_headers?
		if limit.zero?
			raise ProtocolError, "Too many continuation frames!"
		end
		
		continuation = ContinuationFrame.new
		continuation.read_header(stream)
		
		# We validate the frame type here:
		unless continuation.valid_type?
			raise ProtocolError, "Invalid frame type: #{@type}!"
		end
		
		if continuation.stream_id != @stream_id
			raise ProtocolError, "Invalid stream id: #{continuation.stream_id} for continuation of stream id: #{@stream_id}!"
		end
		
		continuation.read(stream, maximum_frame_size, limit - 1)
		
		@continuation = continuation
	end
end

#unpackObject

Unpack data from this frame and any continuation frames.



106
107
108
109
110
111
112
# File 'lib/protocol/http2/continuation_frame.rb', line 106

def unpack
	if @continuation.nil?
		super
	else
		super + @continuation.unpack
	end
end

#write(stream) ⇒ Object

Write the frame and any continuation frames to the stream.



70
71
72
73
74
75
76
# File 'lib/protocol/http2/continuation_frame.rb', line 70

def write(stream)
	super
	
	if continuation = self.continuation
		continuation.write(stream)
	end
end