OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/http2/decoder/frame_parts.h" | |
6 | |
7 #include <type_traits> | |
8 | |
9 #include "base/logging.h" | |
10 #include "net/base/escape.h" | |
11 #include "net/http2/http2_structures_test_util.h" | |
12 #include "net/http2/tools/failure.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 using base::StringPiece; | |
16 using std::string; | |
17 using ::testing::AssertionFailure; | |
18 using ::testing::AssertionResult; | |
19 using ::testing::AssertionSuccess; | |
20 using ::testing::ContainerEq; | |
21 | |
22 namespace net { | |
23 namespace test { | |
24 namespace { | |
25 | |
26 static_assert(std::is_base_of<Http2FrameDecoderListener, FrameParts>::value && | |
27 !std::is_abstract<FrameParts>::value, | |
28 "FrameParts needs to implement all of the methods of " | |
29 "Http2FrameDecoderListener"); | |
30 | |
31 // Compare two optional variables of the same type. | |
32 // TODO(jamessynge): Maybe create a ::testing::Matcher for this. | |
33 template <class T> | |
34 AssertionResult VerifyOptionalEq(const T& opt_a, const T& opt_b) { | |
35 if (opt_a) { | |
36 if (opt_b) { | |
37 VERIFY_EQ(opt_a.value(), opt_b.value()); | |
38 } else { | |
39 return AssertionFailure() << "opt_b is not set; opt_a.value()=" | |
40 << opt_a.value(); | |
41 } | |
42 } else if (opt_b) { | |
43 return AssertionFailure() << "opt_a is not set; opt_b.value()=" | |
44 << opt_b.value(); | |
45 } | |
46 return AssertionSuccess(); | |
47 } | |
48 | |
49 } // namespace | |
50 | |
51 FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header(header) { | |
52 VLOG(1) << "FrameParts, header: " << frame_header; | |
53 } | |
54 | |
55 FrameParts::FrameParts(const Http2FrameHeader& header, StringPiece payload) | |
56 : FrameParts(header) { | |
57 VLOG(1) << "FrameParts with payload.size() = " << payload.size(); | |
58 payload.AppendToString(&this->payload); | |
59 opt_payload_length = payload.size(); | |
60 } | |
61 FrameParts::FrameParts(const Http2FrameHeader& header, | |
62 StringPiece payload, | |
63 size_t total_pad_length) | |
64 : FrameParts(header, payload) { | |
65 VLOG(1) << "FrameParts with total_pad_length=" << total_pad_length; | |
66 SetTotalPadLength(total_pad_length); | |
67 } | |
68 | |
69 FrameParts::FrameParts(const FrameParts& other) = default; | |
70 | |
71 FrameParts::~FrameParts() {} | |
72 | |
73 AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const { | |
74 #define COMMON_MESSAGE "\n this: " << *this << "\n that: " << that | |
75 | |
76 VERIFY_EQ(frame_header, that.frame_header) << COMMON_MESSAGE; | |
77 VERIFY_EQ(payload, that.payload) << COMMON_MESSAGE; | |
78 VERIFY_EQ(padding, that.padding) << COMMON_MESSAGE; | |
79 VERIFY_EQ(altsvc_origin, that.altsvc_origin) << COMMON_MESSAGE; | |
80 VERIFY_EQ(altsvc_value, that.altsvc_value) << COMMON_MESSAGE; | |
81 VERIFY_EQ(settings, that.settings) << COMMON_MESSAGE; | |
82 | |
83 #define VERIFY_OPTIONAL_FIELD(field_name) \ | |
84 VERIFY_SUCCESS(VerifyOptionalEq(field_name, that.field_name)) | |
85 | |
86 VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length) << COMMON_MESSAGE; | |
87 VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length) << COMMON_MESSAGE; | |
88 VERIFY_OPTIONAL_FIELD(opt_goaway) << COMMON_MESSAGE; | |
89 VERIFY_OPTIONAL_FIELD(opt_missing_length) << COMMON_MESSAGE; | |
90 VERIFY_OPTIONAL_FIELD(opt_pad_length) << COMMON_MESSAGE; | |
91 VERIFY_OPTIONAL_FIELD(opt_ping) << COMMON_MESSAGE; | |
92 VERIFY_OPTIONAL_FIELD(opt_priority) << COMMON_MESSAGE; | |
93 VERIFY_OPTIONAL_FIELD(opt_push_promise) << COMMON_MESSAGE; | |
94 VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code) << COMMON_MESSAGE; | |
95 VERIFY_OPTIONAL_FIELD(opt_window_update_increment) << COMMON_MESSAGE; | |
96 | |
97 #undef VERIFY_OPTIONAL_FIELD | |
98 | |
99 return AssertionSuccess(); | |
100 } | |
101 | |
102 void FrameParts::SetTotalPadLength(size_t total_pad_length) { | |
103 opt_pad_length.reset(); | |
104 padding.clear(); | |
105 if (total_pad_length > 0) { | |
106 ASSERT_LE(total_pad_length, 256u); | |
107 ASSERT_TRUE(frame_header.IsPadded()); | |
108 opt_pad_length = total_pad_length - 1; | |
109 char zero = 0; | |
110 padding.append(opt_pad_length.value(), zero); | |
111 } | |
112 | |
113 if (opt_pad_length) { | |
114 VLOG(1) << "SetTotalPadLength: pad_length=" << opt_pad_length.value(); | |
115 } else { | |
116 VLOG(1) << "SetTotalPadLength: has no pad length"; | |
117 } | |
118 } | |
119 | |
120 void FrameParts::SetAltSvcExpected(StringPiece origin, StringPiece value) { | |
121 origin.AppendToString(&altsvc_origin); | |
122 value.AppendToString(&altsvc_value); | |
123 opt_altsvc_origin_length = origin.size(); | |
124 opt_altsvc_value_length = value.size(); | |
125 } | |
126 | |
127 bool FrameParts::OnFrameHeader(const Http2FrameHeader& header) { | |
128 ADD_FAILURE() << "OnFrameHeader: " << *this; | |
129 return true; | |
130 } | |
131 | |
132 void FrameParts::OnDataStart(const Http2FrameHeader& header) { | |
133 VLOG(1) << "OnDataStart: " << header; | |
134 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::DATA)) << *this; | |
135 opt_payload_length = header.payload_length; | |
136 } | |
137 | |
138 void FrameParts::OnDataPayload(const char* data, size_t len) { | |
139 VLOG(1) << "OnDataPayload: len=" << len << "; frame_header: " << frame_header; | |
140 ASSERT_TRUE(InFrameOfType(Http2FrameType::DATA)) << *this; | |
141 ASSERT_TRUE( | |
142 AppendString(StringPiece(data, len), &payload, &opt_payload_length)); | |
143 } | |
144 | |
145 void FrameParts::OnDataEnd() { | |
146 VLOG(1) << "OnDataEnd; frame_header: " << frame_header; | |
147 ASSERT_TRUE(EndFrameOfType(Http2FrameType::DATA)) << *this; | |
148 } | |
149 | |
150 void FrameParts::OnHeadersStart(const Http2FrameHeader& header) { | |
151 VLOG(1) << "OnHeadersStart: " << header; | |
152 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::HEADERS)) << *this; | |
153 opt_payload_length = header.payload_length; | |
154 } | |
155 | |
156 void FrameParts::OnHeadersPriority(const Http2PriorityFields& priority) { | |
157 VLOG(1) << "OnHeadersPriority: priority: " << priority | |
158 << "; frame_header: " << frame_header; | |
159 ASSERT_TRUE(InFrameOfType(Http2FrameType::HEADERS)) << *this; | |
160 ASSERT_FALSE(opt_priority); | |
161 opt_priority = priority; | |
162 ASSERT_TRUE(opt_payload_length); | |
163 opt_payload_length = | |
164 opt_payload_length.value() - Http2PriorityFields::EncodedSize(); | |
165 } | |
166 | |
167 void FrameParts::OnHpackFragment(const char* data, size_t len) { | |
168 VLOG(1) << "OnHpackFragment: len=" << len | |
169 << "; frame_header: " << frame_header; | |
170 ASSERT_TRUE(got_start_callback); | |
171 ASSERT_FALSE(got_end_callback); | |
172 ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header)) << *this; | |
173 ASSERT_TRUE( | |
174 AppendString(StringPiece(data, len), &payload, &opt_payload_length)); | |
175 } | |
176 | |
177 void FrameParts::OnHeadersEnd() { | |
178 VLOG(1) << "OnHeadersEnd; frame_header: " << frame_header; | |
179 ASSERT_TRUE(EndFrameOfType(Http2FrameType::HEADERS)) << *this; | |
180 } | |
181 | |
182 void FrameParts::OnPriorityFrame(const Http2FrameHeader& header, | |
183 const Http2PriorityFields& priority) { | |
184 VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority; | |
185 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY)) << *this; | |
186 ASSERT_FALSE(opt_priority); | |
187 opt_priority = priority; | |
188 ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY)) << *this; | |
189 } | |
190 | |
191 void FrameParts::OnContinuationStart(const Http2FrameHeader& header) { | |
192 VLOG(1) << "OnContinuationStart: " << header; | |
193 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::CONTINUATION)) << *this; | |
194 opt_payload_length = header.payload_length; | |
195 } | |
196 | |
197 void FrameParts::OnContinuationEnd() { | |
198 VLOG(1) << "OnContinuationEnd; frame_header: " << frame_header; | |
199 ASSERT_TRUE(EndFrameOfType(Http2FrameType::CONTINUATION)) << *this; | |
200 } | |
201 | |
202 void FrameParts::OnPadLength(size_t trailing_length) { | |
203 VLOG(1) << "OnPadLength: trailing_length=" << trailing_length; | |
204 ASSERT_TRUE(InPaddedFrame()) << *this; | |
205 ASSERT_FALSE(opt_pad_length); | |
206 ASSERT_TRUE(opt_payload_length); | |
207 size_t total_padding_length = trailing_length + 1; | |
208 ASSERT_GE(opt_payload_length.value(), static_cast<int>(total_padding_length)); | |
209 opt_payload_length = opt_payload_length.value() - total_padding_length; | |
210 opt_pad_length = trailing_length; | |
211 } | |
212 | |
213 void FrameParts::OnPadding(const char* pad, size_t skipped_length) { | |
214 VLOG(1) << "OnPadding: skipped_length=" << skipped_length; | |
215 ASSERT_TRUE(InPaddedFrame()) << *this; | |
216 ASSERT_TRUE(opt_pad_length); | |
217 ASSERT_TRUE(AppendString(StringPiece(pad, skipped_length), &padding, | |
218 &opt_pad_length)); | |
219 } | |
220 | |
221 void FrameParts::OnRstStream(const Http2FrameHeader& header, | |
222 Http2ErrorCode error_code) { | |
223 VLOG(1) << "OnRstStream: " << header << "; code=" << error_code; | |
224 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::RST_STREAM)) << *this; | |
225 ASSERT_FALSE(opt_rst_stream_error_code); | |
226 opt_rst_stream_error_code = error_code; | |
227 ASSERT_TRUE(EndFrameOfType(Http2FrameType::RST_STREAM)) << *this; | |
228 } | |
229 | |
230 void FrameParts::OnSettingsStart(const Http2FrameHeader& header) { | |
231 VLOG(1) << "OnSettingsStart: " << header; | |
232 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this; | |
233 ASSERT_EQ(0u, settings.size()); | |
234 ASSERT_FALSE(header.IsAck()) << header; | |
235 } | |
236 | |
237 void FrameParts::OnSetting(const Http2SettingFields& setting_fields) { | |
238 VLOG(1) << "OnSetting: " << setting_fields; | |
239 ASSERT_TRUE(InFrameOfType(Http2FrameType::SETTINGS)) << *this; | |
240 settings.push_back(setting_fields); | |
241 } | |
242 | |
243 void FrameParts::OnSettingsEnd() { | |
244 VLOG(1) << "OnSettingsEnd; frame_header: " << frame_header; | |
245 ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this; | |
246 } | |
247 | |
248 void FrameParts::OnSettingsAck(const Http2FrameHeader& header) { | |
249 VLOG(1) << "OnSettingsAck: " << header; | |
250 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this; | |
251 ASSERT_EQ(0u, settings.size()); | |
252 ASSERT_TRUE(header.IsAck()); | |
253 ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this; | |
254 } | |
255 | |
256 void FrameParts::OnPushPromiseStart(const Http2FrameHeader& header, | |
257 const Http2PushPromiseFields& promise, | |
258 size_t total_padding_length) { | |
259 VLOG(1) << "OnPushPromiseStart header: " << header << "; promise: " << promise | |
260 << "; total_padding_length: " << total_padding_length; | |
261 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PUSH_PROMISE)) << *this; | |
262 ASSERT_GE(header.payload_length, Http2PushPromiseFields::EncodedSize()); | |
263 opt_payload_length = | |
264 header.payload_length - Http2PushPromiseFields::EncodedSize(); | |
265 ASSERT_FALSE(opt_push_promise); | |
266 opt_push_promise = promise; | |
267 if (total_padding_length > 0) { | |
268 ASSERT_GE(opt_payload_length.value(), | |
269 static_cast<int>(total_padding_length)); | |
270 OnPadLength(total_padding_length - 1); | |
271 } else { | |
272 ASSERT_FALSE(header.IsPadded()); | |
273 } | |
274 } | |
275 | |
276 void FrameParts::OnPushPromiseEnd() { | |
277 VLOG(1) << "OnPushPromiseEnd; frame_header: " << frame_header; | |
278 ASSERT_TRUE(EndFrameOfType(Http2FrameType::PUSH_PROMISE)) << *this; | |
279 } | |
280 | |
281 void FrameParts::OnPing(const Http2FrameHeader& header, | |
282 const Http2PingFields& ping) { | |
283 VLOG(1) << "OnPing header: " << header << " ping: " << ping; | |
284 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this; | |
285 ASSERT_FALSE(header.IsAck()); | |
286 ASSERT_FALSE(opt_ping); | |
287 opt_ping = ping; | |
288 ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this; | |
289 } | |
290 | |
291 void FrameParts::OnPingAck(const Http2FrameHeader& header, | |
292 const Http2PingFields& ping) { | |
293 VLOG(1) << "OnPingAck header: " << header << " ping: " << ping; | |
294 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this; | |
295 ASSERT_TRUE(header.IsAck()); | |
296 ASSERT_FALSE(opt_ping); | |
297 opt_ping = ping; | |
298 ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this; | |
299 } | |
300 | |
301 void FrameParts::OnGoAwayStart(const Http2FrameHeader& header, | |
302 const Http2GoAwayFields& goaway) { | |
303 VLOG(1) << "OnGoAwayStart: " << goaway; | |
304 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::GOAWAY)) << *this; | |
305 ASSERT_FALSE(opt_goaway); | |
306 opt_goaway = goaway; | |
307 opt_payload_length = header.payload_length - Http2GoAwayFields::EncodedSize(); | |
308 } | |
309 | |
310 void FrameParts::OnGoAwayOpaqueData(const char* data, size_t len) { | |
311 VLOG(1) << "OnGoAwayOpaqueData: len=" << len; | |
312 ASSERT_TRUE(InFrameOfType(Http2FrameType::GOAWAY)) << *this; | |
313 ASSERT_TRUE( | |
314 AppendString(StringPiece(data, len), &payload, &opt_payload_length)); | |
315 } | |
316 | |
317 void FrameParts::OnGoAwayEnd() { | |
318 VLOG(1) << "OnGoAwayEnd; frame_header: " << frame_header; | |
319 ASSERT_TRUE(EndFrameOfType(Http2FrameType::GOAWAY)) << *this; | |
320 } | |
321 | |
322 void FrameParts::OnWindowUpdate(const Http2FrameHeader& header, | |
323 uint32_t increment) { | |
324 VLOG(1) << "OnWindowUpdate header: " << header | |
325 << " increment=" << increment; | |
326 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::WINDOW_UPDATE)) << *this; | |
327 ASSERT_FALSE(opt_window_update_increment); | |
328 opt_window_update_increment = increment; | |
329 ASSERT_TRUE(EndFrameOfType(Http2FrameType::WINDOW_UPDATE)) << *this; | |
330 } | |
331 | |
332 void FrameParts::OnAltSvcStart(const Http2FrameHeader& header, | |
333 size_t origin_length, | |
334 size_t value_length) { | |
335 VLOG(1) << "OnAltSvcStart: " << header | |
336 << " origin_length: " << origin_length | |
337 << " value_length: " << value_length; | |
338 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::ALTSVC)) << *this; | |
339 ASSERT_FALSE(opt_altsvc_origin_length); | |
340 opt_altsvc_origin_length = origin_length; | |
341 ASSERT_FALSE(opt_altsvc_value_length); | |
342 opt_altsvc_value_length = value_length; | |
343 } | |
344 | |
345 void FrameParts::OnAltSvcOriginData(const char* data, size_t len) { | |
346 VLOG(1) << "OnAltSvcOriginData: len=" << len; | |
347 ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this; | |
348 ASSERT_TRUE(AppendString(StringPiece(data, len), &altsvc_origin, | |
349 &opt_altsvc_origin_length)); | |
350 } | |
351 | |
352 void FrameParts::OnAltSvcValueData(const char* data, size_t len) { | |
353 VLOG(1) << "OnAltSvcValueData: len=" << len; | |
354 ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this; | |
355 ASSERT_TRUE(AppendString(StringPiece(data, len), &altsvc_value, | |
356 &opt_altsvc_value_length)); | |
357 } | |
358 | |
359 void FrameParts::OnAltSvcEnd() { | |
360 VLOG(1) << "OnAltSvcEnd; frame_header: " << frame_header; | |
361 ASSERT_TRUE(EndFrameOfType(Http2FrameType::ALTSVC)) << *this; | |
362 } | |
363 | |
364 void FrameParts::OnUnknownStart(const Http2FrameHeader& header) { | |
365 VLOG(1) << "OnUnknownStart: " << header; | |
366 ASSERT_FALSE(IsSupportedHttp2FrameType(header.type)) << header; | |
367 ASSERT_FALSE(got_start_callback); | |
368 ASSERT_EQ(frame_header, header); | |
369 got_start_callback = true; | |
370 opt_payload_length = header.payload_length; | |
371 } | |
372 | |
373 void FrameParts::OnUnknownPayload(const char* data, size_t len) { | |
374 VLOG(1) << "OnUnknownPayload: len=" << len; | |
375 ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header.type)) << *this; | |
376 ASSERT_TRUE(got_start_callback); | |
377 ASSERT_FALSE(got_end_callback); | |
378 ASSERT_TRUE( | |
379 AppendString(StringPiece(data, len), &payload, &opt_payload_length)); | |
380 } | |
381 | |
382 void FrameParts::OnUnknownEnd() { | |
383 VLOG(1) << "OnUnknownEnd; frame_header: " << frame_header; | |
384 ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header.type)) << *this; | |
385 ASSERT_TRUE(got_start_callback); | |
386 ASSERT_FALSE(got_end_callback); | |
387 got_end_callback = true; | |
388 } | |
389 | |
390 void FrameParts::OnPaddingTooLong(const Http2FrameHeader& header, | |
391 size_t missing_length) { | |
392 VLOG(1) << "OnPaddingTooLong: " << header | |
393 << "; missing_length: " << missing_length; | |
394 ASSERT_EQ(frame_header, header); | |
395 ASSERT_FALSE(got_end_callback); | |
396 ASSERT_TRUE(FrameIsPadded(header)); | |
397 ASSERT_FALSE(opt_pad_length); | |
398 ASSERT_FALSE(opt_missing_length); | |
399 opt_missing_length = missing_length; | |
400 got_start_callback = true; | |
401 got_end_callback = true; | |
402 } | |
403 | |
404 void FrameParts::OnFrameSizeError(const Http2FrameHeader& header) { | |
405 VLOG(1) << "OnFrameSizeError: " << header; | |
406 ASSERT_EQ(frame_header, header); | |
407 ASSERT_FALSE(got_end_callback); | |
408 ASSERT_FALSE(has_frame_size_error); | |
409 has_frame_size_error = true; | |
410 got_end_callback = true; | |
411 } | |
412 | |
413 void FrameParts::OutputTo(std::ostream& out) const { | |
414 out << "FrameParts{\n frame_header: " << frame_header << "\n"; | |
415 if (!payload.empty()) { | |
416 out << " payload=\"" << EscapeQueryParamValue(payload, false) << "\"\n"; | |
417 } | |
418 if (!padding.empty()) { | |
419 out << " padding=\"" << EscapeQueryParamValue(padding, false) << "\"\n"; | |
420 } | |
421 if (!altsvc_origin.empty()) { | |
422 out << " altsvc_origin=\"" << EscapeQueryParamValue(altsvc_origin, false) | |
423 << "\"\n"; | |
424 } | |
425 if (!altsvc_value.empty()) { | |
426 out << " altsvc_value=\"" << EscapeQueryParamValue(altsvc_value, false) | |
427 << "\"\n"; | |
428 } | |
429 if (opt_priority) { | |
430 out << " priority=" << opt_priority.value() << "\n"; | |
431 } | |
432 if (opt_rst_stream_error_code) { | |
433 out << " rst_stream=" << opt_rst_stream_error_code.value() << "\n"; | |
434 } | |
435 if (opt_push_promise) { | |
436 out << " push_promise=" << opt_push_promise.value() << "\n"; | |
437 } | |
438 if (opt_ping) { | |
439 out << " ping=" << opt_ping.value() << "\n"; | |
440 } | |
441 if (opt_goaway) { | |
442 out << " goaway=" << opt_goaway.value() << "\n"; | |
443 } | |
444 if (opt_window_update_increment) { | |
445 out << " window_update=" << opt_window_update_increment.value() << "\n"; | |
446 } | |
447 if (opt_payload_length) { | |
448 out << " payload_length=" << opt_payload_length.value() << "\n"; | |
449 } | |
450 if (opt_pad_length) { | |
451 out << " pad_length=" << opt_pad_length.value() << "\n"; | |
452 } | |
453 if (opt_missing_length) { | |
454 out << " missing_length=" << opt_missing_length.value() << "\n"; | |
455 } | |
456 if (opt_altsvc_origin_length) { | |
457 out << " origin_length=" << opt_altsvc_origin_length.value() << "\n"; | |
458 } | |
459 if (opt_altsvc_value_length) { | |
460 out << " value_length=" << opt_altsvc_value_length.value() << "\n"; | |
461 } | |
462 if (has_frame_size_error) { | |
463 out << " has_frame_size_error\n"; | |
464 } | |
465 if (got_start_callback) { | |
466 out << " got_start_callback\n"; | |
467 } | |
468 if (got_end_callback) { | |
469 out << " got_end_callback\n"; | |
470 } | |
471 for (size_t ndx = 0; ndx < settings.size(); ++ndx) { | |
472 out << " setting[" << ndx << "]=" << settings[ndx]; | |
473 } | |
474 out << "}"; | |
475 } | |
476 | |
477 AssertionResult FrameParts::StartFrameOfType( | |
478 const Http2FrameHeader& header, | |
479 Http2FrameType expected_frame_type) { | |
480 VERIFY_EQ(header.type, expected_frame_type); | |
481 VERIFY_FALSE(got_start_callback); | |
482 VERIFY_FALSE(got_end_callback); | |
483 VERIFY_EQ(frame_header, header); | |
484 got_start_callback = true; | |
485 return AssertionSuccess(); | |
486 } | |
487 | |
488 AssertionResult FrameParts::InFrameOfType(Http2FrameType expected_frame_type) { | |
489 VERIFY_TRUE(got_start_callback); | |
490 VERIFY_FALSE(got_end_callback); | |
491 VERIFY_EQ(frame_header.type, expected_frame_type); | |
492 return AssertionSuccess(); | |
493 } | |
494 | |
495 AssertionResult FrameParts::EndFrameOfType(Http2FrameType expected_frame_type) { | |
496 VERIFY_SUCCESS(InFrameOfType(expected_frame_type)); | |
497 got_end_callback = true; | |
498 return AssertionSuccess(); | |
499 } | |
500 | |
501 AssertionResult FrameParts::InPaddedFrame() { | |
502 VERIFY_TRUE(got_start_callback); | |
503 VERIFY_FALSE(got_end_callback); | |
504 VERIFY_TRUE(FrameIsPadded(frame_header)); | |
505 return AssertionSuccess(); | |
506 } | |
507 | |
508 AssertionResult FrameParts::AppendString(StringPiece source, | |
509 string* target, | |
510 base::Optional<int>* opt_length) { | |
511 source.AppendToString(target); | |
512 if (opt_length != nullptr) { | |
513 VERIFY_TRUE(*opt_length) << "Length is not set yet\n" << *this; | |
514 VERIFY_LE(target->size(), static_cast<size_t>(opt_length->value())) | |
515 << "String too large; source.size() = " << source.size() << "\n" | |
516 << *this; | |
517 } | |
518 return ::testing::AssertionSuccess(); | |
519 } | |
520 | |
521 std::ostream& operator<<(std::ostream& out, const FrameParts& v) { | |
522 v.OutputTo(out); | |
523 return out; | |
524 } | |
525 | |
526 } // namespace test | |
527 } // namespace net | |
OLD | NEW |