diff --git a/lib/protocol/http2/frame.rb b/lib/protocol/http2/frame.rb index 690816e..3c05a9c 100644 --- a/lib/protocol/http2/frame.rb +++ b/lib/protocol/http2/frame.rb @@ -146,7 +146,7 @@ def self.parse_header(buffer) end def read_header(stream) - if buffer = stream.read(9) and buffer.bytesize == 9 + if buffer = stream.peek(9) and buffer.bytesize == 9 @length, @type, @flags, @stream_id = Frame.parse_header(buffer) # puts "read_header: #{@length} #{@type} #{@flags} #{@stream_id}" else @@ -155,8 +155,9 @@ def read_header(stream) end def read_payload(stream) - if payload = stream.read(@length) and payload.bytesize == @length - @payload = payload + length_with_header = 9 + @length + if full_frame = stream.read(length_with_header) and full_frame.bytesize == length_with_header + @payload = full_frame[9..] else raise EOFError, "Could not read frame payload!" end diff --git a/lib/protocol/http2/framer.rb b/lib/protocol/http2/framer.rb index f3c8f20..b15c7ac 100644 --- a/lib/protocol/http2/framer.rb +++ b/lib/protocol/http2/framer.rb @@ -3,6 +3,9 @@ # Released under the MIT License. # Copyright, 2019-2024, by Samuel Williams. + +require "async/io/stream" + require_relative 'error' require_relative 'data_frame' @@ -37,7 +40,12 @@ module HTTP2 class Framer def initialize(stream, frames = FRAMES) - @stream = stream + @stream = case stream + when Async::IO::Stream + stream + else + Async::IO::Stream.new(stream) + end @frames = frames end @@ -99,7 +107,7 @@ def write_frame(frame) end def read_header - if buffer = @stream.read(9) + if buffer = @stream.peek(9) if buffer.bytesize == 9 return Frame.parse_header(buffer) end diff --git a/protocol-http2.gemspec b/protocol-http2.gemspec index 75de2e3..45db29e 100644 --- a/protocol-http2.gemspec +++ b/protocol-http2.gemspec @@ -24,6 +24,7 @@ Gem::Specification.new do |spec| spec.required_ruby_version = ">= 3.1" + spec.add_dependency "async-io", "~> 1.37" spec.add_dependency "protocol-hpack", "~> 1.4" spec.add_dependency "protocol-http", "~> 0.18" end