class HTTP2Next::FrameBuffer

Attributes

bytesize[R]

Public Class Methods

new() click to toggle source
# File lib/http/2/next/flow_buffer.rb, line 106
def initialize
  @buffer = []
  @bytesize = 0
end

Public Instance Methods

<<(frame) click to toggle source
# File lib/http/2/next/flow_buffer.rb, line 111
def <<(frame)
  @buffer << frame
  @bytesize += frame[:payload].bytesize
end
empty?() click to toggle source
# File lib/http/2/next/flow_buffer.rb, line 116
def empty?
  @bytesize == 0
end
retrieve(window_size) click to toggle source
# File lib/http/2/next/flow_buffer.rb, line 120
def retrieve(window_size)
  frame = @buffer.first or return

  frame_size = frame[:payload].bytesize
  end_stream = frame[:flags].include? :end_stream

  # 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.
  return if window_size <= 0 && !(frame_size == 0 && end_stream)

  @buffer.shift

  if frame_size > window_size
    payload = frame[:payload]
    chunk   = frame.dup

    # Split frame so that it fits in the window
    # TODO: consider padding!
    frame_bytes = payload.byteslice(0, window_size)
    payload = payload.byteslice(window_size..-1)

    frame[:payload] = frame_bytes
    frame[:length] = frame_bytes.bytesize
    chunk[:payload] = payload
    chunk[:length]  = payload.bytesize

    # if no longer last frame in sequence...
    frame[:flags] -= [:end_stream] if end_stream

    @buffer.unshift(chunk)
    @bytesize -= window_size
  else
    @bytesize -= frame_size
  end
  frame
end