Class: Biryani::Frame::Headers

Inherits:
Object
  • Object
show all
Defined in:
lib/biryani/frame/headers.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(end_headers, end_stream, stream_id, stream_dependency, weight, fragment, padding) ⇒ Headers

Returns a new instance of Headers.

Parameters:

  • end_headers (Boolean)
  • end_stream (Boolean)
  • stream_id (Integer)
  • stream_dependency (Integer, nil)
  • weight (Integer, nil)
  • fragment (String)
  • padding (String, nil)


13
14
15
16
17
18
19
20
21
22
# File 'lib/biryani/frame/headers.rb', line 13

def initialize(end_headers, end_stream, stream_id, stream_dependency, weight, fragment, padding)
  @f_type = FrameType::HEADERS
  @end_headers = end_headers
  @end_stream = end_stream
  @stream_id = stream_id
  @stream_dependency = stream_dependency
  @weight = weight
  @fragment = fragment
  @padding = padding
end

Instance Attribute Details

#f_typeObject (readonly)

Returns the value of attribute f_type.



4
5
6
# File 'lib/biryani/frame/headers.rb', line 4

def f_type
  @f_type
end

#fragmentObject (readonly)

Returns the value of attribute fragment.



4
5
6
# File 'lib/biryani/frame/headers.rb', line 4

def fragment
  @fragment
end

#paddingObject (readonly)

Returns the value of attribute padding.



4
5
6
# File 'lib/biryani/frame/headers.rb', line 4

def padding
  @padding
end

#stream_dependencyObject (readonly)

Returns the value of attribute stream_dependency.



4
5
6
# File 'lib/biryani/frame/headers.rb', line 4

def stream_dependency
  @stream_dependency
end

#stream_idObject (readonly)

Returns the value of attribute stream_id.



4
5
6
# File 'lib/biryani/frame/headers.rb', line 4

def stream_id
  @stream_id
end

#weightObject (readonly)

Returns the value of attribute weight.



4
5
6
# File 'lib/biryani/frame/headers.rb', line 4

def weight
  @weight
end

Class Method Details

.read(s, flags, stream_id) ⇒ Headers

rubocop: disable Metrics/AbcSize rubocop: disable Metrics/CyclomaticComplexity rubocop: disable Metrics/MethodLength rubocop: disable Metrics/PerceivedComplexity

Parameters:

  • s (String)
  • flags (Integer)
  • stream_id (Integer)

Returns:



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/biryani/frame/headers.rb', line 69

def self.read(s, flags, stream_id)
  priority = Frame.read_priority(flags)
  padded = Frame.read_padded(flags)
  end_headers = Frame.read_end_headers(flags)
  end_stream = Frame.read_end_stream(flags)

  if priority && padded
    io = IO::Buffer.for(s)
    pad_length, stream_dependency, weight = io.get_values(%i[U8 U32 U8], 0)
    fragment_length = s.bytesize - pad_length - 6
    # exclusive = (stream_dependency / 2**31).positive?
    stream_dependency %= 2**31
    return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'cannot depend on itself') if stream_dependency == stream_id

    fragment = io.get_string(6, fragment_length)
    padding = io.get_string(6 + fragment_length)
    return ConnectionError.new(ErrorCode::FRAME_SIZE_ERROR, 'invalid frame') if padding.bytesize != pad_length
  elsif priority
    io = IO::Buffer.for(s)
    stream_dependency, weight = io.get_values(%i[U32 U8], 0)
    # exclusive = (stream_dependency / 2**31).positive?
    stream_dependency %= 2**31
    return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'cannot depend on itself') if stream_dependency == stream_id

    fragment = io.get_string(5)
    return ConnectionError.new(ErrorCode::FRAME_SIZE_ERROR, 'invalid frame') if fragment.bytesize + 5 != s.bytesize
  elsif padded
    io = IO::Buffer.for(s)
    pad_length = io.get_value(:U8, 0)
    fragment_length = s.bytesize - pad_length - 1
    fragment = io.get_string(1, fragment_length)
    padding = io.get_string(1 + fragment_length)
    return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'invalid frame') if pad_length >= s.bytesize
    return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'invalid frame') if padding.bytesize != pad_length
  else
    fragment = s
  end

  Headers.new(end_headers, end_stream, stream_id, stream_dependency, weight, fragment, padding)
end

Instance Method Details

#end_headers?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/biryani/frame/headers.rb', line 35

def end_headers?
  @end_headers
end

#end_stream?Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/biryani/frame/headers.rb', line 40

def end_stream?
  @end_stream
end

#lengthInteger

Returns:

  • (Integer)


45
46
47
# File 'lib/biryani/frame/headers.rb', line 45

def length
  @fragment.bytesize + (padded? ? 1 + @padding.bytesize : 0) + (priority? ? 5 : 0)
end

#padded?Boolean

Returns:

  • (Boolean)


30
31
32
# File 'lib/biryani/frame/headers.rb', line 30

def padded?
  !@padding.nil?
end

#priority?Boolean

Returns:

  • (Boolean)


25
26
27
# File 'lib/biryani/frame/headers.rb', line 25

def priority?
  !@stream_dependency.nil? && !@weight.nil?
end

#to_binary_sString

Returns:

  • (String)


50
51
52
53
54
55
56
57
58
# File 'lib/biryani/frame/headers.rb', line 50

def to_binary_s
  payload_length = length
  flags = Frame.to_flags(priority: priority?, padded: padded?, end_headers: end_headers?, end_stream: end_stream?)
  pad_length = padded? ? @padding.bytesize.chr : ''
  stream_dependency_weight = priority? ? [@stream_dependency, @weight].pack('NC') : ''
  padding = @padding || ''

  Frame.to_binary_s_header(payload_length, @f_type, flags, @stream_id) + pad_length + stream_dependency_weight + @fragment + padding
end