aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2015-10-25 11:08:18 +0900
committerKazuki Yamaguchi <k@rhe.jp>2015-10-25 11:17:46 +0900
commit68412f1d63ac1336210ee357b573f8308e2f5b97 (patch)
treeebe7db18b5c602e387020e418a7669aa982eb7e2
parent5c4290f57af852f4b9bae8aba3774dd23f58bd19 (diff)
downloadplum-68412f1d63ac1336210ee357b573f8308e2f5b97.tar.gz
improve performance
-rw-r--r--lib/plum/binary_string.rb10
-rw-r--r--lib/plum/connection.rb11
-rw-r--r--lib/plum/flow_control.rb4
-rw-r--r--lib/plum/frame.rb64
-rw-r--r--lib/plum/frame_factory.rb10
-rw-r--r--lib/plum/hpack/context.rb7
-rw-r--r--lib/plum/hpack/decoder.rb96
-rw-r--r--lib/plum/hpack/encoder.rb35
-rw-r--r--lib/plum/stream.rb15
-rw-r--r--test/plum/hpack/test_decoder.rb16
-rw-r--r--test/plum/hpack/test_encoder.rb6
-rw-r--r--test/plum/test_frame.rb5
-rw-r--r--test/utils/server.rb4
13 files changed, 151 insertions, 132 deletions
diff --git a/lib/plum/binary_string.rb b/lib/plum/binary_string.rb
index 72b38b1..053be05 100644
--- a/lib/plum/binary_string.rb
+++ b/lib/plum/binary_string.rb
@@ -4,7 +4,7 @@ module Plum
# Reads a 8-bit unsigned integer.
# @param pos [Integer] The start position to read.
def uint8(pos = 0)
- byteslice(pos, 1).unpack("C")[0]
+ getbyte(pos)
end
# Reads a 16-bit unsigned integer.
@@ -16,7 +16,8 @@ module Plum
# Reads a 24-bit unsigned integer.
# @param pos [Integer] The start position to read.
def uint24(pos = 0)
- (uint16(pos) << 8) | uint8(pos + 2)
+ a, b = byteslice(pos, 3).unpack("nC")
+ (a * 0x100) | b
end
# Reads a 32-bit unsigned integer.
@@ -27,7 +28,7 @@ module Plum
# Appends a 8-bit unsigned integer to this string.
def push_uint8(val)
- self << [val].pack("C")
+ self << val.chr
end
# Appends a 16-bit unsigned integer to this string.
@@ -37,8 +38,7 @@ module Plum
# Appends a 24-bit unsigned integer to this string.
def push_uint24(val)
- push_uint16(val >> 8)
- push_uint8(val & ((1 << 8) - 1))
+ self << [val / 0x100, val % 0x100].pack("nC")
end
# Appends a 32-bit unsigned integer to this string.
diff --git a/lib/plum/connection.rb b/lib/plum/connection.rb
index e8dc1e8..56e5607 100644
--- a/lib/plum/connection.rb
+++ b/lib/plum/connection.rb
@@ -84,6 +84,7 @@ module Plum
private
def send_immediately(frame)
callback(:send_frame, frame)
+ #frame.assemble
@io.write(frame.assemble)
end
@@ -107,8 +108,8 @@ module Plum
end
stream = Stream.new(self, stream_id, **args)
- callback(:stream, stream)
@streams[stream_id] = stream
+ callback(:stream, stream)
stream
end
@@ -122,14 +123,14 @@ module Plum
raise ConnectionError.new(:protocol_error)
end
- if frame.flags.include?(:end_headers)
+ if frame.end_headers?
@state = :open
@continuation_id = nil
end
end
if [:headers].include?(frame.type)
- if !frame.flags.include?(:end_headers)
+ if !frame.end_headers?
@state = :waiting_continuation
@continuation_id = frame.stream_id
end
@@ -180,7 +181,7 @@ module Plum
end
def receive_settings(frame, send_ack: true)
- if frame.flags.include?(:ack)
+ if frame.ack?
raise ConnectionError.new(:frame_size_error) if frame.length != 0
callback(:settings_ack)
return
@@ -210,7 +211,7 @@ module Plum
def receive_ping(frame)
raise Plum::ConnectionError.new(:frame_size_error) if frame.length != 8
- if frame.flags.include?(:ack)
+ if frame.ack?
callback(:ping_ack)
else
opaque_data = frame.payload
diff --git a/lib/plum/flow_control.rb b/lib/plum/flow_control.rb
index f01905a..d1903a7 100644
--- a/lib/plum/flow_control.rb
+++ b/lib/plum/flow_control.rb
@@ -82,8 +82,8 @@ module Plum
end
r_wsi = frame.payload.uint32
- r = r_wsi >> 31
- wsi = r_wsi & ~(1 << 31)
+ # r = r_wsi >> 31 # currently not used
+ wsi = r_wsi # & ~(1 << 31)
if wsi == 0
local_error = (Connection === self) ? ConnectionError : StreamError
diff --git a/lib/plum/frame.rb b/lib/plum/frame.rb
index 6520247..f54938a 100644
--- a/lib/plum/frame.rb
+++ b/lib/plum/frame.rb
@@ -17,6 +17,7 @@ module Plum
window_update: 0x08,
continuation: 0x09
}.freeze
+ FRAME_TYPES_INVERSE = FRAME_TYPES.invert.freeze
FRAME_FLAGS = {
data: {
@@ -48,6 +49,8 @@ module Plum
}.freeze
}.freeze
+ FRAME_FLAGS_MAP = FRAME_FLAGS.values.inject(:merge).freeze
+
SETTINGS_TYPE = {
header_table_size: 0x01,
enable_push: 0x02,
@@ -78,10 +81,10 @@ module Plum
attr_accessor :payload
def initialize(type: nil, type_value: nil, flags: nil, flags_value: nil, stream_id: nil, payload: nil)
- self.payload = (payload || "")
- self.type_value = type_value or self.type = type
- self.flags_value = flags_value or self.flags = flags
- self.stream_id = stream_id or raise ArgumentError.new("stream_id is necessary")
+ @payload = payload.to_s
+ @type_value = type_value or self.type = type
+ @flags_value = flags_value or self.flags = flags
+ @stream_id = stream_id or raise ArgumentError.new("stream_id is necessary")
end
# Returns the length of payload.
@@ -93,13 +96,13 @@ module Plum
# Returns the type of the frame in Symbol.
# @return [Symbol] The type.
def type
- FRAME_TYPES.key(type_value) || ("unknown_%02x" % type_value).to_sym
+ FRAME_TYPES_INVERSE[@type_value] || ("unknown_%02x" % @type_value).to_sym
end
# Sets the frame type.
# @param value [Symbol] The type.
def type=(value)
- self.type_value = FRAME_TYPES[value] or raise ArgumentError.new("unknown frame type: #{value}")
+ @type_value = FRAME_TYPES[value] or raise ArgumentError.new("unknown frame type: #{value}")
end
# Returns the set flags on the frame.
@@ -107,26 +110,37 @@ module Plum
def flags
fs = FRAME_FLAGS[type]
[0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80]
- .select {|v| flags_value & v > 0 }
+ .select {|v| @flags_value & v > 0 }
.map {|val| fs && fs.key(val) || ("unknown_%02x" % val).to_sym }
end
# Sets the frame flags.
- # @param value [Array<Symbol>] The flags.
- def flags=(value)
- self.flags_value = (value && value.map {|flag| FRAME_FLAGS[self.type][flag] }.inject(:|) || 0)
+ # @param values [Array<Symbol>] The flags.
+ def flags=(values)
+ val = 0
+ FRAME_FLAGS_MAP.values_at(*values).each { |c|
+ val |= c if c
+ }
+ @flags_value = val
end
+ # Frame#flag_name?() == Frame#flags().include?(:flag_name)
+ # TODO
+ FRAME_FLAGS_MAP.each { |name, value|
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
+ def #{name}?
+ @flags_value & #{value} > 0
+ end
+ EOS
+ }
+
# Assembles the frame into binary representation.
# @return [String] Binary representation of this frame.
def assemble
- bytes = "".force_encoding(Encoding::BINARY)
- bytes.push_uint24(length)
- bytes.push_uint8(type_value)
- bytes.push_uint8(flags_value)
- bytes.push_uint32(stream_id & ~(1 << 31)) # first bit is reserved (MUST be 0)
- bytes.push(payload.b)
- bytes
+ [length / 0x100, length % 0x100,
+ @type_value,
+ @flags_value,
+ @stream_id].pack("nCCCN") << @payload
end
# @private
@@ -136,23 +150,19 @@ module Plum
# Parses a frame from given buffer. It changes given buffer.
#
- # @param buffer [String] The buffer stored the data received from peer.
+ # @param buffer [String] The buffer stored the data received from peer. Encoding must be Encoding::BINARY.
# @return [Frame, nil] The parsed frame or nil if the buffer is imcomplete.
def self.parse!(buffer)
- buffer.force_encoding(Encoding::BINARY)
-
- return nil if buffer.size < 9 # header: 9 bytes
+ return nil if buffer.bytesize < 9 # header: 9 bytes
length = buffer.uint24
- return nil if buffer.size < 9 + length
+ return nil if buffer.bytesize < 9 + length
bhead = buffer.byteshift(9)
payload = buffer.byteshift(length)
- type_value = bhead.uint8(3)
- flags_value = bhead.uint8(4)
- r_sid = bhead.uint32(5)
- r = r_sid >> 31
- stream_id = r_sid & ~(1 << 31)
+ type_value, flags_value, r_sid = bhead.byteslice(3, 6).unpack("CCN")
+ # r = r_sid >> 31 # currently not used
+ stream_id = r_sid # & ~(1 << 31)
self.new(type_value: type_value,
flags_value: flags_value,
diff --git a/lib/plum/frame_factory.rb b/lib/plum/frame_factory.rb
index b88cfab..3a9fa97 100644
--- a/lib/plum/frame_factory.rb
+++ b/lib/plum/frame_factory.rb
@@ -20,7 +20,7 @@ module Plum
payload.push_uint16(id)
payload.push_uint32(value)
}
- Frame.new(type: :settings, stream_id: 0, flags: [ack].compact, payload: payload)
+ Frame.new(type: :settings, stream_id: 0, flags: [ack], payload: payload)
end
def ping(arg1 = "plum\x00\x00\x00\x00", arg2 = nil)
@@ -33,21 +33,21 @@ module Plum
end
def data(stream_id, payload, *flags)
- Frame.new(type: :data, stream_id: stream_id, flags: flags.compact, payload: payload.to_s)
+ Frame.new(type: :data, stream_id: stream_id, flags: flags, payload: payload)
end
def headers(stream_id, encoded, *flags)
- Frame.new(type: :headers, stream_id: stream_id, flags: flags.compact, payload: encoded)
+ Frame.new(type: :headers, stream_id: stream_id, flags: flags, payload: encoded)
end
def push_promise(stream_id, new_id, encoded, *flags)
payload = "".push_uint32(0 << 31 | new_id)
.push(encoded)
- Frame.new(type: :push_promise, stream_id: stream_id, flags: flags.compact, payload: payload)
+ Frame.new(type: :push_promise, stream_id: stream_id, flags: flags, payload: payload)
end
def continuation(stream_id, payload, *flags)
- Frame.new(type: :continuation, stream_id: stream_id, flags: flags.compact, payload: payload)
+ Frame.new(type: :continuation, stream_id: stream_id, flags: flags, payload: payload)
end
end
end
diff --git a/lib/plum/hpack/context.rb b/lib/plum/hpack/context.rb
index 71f07cb..d15249a 100644
--- a/lib/plum/hpack/context.rb
+++ b/lib/plum/hpack/context.rb
@@ -16,8 +16,9 @@ module Plum
end
def store(name, value)
+ value = value.to_s
@dynamic_table.unshift([name, value])
- @size += name.bytesize + value.to_s.bytesize + 32
+ @size += name.bytesize + value.bytesize + 32
evict
end
@@ -34,7 +35,7 @@ module Plum
end
def search(name, value)
- pr = proc {|n, v|
+ pr = proc { |n, v|
n == name && (!value || v == value)
}
@@ -47,7 +48,7 @@ module Plum
def evict
while @limit && @size > @limit
name, value = @dynamic_table.pop
- @size -= name.bytesize + value.to_s.bytesize + 32
+ @size -= name.bytesize + value.bytesize + 32
end
end
end
diff --git a/lib/plum/hpack/decoder.rb b/lib/plum/hpack/decoder.rb
index 13833c1..b536123 100644
--- a/lib/plum/hpack/decoder.rb
+++ b/lib/plum/hpack/decoder.rb
@@ -10,42 +10,47 @@ module Plum
end
def decode(str)
- str = str.dup
headers = []
- headers << parse!(str) while str.size > 0
- headers.compact
+ pos = 0
+ lpos = str.bytesize
+ while pos < lpos
+ l, succ = parse(str, pos)
+ pos += succ
+ headers << l if l
+ end
+ headers
end
private
- def parse!(str)
- first_byte = str.uint8
- if first_byte >= 128 # 0b1XXXXXXX
- parse_indexed!(str)
- elsif first_byte >= 64 # 0b01XXXXXX
- parse_indexing!(str)
- elsif first_byte >= 32 # 0b001XXXXX
- self.limit = read_integer!(str, 5)
- nil
+ def parse(str, pos)
+ first_byte = str.uint8(pos)
+ if first_byte >= 0x80 # 0b1XXXXXXX
+ parse_indexed(str, pos)
+ elsif first_byte >= 0x40 # 0b01XXXXXX
+ parse_indexing(str, pos)
+ elsif first_byte >= 0x20 # 0b001XXXXX
+ self.limit, succ = read_integer(str, pos, 5)
+ [nil, succ]
else # 0b0000XXXX (without indexing) or 0b0001XXXX (never indexing)
- parse_no_indexing!(str)
+ parse_no_indexing(str, pos)
end
end
- def read_integer!(str, prefix_length)
- first_byte = str.byteshift(1).uint8
- raise HPACKError.new("integer: end of buffer") unless first_byte
+ def read_integer(str, pos, prefix_length)
+ raise HPACKError.new("integer: end of buffer") if str.empty?
+ first_byte = str.uint8(pos)
mask = (1 << prefix_length) - 1
ret = first_byte & mask
- return ret if ret < mask
+ return [ret, 1] if ret != mask
octets = 0
- while next_value = str.byteshift(1).uint8
- ret += (next_value & 0b01111111) << (7 * octets)
+ while next_value = str.uint8(pos + octets + 1)
+ ret += (next_value % 0x80) << (7 * octets)
octets += 1
- if next_value < 128
- return ret
+ if next_value < 0x80
+ return [ret, 1 + octets]
elsif octets == 4 # RFC 7541 5.1 tells us that we MUST have limitation. at least > 2 ** 28
raise HPACKError.new("integer: too large integer")
end
@@ -54,29 +59,32 @@ module Plum
raise HPACKError.new("integer: end of buffer")
end
- def read_string!(str)
- first_byte = str.uint8
- raise HPACKError.new("string: end of buffer") unless first_byte
+ def read_string(str, pos)
+ raise HPACKError.new("string: end of buffer") if str.empty?
+ first_byte = str.uint8(pos)
- huffman = (first_byte >> 7) == 1
- length = read_integer!(str, 7)
- bin = str.byteshift(length)
+ huffman = first_byte > 0x80
+ length, ilen = read_integer(str, pos, 7)
+ raise HTTPError.new("string: end of buffer") if str.bytesize < length
- raise HTTPError.new("string: end of buffer") if bin.bytesize < length
- bin = Huffman.decode(bin) if huffman
- bin
+ bin = str.byteslice(pos + ilen, length)
+ if huffman
+ [Huffman.decode(bin), ilen + length]
+ else
+ [bin, ilen + length]
+ end
end
- def parse_indexed!(str)
+ def parse_indexed(str, pos)
# indexed
# +---+---+---+---+---+---+---+---+
# | 1 | Index (7+) |
# +---+---------------------------+
- index = read_integer!(str, 7)
- fetch(index)
+ index, succ = read_integer(str, pos, 7)
+ [fetch(index), succ]
end
- def parse_indexing!(str)
+ def parse_indexing(str, pos)
# +---+---+---+---+---+---+---+---+
# | 0 | 1 | Index (6+) |
# +---+---+-----------------------+
@@ -96,20 +104,21 @@ module Plum
# +---+---------------------------+
# | Value String (Length octets) |
# +-------------------------------+
- index = read_integer!(str, 6)
+ index, ilen = read_integer(str, pos, 6)
if index == 0
- name = read_string!(str)
+ name, nlen = read_string(str, pos + ilen)
else
name, = fetch(index)
+ nlen = 0
end
- val = read_string!(str)
+ val, vlen = read_string(str, pos + ilen + nlen)
store(name, val)
- [name, val]
+ [[name, val], ilen + nlen + vlen]
end
- def parse_no_indexing!(str)
+ def parse_no_indexing(str, pos)
# +---+---+---+---+---+---+---+---+
# | 0 | 0 | 0 |0,1| Index (4+) |
# +---+---+-----------------------+
@@ -129,16 +138,17 @@ module Plum
# +---+---------------------------+
# | Value String (Length octets) |
# +-------------------------------+
- index = read_integer!(str, 4)
+ index, ilen = read_integer(str, pos, 4)
if index == 0
- name = read_string!(str)
+ name, nlen = read_string(str, pos + ilen)
else
name, = fetch(index)
+ nlen = 0
end
- val = read_string!(str)
+ val, vlen = read_string(str, pos + ilen + nlen)
- [name, val]
+ [[name, val], ilen + nlen + vlen]
end
end
end
diff --git a/lib/plum/hpack/encoder.rb b/lib/plum/hpack/encoder.rb
index 2dc2482..d78f96e 100644
--- a/lib/plum/hpack/encoder.rb
+++ b/lib/plum/hpack/encoder.rb
@@ -14,8 +14,8 @@ module Plum
def encode(headers)
out = ""
headers.each do |name, value|
- name = name.to_s.b
- value = value.to_s.b
+ name = name.to_s
+ value = value.to_s
if index = search(name, value)
out << encode_indexed(index)
elsif index = search(name, nil)
@@ -59,10 +59,9 @@ module Plum
def encode_half_indexed(index, value)
if @indexing
store(fetch(index)[0], value)
- fb = encode_integer(index, 6)
- fb.setbyte(0, fb.uint8 | 0b01000000)
+ fb = encode_integer(index, 6, 0b01000000)
else
- fb = encode_integer(index, 4)
+ fb = encode_integer(index, 4, 0b00000000)
end
fb << encode_string(value)
end
@@ -71,27 +70,24 @@ module Plum
# | 1 | Index (7+) |
# +---+---------------------------+
def encode_indexed(index)
- s = encode_integer(index, 7)
- s.setbyte(0, s.uint8 | 0b10000000)
- s
+ encode_integer(index, 7, 0b10000000)
end
- def encode_integer(value, prefix_length)
+ def encode_integer(value, prefix_length, hmask)
mask = (1 << prefix_length) - 1
- out = ""
if value < mask
- out.push_uint8(value)
+ (value + hmask).chr.force_encoding(Encoding::BINARY)
else
+ vals = [mask + hmask]
value -= mask
- out.push_uint8(mask)
while value >= mask
- out.push_uint8((value % 0b10000000) + 0b10000000)
- value >>= 7
+ vals << (value % 0x80) + 0x80
+ value /= 0x80
end
- out.push_uint8(value)
+ vals << value
+ vals.pack("C*")
end
- out.force_encoding(Encoding::BINARY)
end
def encode_string(str)
@@ -105,14 +101,13 @@ module Plum
end
def encode_string_plain(str)
- encode_integer(str.bytesize, 7) << str.force_encoding(Encoding::BINARY)
+ encode_integer(str.bytesize, 7, 0b00000000) << str.force_encoding(Encoding::BINARY)
end
def encode_string_huffman(str)
huffman_str = Huffman.encode(str)
- lenstr = encode_integer(huffman_str.bytesize, 7)
- lenstr.setbyte(0, lenstr.uint8(0) | 0b10000000)
- lenstr.force_encoding(Encoding::BINARY) << huffman_str
+ lenstr = encode_integer(huffman_str.bytesize, 7, 0b10000000)
+ lenstr << huffman_str
end
end
end
diff --git a/lib/plum/stream.rb b/lib/plum/stream.rb
index eee7cad..007d352 100644
--- a/lib/plum/stream.rb
+++ b/lib/plum/stream.rb
@@ -105,7 +105,7 @@ module Plum
raise StreamError.new(:stream_closed)
end
- if frame.flags.include?(:padded)
+ if frame.padded?
padding_length = frame.payload.uint8(0)
if padding_length >= frame.length
raise ConnectionError.new(:protocol_error, "padding is too long")
@@ -116,18 +116,17 @@ module Plum
end
callback(:data, body)
- receive_end_stream if frame.flags.include?(:end_stream)
+ receive_end_stream if frame.end_stream?
end
def receive_complete_headers(frames)
- frames = frames.dup
first = frames.shift
payload = first.payload
first_length = first.length
padding_length = 0
- if first.flags.include?(:padded)
+ if first.padded?
padding_length = payload.uint8
first_length -= 1 + padding_length
payload = payload.byteslice(1, first_length)
@@ -135,7 +134,7 @@ module Plum
payload = payload.dup
end
- if first.flags.include?(:priority)
+ if first.priority?
receive_priority_payload(payload.byteshift(5))
first_length -= 5
end
@@ -156,7 +155,7 @@ module Plum
callback(:headers, decoded_headers)
- receive_end_stream if first.flags.include?(:end_stream)
+ receive_end_stream if first.end_stream?
end
def receive_headers(frame)
@@ -171,7 +170,7 @@ module Plum
@state = :open
callback(:open)
- if frame.flags.include?(:end_headers)
+ if frame.end_headers?
receive_complete_headers([frame])
else
@continuation << frame
@@ -182,7 +181,7 @@ module Plum
# state error mustn't happen: server_connection validates
@continuation << frame
- if frame.flags.include?(:end_headers)
+ if frame.end_headers?
receive_complete_headers(@continuation)
@continuation.clear
end
diff --git a/test/plum/hpack/test_decoder.rb b/test/plum/hpack/test_decoder.rb
index 9acb821..9a500f7 100644
--- a/test/plum/hpack/test_decoder.rb
+++ b/test/plum/hpack/test_decoder.rb
@@ -4,38 +4,38 @@ class HPACKDecoderTest < Minitest::Test
# C.1.1
def test_hpack_read_integer_small
buf = [0b11001010, 0b00001111].pack("C*")
- result = new_decoder.__send__(:read_integer!, buf, 5)
+ result, succ = new_decoder.__send__(:read_integer, buf, 0, 5)
assert_equal(10, result)
- assert_equal([0b00001111].pack("C*"), buf)
+ assert_equal(1, succ)
end
# C.1.2
def test_hpack_read_integer_big
buf = [0b11011111, 0b10011010, 0b00001010, 0b00001111].pack("C*")
- result = new_decoder.__send__(:read_integer!, buf, 5)
+ result, succ = new_decoder.__send__(:read_integer, buf, 0, 5)
assert_equal(1337, result)
- assert_equal([0b00001111].pack("C*"), buf)
+ assert_equal(3, succ)
end
# C.1.3
def test_hpack_read_integer_8prefix
buf = [0b00101010, 0b00001111].pack("C*")
- result = new_decoder.__send__(:read_integer!, buf, 8)
+ result, succ = new_decoder.__send__(:read_integer, buf, 0, 8)
assert_equal(42, result)
- assert_equal([0b00001111].pack("C*"), buf)
+ assert_equal(1, succ)
end
def test_hpack_read_integer_too_big
buf = [0b11011111, 0b10011010, 0b10001010, 0b10001111, 0b11111111, 0b00000011].pack("C*")
assert_raises(HPACKError) {
- new_decoder.__send__(:read_integer!, buf, 5)
+ new_decoder.__send__(:read_integer, buf, 0, 5)
}
end
def test_hpack_read_integer_incomplete
buf = [0b11011111, 0b10011010].pack("C*")
assert_raises(HPACKError) {
- new_decoder.__send__(:read_integer!, buf, 5)
+ new_decoder.__send__(:read_integer, buf, 0, 5)
}
end
diff --git a/test/plum/hpack/test_encoder.rb b/test/plum/hpack/test_encoder.rb
index 3c56dfc..a0096ed 100644
--- a/test/plum/hpack/test_encoder.rb
+++ b/test/plum/hpack/test_encoder.rb
@@ -3,19 +3,19 @@ require "test_helper"
class HPACKEncoderTest < Minitest::Test
# C.1.1
def test_hpack_encode_integer_small
- result = new_encoder(1 << 31).__send__(:encode_integer, 10, 5)
+ result = new_encoder(1 << 31).__send__(:encode_integer, 10, 5, 0b00000000)
assert_equal([0b00001010].pack("C*"), result)
end
# C.1.2
def test_hpack_encode_integer_big
- result = new_encoder(1 << 31).__send__(:encode_integer, 1337, 5)
+ result = new_encoder(1 << 31).__send__(:encode_integer, 1337, 5, 0b000000)
assert_equal([0b00011111, 0b10011010, 0b00001010].pack("C*"), result)
end
# C.1.3
def test_hpack_encode_integer_8prefix
- result = new_encoder(1 << 31).__send__(:encode_integer, 42, 8)
+ result = new_encoder(1 << 31).__send__(:encode_integer, 42, 8, 0b000000)
assert_equal([0b00101010].pack("C*"), result)
end
diff --git a/test/plum/test_frame.rb b/test/plum/test_frame.rb
index 0cd9e7e..4795627 100644
--- a/test/plum/test_frame.rb
+++ b/test/plum/test_frame.rb
@@ -4,6 +4,7 @@ class FrameTest < Minitest::Test
# Frame.parse!
def test_parse_header_uncomplete
buffer = "\x00\x00\x00" << "\x00" << "\x00"
+ buffer.force_encoding(Encoding::BINARY)
buffer_orig = buffer.dup
assert_nil(Plum::Frame.parse!(buffer))
assert_equal(buffer_orig, buffer)
@@ -11,6 +12,7 @@ class FrameTest < Minitest::Test
def test_parse_body_uncomplete
buffer = "\x00\x00\x03" << "\x00" << "\x00" << "\x00\x00\x00\x00" << "ab"
+ buffer.force_encoding(Encoding::BINARY)
buffer_orig = buffer.dup
assert_nil(Plum::Frame.parse!(buffer))
assert_equal(buffer_orig, buffer)
@@ -18,7 +20,8 @@ class FrameTest < Minitest::Test
def test_parse
# R 0x1, stream_id 0x4, body "abc"
- buffer = "\x00\x00\x03" << "\x00" << "\x09" << "\x80\x00\x00\x04" << "abc" << "next_frame_data"
+ buffer = "\x00\x00\x03" << "\x00" << "\x09" << "\x00\x00\x00\x04" << "abc" << "next_frame_data"
+ buffer.force_encoding(Encoding::BINARY)
frame = Plum::Frame.parse!(buffer)
assert_equal(3, frame.length)
assert_equal(:data, frame.type)
diff --git a/test/utils/server.rb b/test/utils/server.rb
index e3b8386..e0bdae9 100644
--- a/test/utils/server.rb
+++ b/test/utils/server.rb
@@ -31,7 +31,7 @@ module ServerUtils
end
def sent_frames(con = nil)
- resp = (con || @_con).io.string.dup
+ resp = (con || @_con).io.string.dup.force_encoding(Encoding::BINARY)
frames = []
while f = Frame.parse!(resp)
frames << f
@@ -43,7 +43,7 @@ module ServerUtils
io = (con || @_con).io
pos = io.string.bytesize
blk.call
- resp = io.string.byteslice(pos, io.string.bytesize - pos)
+ resp = io.string.byteslice(pos, io.string.bytesize - pos).force_encoding(Encoding::BINARY)
frames = []
while f = Frame.parse!(resp)
frames << f