1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
# frozen_string_literal: true
# Released under the MIT License.
# Copyright, 2019-2024, by Samuel Williams.
require "protocol/http2/headers_frame"
require "protocol/http2/connection_context"
require "protocol/http2/a_frame"
describe Protocol::HTTP2::HeadersFrame do
let(:data) {"Hello World!"}
let(:frame) {subject.new}
it_behaves_like Protocol::HTTP2::AFrame do
def before
frame.set_flags(Protocol::HTTP2::END_HEADERS)
frame.pack data
super
end
end
with "#pack" do
it "adds appropriate padding" do
frame.pack data
expect(frame.length).to be == 12
expect(frame).not.to be(:priority?)
end
it "ignores priority data" do
frame.pack "xxxxx" + data
frame.set_flags(Protocol::HTTP2::PRIORITY)
expect(frame.length).to be == 17
expect(frame).to be(:priority?)
expect(frame.unpack).to be == data
end
end
with "#unpack" do
it "removes padding" do
frame.pack data
expect(frame.unpack).to be == data
end
end
with "#continuation" do
let(:stream) {StringIO.new}
def before
frame.pack "Hello World", maximum_size: 8
super
end
it "generates chain of frames" do
expect(frame).to be(:continued?)
expect(frame.continuation).to be(:end_headers?)
expect(frame.length).to be == 8
expect(frame.continuation).not.to be_nil
expect(frame.continuation.length).to be == 3
end
it "can read and write continuation frames" do
frame.write(stream)
stream.rewind
frame2 = subject.new
frame2.read(stream, 128)
expect(frame).to be(:continued?)
expect(frame.continuation).to be(:end_headers?)
expect(frame.length).to be == 8
expect(frame.continuation).not.to be_nil
expect(frame.continuation.length).to be == 3
end
it "fails if the stream id of the continuation doesn't match" do
frame.continuation.stream_id = frame.stream_id+1
frame.write(stream)
stream.rewind
frame2 = subject.new
expect do
frame2.read(stream, 128)
end.to raise_exception(Protocol::HTTP2::ProtocolError, message: be =~ /Invalid stream id/)
end
it "fails if the frame type of the continuation doesn't match" do
frame.continuation.type = frame.type+1
frame.write(stream)
stream.rewind
frame2 = subject.new
expect do
frame2.read(stream, 128)
end.to raise_exception(Protocol::HTTP2::ProtocolError, message: be =~ /Invalid frame type/)
end
end
with "client/server connection" do
include_context Protocol::HTTP2::ConnectionContext
def before
client.open!
server.open!
# We force this to something low so we can exceed it without hitting the socket buffer:
server.local_settings.current.instance_variable_set(:@maximum_frame_size, 128)
super
end
let(:stream) {client.create_stream}
it "rejects headers frame that exceeds maximum frame size" do
frame.stream_id = stream.id
frame.pack "\0" * (server.local_settings.maximum_frame_size + 1)
client.write_frame(frame)
expect do
server.read_frame
end.to raise_exception(Protocol::HTTP2::FrameSizeError)
expect(client).to receive(:receive_goaway)
expect do
client.read_frame
end.to raise_exception(Protocol::HTTP2::GoawayError)
end
end
with "#inspect" do
it "can generate a string representation" do
expect(frame.inspect).to be =~ /Protocol::HTTP2::HeadersFrame stream_id=0 flags=0 0b/
end
end
end
|