File: push_promise_frame.rb

package info (click to toggle)
ruby-protocol-http2 0.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 472 kB
  • sloc: ruby: 3,627; makefile: 4
file content (106 lines) | stat: -rw-r--r-- 2,731 bytes parent folder | download
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
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2019-2024, by Samuel Williams.

require "protocol/http2/push_promise_frame"
require "protocol/http2/connection_context"
require "protocol/http2/a_frame"

describe Protocol::HTTP2::PushPromiseFrame do
	let(:stream_id) {5}
	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 stream_id, data
			
			super
		end
	end
	
	with "#pack" do
		it "packs stream_id and data with padding" do
			frame.pack stream_id, data
			
			expect(frame.padded?).to be_falsey
			expect(frame.length).to be == 16
		end
	end
	
	with "#unpack" do
		it "unpacks stream_id and data" do
			frame.pack stream_id, data
			
			expect(frame.unpack).to be == [stream_id, data]
		end
	end
	
	with "client/server connection" do
		include_context Protocol::HTTP2::ConnectionContext
		
		def before
			client.open!
			server.open!
			
			super
		end
		
		let(:stream) {client.create_stream}
		
		let(:request_headers) do
			[[":method", "GET"], [":authority", "Earth"], [":path", "/index.html"]]
		end
		
		let(:push_promise_headers) do
			[[":method", "GET"], [":authority", "Earth"], [":path", "/index.css"]]
		end
		
		it "sends push promise to client" do
			# Client sends a request:
			stream.send_headers(request_headers)
			
			# Server receives request:
			expect(server.read_frame).to be_a Protocol::HTTP2::HeadersFrame
			
			# Get the request stream on the server:
			server_stream = server.streams[stream.id]
			
			# Push a promise back through the stream:
			promised_stream = server_stream.send_push_promise(push_promise_headers)
			
			expect(client).to receive(:receive_push_promise) do |frame|
				stream, headers = super(frame)
				
				expect(stream.id).to be == promised_stream.id
				expect(headers).to be == push_promise_headers
			end
			
			expect(client.read_frame).to be_a Protocol::HTTP2::PushPromiseFrame
		end
		
		it "fails if the same push promise is sent twice" do
			# Client sends a request:
			stream.send_headers(request_headers)
			
			# Server receives request:
			expect(server.read_frame).to be_a Protocol::HTTP2::HeadersFrame
			
			# Get the request stream on the server:
			server_stream = server.streams[stream.id]
			
			# Push a promise back through the stream:
			promised_stream = server_stream.send_push_promise(push_promise_headers)
			
			push_promise_frame = client.read_frame
			expect(push_promise_frame).to be_a Protocol::HTTP2::PushPromiseFrame
			
			# Force the stream to be sent a 2nd time:
			expect do
				push_promise_frame.apply(client)
			end.to raise_exception(Protocol::HTTP2::Error)
		end
	end
end