1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/core/ext/transport/chttp2/transport/frame.h"
16
17 #include <algorithm>
18 #include <initializer_list>
19 #include <utility>
20
21 #include "absl/status/status.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24
25 #include "src/core/lib/transport/http2_errors.h"
26
27 namespace grpc_core {
28 namespace {
29
30 MATCHER_P2(StatusIs, code, message, "") {
31 return arg.code() == code && arg.message() == message;
32 }
33
DoTheseThings(std::initializer_list<int>)34 void DoTheseThings(std::initializer_list<int>) {}
35
36 template <typename... Frames>
Serialize(Frames...f)37 std::vector<uint8_t> Serialize(Frames... f) {
38 std::vector<Http2Frame> frames;
39 DoTheseThings({(frames.emplace_back(std::move(f)), 1)...});
40 SliceBuffer temp;
41 Serialize(absl::Span<Http2Frame>(frames), temp);
42 auto slice = temp.JoinIntoSlice();
43 return std::vector<uint8_t>(slice.begin(), slice.end());
44 }
45
46 template <typename... I>
ByteVec(I...i)47 std::vector<uint8_t> ByteVec(I... i) {
48 return std::vector<uint8_t>{static_cast<uint8_t>(i)...};
49 }
50
SliceBufferFromString(absl::string_view s)51 SliceBuffer SliceBufferFromString(absl::string_view s) {
52 SliceBuffer temp;
53 temp.Append(Slice::FromCopiedString(s));
54 return temp;
55 }
56
Serialize(const Http2FrameHeader & header)57 std::vector<uint8_t> Serialize(const Http2FrameHeader& header) {
58 uint8_t temp[9];
59 header.Serialize(temp);
60 return std::vector<uint8_t>(temp, temp + 9);
61 }
62
ParseHeader(uint8_t b0,uint8_t b1,uint8_t b2,uint8_t b3,uint8_t b4,uint8_t b5,uint8_t b6,uint8_t b7,uint8_t b8)63 Http2FrameHeader ParseHeader(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3,
64 uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7,
65 uint8_t b8) {
66 uint8_t temp[9] = {b0, b1, b2, b3, b4, b5, b6, b7, b8};
67 return Http2FrameHeader::Parse(temp);
68 }
69
70 template <typename... I>
ParseFrame(I...i)71 Http2Frame ParseFrame(I... i) {
72 SliceBuffer buffer;
73 buffer.Append(Slice::FromCopiedBuffer(ByteVec(i...)));
74 uint8_t hdr[9];
75 buffer.MoveFirstNBytesIntoBuffer(9, hdr);
76 auto frame_hdr = Http2FrameHeader::Parse(hdr);
77 EXPECT_EQ(frame_hdr.length, buffer.Length())
78 << "frame_hdr=" << frame_hdr.ToString();
79 auto r = ParseFramePayload(frame_hdr, std::move(buffer));
80 EXPECT_TRUE(r.ok()) << r.status();
81 return std::move(r.value());
82 }
83
84 template <typename... I>
ValidateFrame(I...i)85 absl::Status ValidateFrame(I... i) {
86 SliceBuffer buffer;
87 buffer.Append(Slice::FromCopiedBuffer(ByteVec(i...)));
88 uint8_t hdr[9];
89 buffer.MoveFirstNBytesIntoBuffer(9, hdr);
90 auto frame_hdr = Http2FrameHeader::Parse(hdr);
91 EXPECT_EQ(frame_hdr.length, buffer.Length())
92 << "frame_hdr=" << frame_hdr.ToString();
93 return ParseFramePayload(frame_hdr, std::move(buffer)).status();
94 }
95
TEST(Header,Serialization)96 TEST(Header, Serialization) {
97 EXPECT_EQ(Serialize(Http2FrameHeader{0, 0, 0, 0}),
98 ByteVec(0, 0, 0, 0, 0, 0, 0, 0, 0));
99 EXPECT_EQ(Serialize(Http2FrameHeader{0x123456, 0x9a, 0xbc, 0x12345678}),
100 ByteVec(0x12, 0x34, 0x56, 0x9a, 0xbc, 0x12, 0x34, 0x56, 0x78));
101 }
102
TEST(Header,Parse)103 TEST(Header, Parse) {
104 EXPECT_EQ(ParseHeader(0, 0, 0, 0, 0, 0, 0, 0, 0),
105 (Http2FrameHeader{0, 0, 0, 0}));
106 EXPECT_EQ(ParseHeader(0x12, 0x34, 0x56, 0x9a, 0xbc, 0x12, 0x34, 0x56, 0x78),
107 (Http2FrameHeader{0x123456, 0x9a, 0xbc, 0x12345678}));
108 }
109
TEST(Header,ToString)110 TEST(Header, ToString) {
111 EXPECT_EQ((Http2FrameHeader{0, 0, 0, 0}).ToString(),
112 "{DATA: flags=0, stream_id=0, length=0}");
113 EXPECT_EQ((Http2FrameHeader{0x123456, 0x9a, 0xbc, 0x12345678}).ToString(),
114 "{UNKNOWN(154): flags=188, stream_id=305419896, length=1193046}");
115 }
116
TEST(Frame,Serialization)117 TEST(Frame, Serialization) {
118 EXPECT_EQ(Serialize(Http2DataFrame{1, false, SliceBufferFromString("hello")}),
119 ByteVec(0, 0, 5, 0, 0, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'));
120 EXPECT_EQ(Serialize(Http2DataFrame{0x98381822, true,
121 SliceBufferFromString("kids")}),
122 ByteVec(0, 0, 4, 0, 1, 0x98, 0x38, 0x18, 0x22, 'k', 'i', 'd', 's'));
123 EXPECT_EQ(Serialize(Http2HeaderFrame{1, false, false,
124 SliceBufferFromString("hello")}),
125 ByteVec(0, 0, 5, 1, 0, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'));
126 EXPECT_EQ(Serialize(Http2HeaderFrame{1, true, false,
127 SliceBufferFromString("hello")}),
128 ByteVec(0, 0, 5, 1, 4, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'));
129 EXPECT_EQ(Serialize(Http2HeaderFrame{1, false, true,
130 SliceBufferFromString("hello")}),
131 ByteVec(0, 0, 5, 1, 1, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'));
132 EXPECT_EQ(Serialize(Http2HeaderFrame{1, true, true,
133 SliceBufferFromString("hello")}),
134 ByteVec(0, 0, 5, 1, 5, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'));
135 EXPECT_EQ(Serialize(Http2ContinuationFrame{1, false,
136 SliceBufferFromString("hello")}),
137 ByteVec(0, 0, 5, 9, 0, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'));
138 EXPECT_EQ(Serialize(Http2ContinuationFrame{1, true,
139 SliceBufferFromString("hello")}),
140 ByteVec(0, 0, 5, 9, 4, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'));
141 EXPECT_EQ(Serialize(Http2RstStreamFrame{1, GRPC_HTTP2_CONNECT_ERROR}),
142 ByteVec(0, 0, 4, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0x0a));
143 EXPECT_EQ(Serialize(Http2SettingsFrame{}),
144 ByteVec(0, 0, 0, 4, 0, 0, 0, 0, 0));
145 EXPECT_EQ(
146 Serialize(Http2SettingsFrame{false, {{0x1234, 0x9abcdef0}}}),
147 ByteVec(0, 0, 6, 4, 0, 0, 0, 0, 0, 0x12, 0x34, 0x9a, 0xbc, 0xde, 0xf0));
148 EXPECT_EQ(Serialize(Http2SettingsFrame{
149 false, {{0x1234, 0x9abcdef0}, {0x4321, 0x12345678}}}),
150 ByteVec(0, 0, 12, 4, 0, 0, 0, 0, 0, 0x12, 0x34, 0x9a, 0xbc, 0xde,
151 0xf0, 0x43, 0x21, 0x12, 0x34, 0x56, 0x78));
152 EXPECT_EQ(Serialize(Http2SettingsFrame{true, {}}),
153 ByteVec(0, 0, 0, 4, 1, 0, 0, 0, 0));
154 EXPECT_EQ(Serialize(Http2PingFrame{false, 0x123456789abcdef0}),
155 ByteVec(0, 0, 8, 6, 0, 0, 0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0x9a,
156 0xbc, 0xde, 0xf0));
157 EXPECT_EQ(Serialize(Http2PingFrame{true, 0x123456789abcdef0}),
158 ByteVec(0, 0, 8, 6, 1, 0, 0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0x9a,
159 0xbc, 0xde, 0xf0));
160 EXPECT_EQ(Serialize(Http2GoawayFrame{0x12345678, GRPC_HTTP2_ENHANCE_YOUR_CALM,
161 Slice::FromCopiedString("hello")}),
162 ByteVec(0, 0, 13, 7, 0, 0, 0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0, 0, 0,
163 0x0b, 'h', 'e', 'l', 'l', 'o'));
164 EXPECT_EQ(Serialize(Http2WindowUpdateFrame{1, 0x12345678}),
165 ByteVec(0, 0, 4, 8, 0, 0, 0, 0, 1, 0x12, 0x34, 0x56, 0x78));
166 }
167
TEST(Frame,Parse)168 TEST(Frame, Parse) {
169 EXPECT_EQ(
170 ParseFrame(0, 0, 5, 0, 0, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'),
171 Http2Frame(Http2DataFrame{1, false, SliceBufferFromString("hello")}));
172 EXPECT_EQ(
173 ParseFrame(0, 0, 4, 0, 1, 0x98, 0x38, 0x18, 0x22, 'k', 'i', 'd', 's'),
174 Http2Frame(
175 Http2DataFrame{0x98381822, true, SliceBufferFromString("kids")}));
176 EXPECT_EQ(ParseFrame(0, 0, 5, 1, 0, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'),
177 Http2Frame(Http2HeaderFrame{1, false, false,
178 SliceBufferFromString("hello")}));
179 EXPECT_EQ(
180 ParseFrame(0, 0, 4, 1, 4, 0x98, 0x38, 0x18, 0x22, 'k', 'i', 'd', 's'),
181 Http2Frame(Http2HeaderFrame{0x98381822, true, false,
182 SliceBufferFromString("kids")}));
183 EXPECT_EQ(
184 ParseFrame(0, 0, 4, 1, 1, 0x98, 0x38, 0x18, 0x22, 'k', 'i', 'd', 's'),
185 Http2Frame(Http2HeaderFrame{0x98381822, false, true,
186 SliceBufferFromString("kids")}));
187 EXPECT_EQ(ParseFrame(0, 0, 5, 9, 0, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'),
188 Http2Frame(Http2ContinuationFrame{1, false,
189 SliceBufferFromString("hello")}));
190 EXPECT_EQ(ParseFrame(0, 0, 5, 9, 4, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o'),
191 Http2Frame(Http2ContinuationFrame{1, true,
192 SliceBufferFromString("hello")}));
193 EXPECT_EQ(ParseFrame(0, 0, 4, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0x0a),
194 Http2Frame(Http2RstStreamFrame{1, GRPC_HTTP2_CONNECT_ERROR}));
195 EXPECT_EQ(ParseFrame(0, 0, 0, 4, 0, 0, 0, 0, 0),
196 Http2Frame(Http2SettingsFrame{}));
197 EXPECT_EQ(
198 ParseFrame(0, 0, 6, 4, 0, 0, 0, 0, 0, 0x12, 0x34, 0x9a, 0xbc, 0xde, 0xf0),
199 Http2Frame(Http2SettingsFrame{false, {{0x1234, 0x9abcdef0}}}));
200 EXPECT_EQ(ParseFrame(0, 0, 12, 4, 0, 0, 0, 0, 0, 0x12, 0x34, 0x9a, 0xbc, 0xde,
201 0xf0, 0x43, 0x21, 0x12, 0x34, 0x56, 0x78),
202 Http2Frame(Http2SettingsFrame{
203 false, {{0x1234, 0x9abcdef0}, {0x4321, 0x12345678}}}));
204 EXPECT_EQ(ParseFrame(0, 0, 0, 4, 1, 0, 0, 0, 0),
205 Http2Frame(Http2SettingsFrame{true, {}}));
206 EXPECT_EQ(ParseFrame(0, 0, 8, 6, 0, 0, 0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0x9a,
207 0xbc, 0xde, 0xf0),
208 Http2Frame(Http2PingFrame{false, 0x123456789abcdef0}));
209 EXPECT_EQ(ParseFrame(0, 0, 8, 6, 1, 0, 0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0x9a,
210 0xbc, 0xde, 0xf0),
211 Http2Frame(Http2PingFrame{true, 0x123456789abcdef0}));
212 EXPECT_EQ(
213 ParseFrame(0, 0, 13, 7, 0, 0, 0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0, 0, 0,
214 0x0b, 'h', 'e', 'l', 'l', 'o'),
215 Http2Frame(Http2GoawayFrame{0x12345678, GRPC_HTTP2_ENHANCE_YOUR_CALM,
216 Slice::FromCopiedString("hello")}));
217 EXPECT_EQ(ParseFrame(0, 0, 4, 8, 0, 0, 0, 0, 1, 0x12, 0x34, 0x56, 0x78),
218 Http2Frame(Http2WindowUpdateFrame{1, 0x12345678}));
219 }
220
TEST(Frame,ParsePadded)221 TEST(Frame, ParsePadded) {
222 EXPECT_EQ(
223 ParseFrame(0, 0, 9, 0, 8, 0, 0, 0, 1, 3, 'h', 'e', 'l', 'l', 'o', 1, 2,
224 3),
225 Http2Frame(Http2DataFrame{1, false, SliceBufferFromString("hello")}));
226 EXPECT_EQ(
227 ParseFrame(0, 0, 8, 1, 8, 0, 0, 0, 1, 2, 'h', 'e', 'l', 'l', 'o', 1, 2),
228 Http2Frame(
229 Http2HeaderFrame{1, false, false, SliceBufferFromString("hello")}));
230 EXPECT_EQ(ParseFrame(0, 0, 10, 1, 32, 0, 0, 0, 1, 1, 2, 3, 4, 5, 'h', 'e',
231 'l', 'l', 'o'),
232 Http2Frame(Http2HeaderFrame{1, false, false,
233 SliceBufferFromString("hello")}));
234 EXPECT_EQ(ParseFrame(0, 0, 13, 1, 40, 0, 0, 0, 1, 2, 1, 2, 3, 4, 5, 'h', 'e',
235 'l', 'l', 'o', 1, 2),
236 Http2Frame(Http2HeaderFrame{1, false, false,
237 SliceBufferFromString("hello")}));
238 }
239
TEST(Frame,UnknownIgnored)240 TEST(Frame, UnknownIgnored) {
241 // 77 = some random undefined frame
242 EXPECT_EQ(
243 ParseFrame(0, 0, 10, 77, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
244 Http2Frame(Http2UnknownFrame{}));
245 // 2 = PRIORITY, we just ignore it
246 EXPECT_EQ(
247 ParseFrame(0, 0, 10, 2, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
248 Http2Frame(Http2UnknownFrame{}));
249 }
250
TEST(Frame,ParseRejects)251 TEST(Frame, ParseRejects) {
252 // 5 == PUSH_PROMISE
253 EXPECT_THAT(
254 ValidateFrame(0, 0, 10, 5, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
255 StatusIs(absl::StatusCode::kInternal,
256 "push promise not supported (and SETTINGS_ENABLE_PUSH "
257 "explicitly disabled)."));
258 EXPECT_THAT(ValidateFrame(0, 0, 0, 0, 0, 0, 0, 0, 0),
259 StatusIs(absl::StatusCode::kInternal,
260 "invalid stream id: {DATA: flags=0, "
261 "stream_id=0, length=0}"));
262 EXPECT_THAT(ValidateFrame(0, 0, 0, 1, 0, 0, 0, 0, 0),
263 StatusIs(absl::StatusCode::kInternal,
264 "invalid stream id: {HEADER: flags=0, "
265 "stream_id=0, length=0}"));
266 EXPECT_THAT(ValidateFrame(0, 0, 0, 9, 0, 0, 0, 0, 0),
267 StatusIs(absl::StatusCode::kInternal,
268 "invalid stream id: {CONTINUATION: flags=0, "
269 "stream_id=0, length=0}"));
270 EXPECT_THAT(ValidateFrame(0, 0, 3, 3, 0, 0, 0, 0, 1, 100, 100, 100),
271 StatusIs(absl::StatusCode::kInternal,
272 "invalid rst stream payload: {RST_STREAM: flags=0, "
273 "stream_id=1, length=3}"));
274 EXPECT_THAT(ValidateFrame(0, 0, 4, 3, 0, 0, 0, 0, 0, 100, 100, 100, 100),
275 StatusIs(absl::StatusCode::kInternal,
276 "invalid stream id: {RST_STREAM: flags=0, "
277 "stream_id=0, length=4}"));
278 EXPECT_THAT(ValidateFrame(0, 0, 1, 4, 1, 0, 0, 0, 0, 1),
279 StatusIs(absl::StatusCode::kInternal,
280 "invalid settings ack length: {SETTINGS: flags=1, "
281 "stream_id=0, length=1}"));
282 EXPECT_THAT(ValidateFrame(0, 0, 1, 4, 0, 0, 0, 0, 0, 1),
283 StatusIs(absl::StatusCode::kInternal,
284 "invalid settings payload: {SETTINGS: flags=0, "
285 "stream_id=0, length=1} -- settings must be multiples "
286 "of 6 bytes long"));
287 EXPECT_THAT(ValidateFrame(0, 0, 2, 4, 0, 0, 0, 0, 0, 1, 1),
288 StatusIs(absl::StatusCode::kInternal,
289 "invalid settings payload: {SETTINGS: flags=0, "
290 "stream_id=0, length=2} -- settings must be multiples "
291 "of 6 bytes long"));
292 EXPECT_THAT(ValidateFrame(0, 0, 3, 4, 0, 0, 0, 0, 0, 1, 1, 1),
293 StatusIs(absl::StatusCode::kInternal,
294 "invalid settings payload: {SETTINGS: flags=0, "
295 "stream_id=0, length=3} -- settings must be multiples "
296 "of 6 bytes long"));
297 EXPECT_THAT(ValidateFrame(0, 0, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1),
298 StatusIs(absl::StatusCode::kInternal,
299 "invalid settings payload: {SETTINGS: flags=0, "
300 "stream_id=0, length=4} -- settings must be multiples "
301 "of 6 bytes long"));
302 EXPECT_THAT(ValidateFrame(0, 0, 5, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1),
303 StatusIs(absl::StatusCode::kInternal,
304 "invalid settings payload: {SETTINGS: flags=0, "
305 "stream_id=0, length=5} -- settings must be multiples "
306 "of 6 bytes long"));
307 EXPECT_THAT(ValidateFrame(0, 0, 7, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1),
308 StatusIs(absl::StatusCode::kInternal,
309 "invalid settings payload: {SETTINGS: flags=0, "
310 "stream_id=0, length=7} -- settings must be multiples "
311 "of 6 bytes long"));
312 EXPECT_THAT(ValidateFrame(0, 0, 0, 4, 0, 0, 0, 0, 1),
313 StatusIs(absl::StatusCode::kInternal,
314 "invalid stream id: {SETTINGS: flags=0, "
315 "stream_id=1, length=0}"));
316 EXPECT_THAT(ValidateFrame(0, 0, 0, 6, 0, 0, 0, 0, 0),
317 StatusIs(absl::StatusCode::kInternal,
318 "invalid ping payload: {PING: flags=0, "
319 "stream_id=0, length=0}"));
320 EXPECT_THAT(ValidateFrame(0, 0, 8, 6, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8),
321 StatusIs(absl::StatusCode::kInternal,
322 "invalid ping stream id: {PING: flags=0, "
323 "stream_id=1, length=8}"));
324 EXPECT_THAT(ValidateFrame(0, 0, 8, 6, 2, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8),
325 StatusIs(absl::StatusCode::kInternal,
326 "invalid ping flags: {PING: flags=2, "
327 "stream_id=0, length=8}"));
328 EXPECT_THAT(
329 ValidateFrame(0, 0, 8, 6, 255, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8),
330 StatusIs(absl::StatusCode::kInternal,
331 "invalid ping flags: {PING: flags=255, "
332 "stream_id=0, length=8}"));
333 EXPECT_THAT(ValidateFrame(0, 0, 0, 7, 0, 0, 0, 0, 0),
334 StatusIs(absl::StatusCode::kInternal,
335 "invalid goaway payload: {GOAWAY: flags=0, "
336 "stream_id=0, length=0} -- must be at least 8 bytes"));
337 EXPECT_THAT(ValidateFrame(0, 0, 1, 7, 0, 0, 0, 0, 0, 1),
338 StatusIs(absl::StatusCode::kInternal,
339 "invalid goaway payload: {GOAWAY: flags=0, "
340 "stream_id=0, length=1} -- must be at least 8 bytes"));
341 EXPECT_THAT(ValidateFrame(0, 0, 2, 7, 0, 0, 0, 0, 0, 1, 1),
342 StatusIs(absl::StatusCode::kInternal,
343 "invalid goaway payload: {GOAWAY: flags=0, "
344 "stream_id=0, length=2} -- must be at least 8 bytes"));
345 EXPECT_THAT(ValidateFrame(0, 0, 3, 7, 0, 0, 0, 0, 0, 1, 1, 1),
346 StatusIs(absl::StatusCode::kInternal,
347 "invalid goaway payload: {GOAWAY: flags=0, "
348 "stream_id=0, length=3} -- must be at least 8 bytes"));
349 EXPECT_THAT(ValidateFrame(0, 0, 4, 7, 0, 0, 0, 0, 0, 1, 1, 1, 1),
350 StatusIs(absl::StatusCode::kInternal,
351 "invalid goaway payload: {GOAWAY: flags=0, "
352 "stream_id=0, length=4} -- must be at least 8 bytes"));
353 EXPECT_THAT(ValidateFrame(0, 0, 5, 7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1),
354 StatusIs(absl::StatusCode::kInternal,
355 "invalid goaway payload: {GOAWAY: flags=0, "
356 "stream_id=0, length=5} -- must be at least 8 bytes"));
357 EXPECT_THAT(ValidateFrame(0, 0, 6, 7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1),
358 StatusIs(absl::StatusCode::kInternal,
359 "invalid goaway payload: {GOAWAY: flags=0, "
360 "stream_id=0, length=6} -- must be at least 8 bytes"));
361 EXPECT_THAT(ValidateFrame(0, 0, 7, 7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1),
362 StatusIs(absl::StatusCode::kInternal,
363 "invalid goaway payload: {GOAWAY: flags=0, "
364 "stream_id=0, length=7} -- must be at least 8 bytes"));
365 EXPECT_THAT(ValidateFrame(0, 0, 8, 7, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8),
366 StatusIs(absl::StatusCode::kInternal,
367 "invalid goaway stream id: {GOAWAY: flags=0, "
368 "stream_id=1, length=8}"));
369 EXPECT_THAT(ValidateFrame(0, 0, 8, 7, 1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8),
370 StatusIs(absl::StatusCode::kInternal,
371 "invalid goaway flags: {GOAWAY: flags=1, "
372 "stream_id=0, length=8}"));
373 EXPECT_THAT(
374 ValidateFrame(0, 0, 8, 7, 255, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8),
375 StatusIs(absl::StatusCode::kInternal,
376 "invalid goaway flags: {GOAWAY: flags=255, "
377 "stream_id=0, length=8}"));
378 EXPECT_THAT(ValidateFrame(0, 0, 0, 8, 0, 0, 0, 0, 0),
379 StatusIs(absl::StatusCode::kInternal,
380 "invalid window update payload: {WINDOW_UPDATE: "
381 "flags=0, stream_id=0, length=0} -- must be 4 bytes"));
382 EXPECT_THAT(ValidateFrame(0, 0, 1, 8, 0, 0, 0, 0, 0, 1),
383 StatusIs(absl::StatusCode::kInternal,
384 "invalid window update payload: {WINDOW_UPDATE: "
385 "flags=0, stream_id=0, length=1} -- must be 4 bytes"));
386 EXPECT_THAT(ValidateFrame(0, 0, 2, 8, 0, 0, 0, 0, 0, 1, 1),
387 StatusIs(absl::StatusCode::kInternal,
388 "invalid window update payload: {WINDOW_UPDATE: "
389 "flags=0, stream_id=0, length=2} -- must be 4 bytes"));
390 EXPECT_THAT(ValidateFrame(0, 0, 3, 8, 0, 0, 0, 0, 0, 1, 1, 1),
391 StatusIs(absl::StatusCode::kInternal,
392 "invalid window update payload: {WINDOW_UPDATE: "
393 "flags=0, stream_id=0, length=3} -- must be 4 bytes"));
394 EXPECT_THAT(ValidateFrame(0, 0, 5, 8, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1),
395 StatusIs(absl::StatusCode::kInternal,
396 "invalid window update payload: {WINDOW_UPDATE: "
397 "flags=0, stream_id=0, length=5} -- must be 4 bytes"));
398 EXPECT_THAT(ValidateFrame(0, 0, 4, 8, 1, 0, 0, 0, 0, 1, 1, 1, 1),
399 StatusIs(absl::StatusCode::kInternal,
400 "invalid window update flags: {WINDOW_UPDATE: flags=1, "
401 "stream_id=0, length=4}"));
402 }
403
404 } // namespace
405 } // namespace grpc_core
406
main(int argc,char ** argv)407 int main(int argc, char** argv) {
408 ::testing::InitGoogleTest(&argc, argv);
409 return RUN_ALL_TESTS();
410 }
411