module Protocol::HTTP2::FlowControlled

def available_frame_size(maximum_frame_size = self.maximum_frame_size)

This could be negative if the window has been overused due to a change in initial window size.
def available_frame_size(maximum_frame_size = self.maximum_frame_size)
	available_size = self.available_size
	
	# puts "available_size=#{available_size} maximum_frame_size=#{maximum_frame_size}"
	
	if available_size < maximum_frame_size
		return available_size
	else
		return maximum_frame_size
	end
end

def available_size

def available_size
	@remote_window.available
end

def consume_local_window(frame)

def consume_local_window(frame)
	# For flow-control calculations, the 9-octet frame header is not counted.
	amount = frame.length
	@local_window.consume(amount)
end

def consume_remote_window(frame)

Keep track of the amount of data sent, and fail if is too much.
def consume_remote_window(frame)
	amount = frame.length
	
	# Frames with zero length with the END_STREAM flag set (that is, an empty DATA frame) MAY be sent if there is no available space in either flow-control window.
	if amount.zero? and frame.end_stream?
		# It's okay, we can send. No need to consume, it's empty anyway.
	elsif amount >= 0 and amount <= @remote_window.available
		@remote_window.consume(amount)
	else
		raise FlowControlError, "Trying to send #{frame.length} bytes, exceeded window size: #{@remote_window.available} (#{@remote_window})"
	end
end

def receive_window_update(frame)

def receive_window_update(frame)
	amount = frame.unpack
	
	if amount != 0
		@remote_window.expand(amount)
	else
		raise ProtocolError, "Invalid window size increment: #{amount}!"
	end
end

def request_window_update

def request_window_update
	if @local_window.limited?
		self.send_window_update(@local_window.wanted)
	end
end

def send_window_update(window_increment)

Notify the remote end that we are prepared to receive more data:
def send_window_update(window_increment)
	frame = WindowUpdateFrame.new(self.id)
	frame.pack window_increment
	
	write_frame(frame)
	
	@local_window.expand(window_increment)
end

def update_local_window(frame)

def update_local_window(frame)
	consume_local_window(frame)
	request_window_update
end

def window_updated(size)

Returns:
  • (Boolean) - whether the window update was used or not.

Parameters:
  • size (Integer) -- the maximum amount of data to send.
def window_updated(size)
	return false
end