blob: e5e3e9ad411a2572ae5556e55a62ec3e726a8ba5 [file] [log] [blame]
QUICHE team82dee2f2019-01-18 12:35:12 -05001// 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/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h"
6
QUICHE teamded03512019-03-07 14:45:11 -08007// Logging policy: If an error in the input is detected, SPDY_VLOG(n) is used so
8// that the option exists to debug the situation. Otherwise, this code mostly
9// uses DVLOG so that the logging does not slow down production code when things
10// are working OK.
QUICHE team82dee2f2019-01-18 12:35:12 -050011
12#include <stddef.h>
13
14#include <cstdint>
15#include <cstring>
16#include <utility>
17
QUICHE team82dee2f2019-01-18 12:35:12 -050018#include "net/third_party/quiche/src/http2/decoder/decode_buffer.h"
19#include "net/third_party/quiche/src/http2/decoder/decode_status.h"
20#include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder.h"
21#include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h"
22#include "net/third_party/quiche/src/http2/http2_constants.h"
23#include "net/third_party/quiche/src/http2/http2_structures.h"
24#include "net/third_party/quiche/src/http2/platform/api/http2_string.h"
25#include "net/third_party/quiche/src/spdy/core/hpack/hpack_decoder_adapter.h"
26#include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h"
27#include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h"
28#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
29#include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h"
30#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
31#include "net/third_party/quiche/src/spdy/platform/api/spdy_bug_tracker.h"
32#include "net/third_party/quiche/src/spdy/platform/api/spdy_endianness_util.h"
33#include "net/third_party/quiche/src/spdy/platform/api/spdy_estimate_memory_usage.h"
34#include "net/third_party/quiche/src/spdy/platform/api/spdy_flags.h"
QUICHE teamded03512019-03-07 14:45:11 -080035#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
QUICHE team82dee2f2019-01-18 12:35:12 -050036#include "net/third_party/quiche/src/spdy/platform/api/spdy_ptr_util.h"
37#include "net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h"
38
39using ::spdy::ExtensionVisitorInterface;
40using ::spdy::HpackDecoderAdapter;
41using ::spdy::HpackHeaderTable;
42using ::spdy::ParseErrorCode;
43using ::spdy::ParseFrameType;
44using ::spdy::SpdyAltSvcWireFormat;
45using ::spdy::SpdyErrorCode;
46using ::spdy::SpdyEstimateMemoryUsage;
47using ::spdy::SpdyFramerDebugVisitorInterface;
48using ::spdy::SpdyFramerVisitorInterface;
49using ::spdy::SpdyFrameType;
50using ::spdy::SpdyHeadersHandlerInterface;
51using ::spdy::SpdyKnownSettingsId;
52using ::spdy::SpdyMakeUnique;
53using ::spdy::SpdySettingsId;
54
55namespace http2 {
56namespace {
57
58const bool kHasPriorityFields = true;
59const bool kNotHasPriorityFields = false;
60
61bool IsPaddable(Http2FrameType type) {
62 return type == Http2FrameType::DATA || type == Http2FrameType::HEADERS ||
63 type == Http2FrameType::PUSH_PROMISE;
64}
65
66SpdyFrameType ToSpdyFrameType(Http2FrameType type) {
67 return ParseFrameType(static_cast<uint8_t>(type));
68}
69
70uint64_t ToSpdyPingId(const Http2PingFields& ping) {
71 uint64_t v;
72 std::memcpy(&v, ping.opaque_bytes, Http2PingFields::EncodedSize());
73 return spdy::SpdyNetToHost64(v);
74}
75
76// Overwrites the fields of the header with invalid values, for the purpose
77// of identifying reading of unset fields. Only takes effect for debug builds.
78// In Address Sanatizer builds, it also marks the fields as un-readable.
79void CorruptFrameHeader(Http2FrameHeader* header) {
80#ifndef NDEBUG
81 // Beyond a valid payload length, which is 2^24 - 1.
82 header->payload_length = 0x1010dead;
83 // An unsupported frame type.
84 header->type = Http2FrameType(0x80);
85 DCHECK(!IsSupportedHttp2FrameType(header->type));
86 // Frame flag bits that aren't used by any supported frame type.
87 header->flags = Http2FrameFlag(0xd2);
88 // A stream id with the reserved high-bit (R in the RFC) set.
89 // 2129510127 when the high-bit is cleared.
90 header->stream_id = 0xfeedbeef;
91#endif
92}
93
94} // namespace
95
96const char* Http2DecoderAdapter::StateToString(int state) {
97 switch (state) {
98 case SPDY_ERROR:
99 return "ERROR";
100 case SPDY_FRAME_COMPLETE:
101 return "FRAME_COMPLETE";
102 case SPDY_READY_FOR_FRAME:
103 return "READY_FOR_FRAME";
104 case SPDY_READING_COMMON_HEADER:
105 return "READING_COMMON_HEADER";
106 case SPDY_CONTROL_FRAME_PAYLOAD:
107 return "CONTROL_FRAME_PAYLOAD";
108 case SPDY_READ_DATA_FRAME_PADDING_LENGTH:
109 return "SPDY_READ_DATA_FRAME_PADDING_LENGTH";
110 case SPDY_CONSUME_PADDING:
111 return "SPDY_CONSUME_PADDING";
112 case SPDY_IGNORE_REMAINING_PAYLOAD:
113 return "IGNORE_REMAINING_PAYLOAD";
114 case SPDY_FORWARD_STREAM_FRAME:
115 return "FORWARD_STREAM_FRAME";
116 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
117 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
118 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
119 return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
120 case SPDY_GOAWAY_FRAME_PAYLOAD:
121 return "SPDY_GOAWAY_FRAME_PAYLOAD";
122 case SPDY_SETTINGS_FRAME_HEADER:
123 return "SPDY_SETTINGS_FRAME_HEADER";
124 case SPDY_SETTINGS_FRAME_PAYLOAD:
125 return "SPDY_SETTINGS_FRAME_PAYLOAD";
126 case SPDY_ALTSVC_FRAME_PAYLOAD:
127 return "SPDY_ALTSVC_FRAME_PAYLOAD";
128 }
129 return "UNKNOWN_STATE";
130}
131
132const char* Http2DecoderAdapter::SpdyFramerErrorToString(
133 SpdyFramerError spdy_framer_error) {
134 switch (spdy_framer_error) {
135 case SPDY_NO_ERROR:
136 return "NO_ERROR";
137 case SPDY_INVALID_STREAM_ID:
138 return "INVALID_STREAM_ID";
139 case SPDY_INVALID_CONTROL_FRAME:
140 return "INVALID_CONTROL_FRAME";
141 case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
142 return "CONTROL_PAYLOAD_TOO_LARGE";
143 case SPDY_ZLIB_INIT_FAILURE:
144 return "ZLIB_INIT_FAILURE";
145 case SPDY_UNSUPPORTED_VERSION:
146 return "UNSUPPORTED_VERSION";
147 case SPDY_DECOMPRESS_FAILURE:
148 return "DECOMPRESS_FAILURE";
149 case SPDY_COMPRESS_FAILURE:
150 return "COMPRESS_FAILURE";
151 case SPDY_GOAWAY_FRAME_CORRUPT:
152 return "GOAWAY_FRAME_CORRUPT";
153 case SPDY_RST_STREAM_FRAME_CORRUPT:
154 return "RST_STREAM_FRAME_CORRUPT";
155 case SPDY_INVALID_PADDING:
156 return "INVALID_PADDING";
157 case SPDY_INVALID_DATA_FRAME_FLAGS:
158 return "INVALID_DATA_FRAME_FLAGS";
159 case SPDY_INVALID_CONTROL_FRAME_FLAGS:
160 return "INVALID_CONTROL_FRAME_FLAGS";
161 case SPDY_UNEXPECTED_FRAME:
162 return "UNEXPECTED_FRAME";
163 case SPDY_INTERNAL_FRAMER_ERROR:
164 return "INTERNAL_FRAMER_ERROR";
165 case SPDY_INVALID_CONTROL_FRAME_SIZE:
166 return "INVALID_CONTROL_FRAME_SIZE";
167 case SPDY_OVERSIZED_PAYLOAD:
168 return "OVERSIZED_PAYLOAD";
169 case LAST_ERROR:
170 return "UNKNOWN_ERROR";
171 }
172 return "UNKNOWN_ERROR";
173}
174
175Http2DecoderAdapter::Http2DecoderAdapter() {
QUICHE teamded03512019-03-07 14:45:11 -0800176 SPDY_DVLOG(1) << "Http2DecoderAdapter ctor";
QUICHE team82dee2f2019-01-18 12:35:12 -0500177 ResetInternal();
178}
179
180Http2DecoderAdapter::~Http2DecoderAdapter() = default;
181
182void Http2DecoderAdapter::set_visitor(SpdyFramerVisitorInterface* visitor) {
183 visitor_ = visitor;
184}
185
186void Http2DecoderAdapter::set_debug_visitor(
187 SpdyFramerDebugVisitorInterface* debug_visitor) {
188 debug_visitor_ = debug_visitor;
189}
190
191void Http2DecoderAdapter::set_process_single_input_frame(bool v) {
192 process_single_input_frame_ = v;
193}
194
195void Http2DecoderAdapter::set_extension_visitor(
196 ExtensionVisitorInterface* visitor) {
197 extension_ = visitor;
198}
199
200// Passes the call on to the HPACK decoder.
201void Http2DecoderAdapter::SetDecoderHeaderTableDebugVisitor(
202 std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) {
203 GetHpackDecoder()->SetHeaderTableDebugVisitor(std::move(visitor));
204}
205
206size_t Http2DecoderAdapter::ProcessInput(const char* data, size_t len) {
207 size_t limit = recv_frame_size_limit_;
208 frame_decoder_->set_maximum_payload_size(limit);
209
210 size_t total_processed = 0;
211 while (len > 0 && spdy_state_ != SPDY_ERROR) {
212 // Process one at a time so that we update the adapter's internal
213 // state appropriately.
214 const size_t processed = ProcessInputFrame(data, len);
215
216 // We had some data, and weren't in an error state, so should have
217 // processed/consumed at least one byte of it, even if we then ended up
218 // in an error state.
219 DCHECK(processed > 0) << "processed=" << processed
220 << " spdy_state_=" << spdy_state_
221 << " spdy_framer_error_=" << spdy_framer_error_;
222
223 data += processed;
224 len -= processed;
225 total_processed += processed;
226 if (process_single_input_frame() || processed == 0) {
227 break;
228 }
229 }
230 return total_processed;
231}
232
233void Http2DecoderAdapter::Reset() {
234 ResetInternal();
235}
236
237Http2DecoderAdapter::SpdyState Http2DecoderAdapter::state() const {
238 return spdy_state_;
239}
240
241Http2DecoderAdapter::SpdyFramerError Http2DecoderAdapter::spdy_framer_error()
242 const {
243 return spdy_framer_error_;
244}
245
246bool Http2DecoderAdapter::probable_http_response() const {
247 return latched_probable_http_response_;
248}
249
250size_t Http2DecoderAdapter::EstimateMemoryUsage() const {
251 // Skip |frame_decoder_|, |frame_header_| and |hpack_first_frame_header_| as
252 // they don't allocate.
253 return SpdyEstimateMemoryUsage(alt_svc_origin_) +
254 SpdyEstimateMemoryUsage(alt_svc_value_);
255}
256
257// ===========================================================================
258// Implementations of the methods declared by Http2FrameDecoderListener.
259
260// Called once the common frame header has been decoded for any frame.
261// This function is largely based on Http2DecoderAdapter::ValidateFrameHeader
262// and some parts of Http2DecoderAdapter::ProcessCommonHeader.
263bool Http2DecoderAdapter::OnFrameHeader(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800264 SPDY_DVLOG(1) << "OnFrameHeader: " << header;
QUICHE team82dee2f2019-01-18 12:35:12 -0500265 decoded_frame_header_ = true;
266 if (!latched_probable_http_response_) {
267 latched_probable_http_response_ = header.IsProbableHttpResponse();
268 }
269 const uint8_t raw_frame_type = static_cast<uint8_t>(header.type);
270 visitor()->OnCommonHeader(header.stream_id, header.payload_length,
271 raw_frame_type, header.flags);
272 if (has_expected_frame_type_ && header.type != expected_frame_type_) {
273 // Report an unexpected frame error and close the connection if we
274 // expect a known frame type (probably CONTINUATION) and receive an
275 // unknown frame.
QUICHE teamded03512019-03-07 14:45:11 -0800276 SPDY_VLOG(1) << "The framer was expecting to receive a "
277 << expected_frame_type_
278 << " frame, but instead received an unknown frame of type "
279 << header.type;
QUICHE team82dee2f2019-01-18 12:35:12 -0500280 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME);
281 return false;
282 }
283 if (!IsSupportedHttp2FrameType(header.type)) {
284 if (extension_ != nullptr) {
285 // Unknown frames will be passed to the registered extension.
286 return true;
287 }
288 // In HTTP2 we ignore unknown frame types for extensibility, as long as
289 // the rest of the control frame header is valid.
290 // We rely on the visitor to check validity of stream_id.
291 bool valid_stream =
292 visitor()->OnUnknownFrame(header.stream_id, raw_frame_type);
293 if (!valid_stream) {
294 // Report an invalid frame error if the stream_id is not valid.
QUICHE teamded03512019-03-07 14:45:11 -0800295 SPDY_VLOG(1) << "Unknown control frame type " << header.type
296 << " received on invalid stream " << header.stream_id;
QUICHE team82dee2f2019-01-18 12:35:12 -0500297 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME);
298 return false;
299 } else {
QUICHE teamded03512019-03-07 14:45:11 -0800300 SPDY_DVLOG(1) << "Ignoring unknown frame type " << header.type;
QUICHE team82dee2f2019-01-18 12:35:12 -0500301 return true;
302 }
303 }
304
305 SpdyFrameType frame_type = ToSpdyFrameType(header.type);
306 if (!IsValidHTTP2FrameStreamId(header.stream_id, frame_type)) {
QUICHE teamded03512019-03-07 14:45:11 -0800307 SPDY_VLOG(1) << "The framer received an invalid streamID of "
308 << header.stream_id << " for a frame of type " << header.type;
QUICHE team82dee2f2019-01-18 12:35:12 -0500309 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID);
310 return false;
311 }
312
313 if (has_expected_frame_type_ && header.type != expected_frame_type_) {
QUICHE teamded03512019-03-07 14:45:11 -0800314 SPDY_VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not "
315 << header.type;
QUICHE team82dee2f2019-01-18 12:35:12 -0500316 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME);
317 return false;
318 }
319
320 if (!has_expected_frame_type_ &&
321 header.type == Http2FrameType::CONTINUATION) {
QUICHE teamded03512019-03-07 14:45:11 -0800322 SPDY_VLOG(1) << "Got CONTINUATION frame when not expected.";
QUICHE team82dee2f2019-01-18 12:35:12 -0500323 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME);
324 return false;
325 }
326
327 if (header.type == Http2FrameType::DATA) {
328 // For some reason SpdyFramer still rejects invalid DATA frame flags.
329 uint8_t valid_flags = Http2FrameFlag::PADDED | Http2FrameFlag::END_STREAM;
330 if (header.HasAnyFlags(~valid_flags)) {
331 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS);
332 return false;
333 }
334 }
335
336 return true;
337}
338
339void Http2DecoderAdapter::OnDataStart(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800340 SPDY_DVLOG(1) << "OnDataStart: " << header;
QUICHE team82dee2f2019-01-18 12:35:12 -0500341
342 if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
343 frame_header_ = header;
344 has_frame_header_ = true;
345 visitor()->OnDataFrameHeader(header.stream_id, header.payload_length,
346 header.IsEndStream());
347 }
348}
349
350void Http2DecoderAdapter::OnDataPayload(const char* data, size_t len) {
QUICHE teamded03512019-03-07 14:45:11 -0800351 SPDY_DVLOG(1) << "OnDataPayload: len=" << len;
QUICHE team82dee2f2019-01-18 12:35:12 -0500352 DCHECK(has_frame_header_);
353 DCHECK_EQ(frame_header_.type, Http2FrameType::DATA);
354 visitor()->OnStreamFrameData(frame_header().stream_id, data, len);
355}
356
357void Http2DecoderAdapter::OnDataEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800358 SPDY_DVLOG(1) << "OnDataEnd";
QUICHE team82dee2f2019-01-18 12:35:12 -0500359 DCHECK(has_frame_header_);
360 DCHECK_EQ(frame_header_.type, Http2FrameType::DATA);
361 if (frame_header().IsEndStream()) {
362 visitor()->OnStreamEnd(frame_header().stream_id);
363 }
364 opt_pad_length_.reset();
365}
366
367void Http2DecoderAdapter::OnHeadersStart(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800368 SPDY_DVLOG(1) << "OnHeadersStart: " << header;
QUICHE team82dee2f2019-01-18 12:35:12 -0500369 if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
370 frame_header_ = header;
371 has_frame_header_ = true;
372 if (header.HasPriority()) {
373 // Once we've got the priority fields, then we can report the arrival
374 // of this HEADERS frame.
375 on_headers_called_ = false;
376 return;
377 }
378 on_headers_called_ = true;
379 ReportReceiveCompressedFrame(header);
380 visitor()->OnHeaders(header.stream_id, kNotHasPriorityFields,
381 0, // priority
382 0, // parent_stream_id
383 false, // exclusive
384 header.IsEndStream(), header.IsEndHeaders());
385 CommonStartHpackBlock();
386 }
387}
388
389void Http2DecoderAdapter::OnHeadersPriority(
390 const Http2PriorityFields& priority) {
QUICHE teamded03512019-03-07 14:45:11 -0800391 SPDY_DVLOG(1) << "OnHeadersPriority: " << priority;
QUICHE team82dee2f2019-01-18 12:35:12 -0500392 DCHECK(has_frame_header_);
393 DCHECK_EQ(frame_type(), Http2FrameType::HEADERS) << frame_header_;
394 DCHECK(frame_header_.HasPriority());
395 DCHECK(!on_headers_called_);
396 on_headers_called_ = true;
397 ReportReceiveCompressedFrame(frame_header_);
398 visitor()->OnHeaders(frame_header_.stream_id, kHasPriorityFields,
399 priority.weight, priority.stream_dependency,
400 priority.is_exclusive, frame_header_.IsEndStream(),
401 frame_header_.IsEndHeaders());
402 CommonStartHpackBlock();
403}
404
405void Http2DecoderAdapter::OnHpackFragment(const char* data, size_t len) {
QUICHE teamded03512019-03-07 14:45:11 -0800406 SPDY_DVLOG(1) << "OnHpackFragment: len=" << len;
QUICHE team82dee2f2019-01-18 12:35:12 -0500407 on_hpack_fragment_called_ = true;
408 if (!GetHpackDecoder()->HandleControlFrameHeadersData(data, len)) {
409 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_DECOMPRESS_FAILURE);
410 return;
411 }
412}
413
414void Http2DecoderAdapter::OnHeadersEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800415 SPDY_DVLOG(1) << "OnHeadersEnd";
QUICHE team82dee2f2019-01-18 12:35:12 -0500416 CommonHpackFragmentEnd();
417 opt_pad_length_.reset();
418}
419
420void Http2DecoderAdapter::OnPriorityFrame(const Http2FrameHeader& header,
421 const Http2PriorityFields& priority) {
QUICHE teamded03512019-03-07 14:45:11 -0800422 SPDY_DVLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority;
QUICHE team82dee2f2019-01-18 12:35:12 -0500423 if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
424 visitor()->OnPriority(header.stream_id, priority.stream_dependency,
425 priority.weight, priority.is_exclusive);
426 }
427}
428
429void Http2DecoderAdapter::OnContinuationStart(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800430 SPDY_DVLOG(1) << "OnContinuationStart: " << header;
QUICHE team82dee2f2019-01-18 12:35:12 -0500431 if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
432 DCHECK(has_hpack_first_frame_header_);
433 if (header.stream_id != hpack_first_frame_header_.stream_id) {
434 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME);
435 return;
436 }
437 frame_header_ = header;
438 has_frame_header_ = true;
439 ReportReceiveCompressedFrame(header);
440 visitor()->OnContinuation(header.stream_id, header.IsEndHeaders());
441 }
442}
443
444void Http2DecoderAdapter::OnContinuationEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800445 SPDY_DVLOG(1) << "OnContinuationEnd";
QUICHE team82dee2f2019-01-18 12:35:12 -0500446 CommonHpackFragmentEnd();
447}
448
449void Http2DecoderAdapter::OnPadLength(size_t trailing_length) {
QUICHE teamded03512019-03-07 14:45:11 -0800450 SPDY_DVLOG(1) << "OnPadLength: " << trailing_length;
QUICHE team82dee2f2019-01-18 12:35:12 -0500451 opt_pad_length_ = trailing_length;
452 DCHECK_LT(trailing_length, 256u);
453 if (frame_header_.type == Http2FrameType::DATA) {
454 visitor()->OnStreamPadLength(stream_id(), trailing_length);
455 }
456}
457
458void Http2DecoderAdapter::OnPadding(const char* padding,
459 size_t skipped_length) {
QUICHE teamded03512019-03-07 14:45:11 -0800460 SPDY_DVLOG(1) << "OnPadding: " << skipped_length;
QUICHE team82dee2f2019-01-18 12:35:12 -0500461 if (frame_header_.type == Http2FrameType::DATA) {
462 visitor()->OnStreamPadding(stream_id(), skipped_length);
463 } else {
464 MaybeAnnounceEmptyFirstHpackFragment();
465 }
466}
467
468void Http2DecoderAdapter::OnRstStream(const Http2FrameHeader& header,
469 Http2ErrorCode http2_error_code) {
QUICHE teamded03512019-03-07 14:45:11 -0800470 SPDY_DVLOG(1) << "OnRstStream: " << header << "; code=" << http2_error_code;
QUICHE team82dee2f2019-01-18 12:35:12 -0500471 if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
472 SpdyErrorCode error_code =
473 ParseErrorCode(static_cast<uint32_t>(http2_error_code));
474 visitor()->OnRstStream(header.stream_id, error_code);
475 }
476}
477
478void Http2DecoderAdapter::OnSettingsStart(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800479 SPDY_DVLOG(1) << "OnSettingsStart: " << header;
QUICHE team82dee2f2019-01-18 12:35:12 -0500480 if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
481 frame_header_ = header;
482 has_frame_header_ = true;
483 visitor()->OnSettings();
484 }
485}
486
487void Http2DecoderAdapter::OnSetting(const Http2SettingFields& setting_fields) {
QUICHE teamded03512019-03-07 14:45:11 -0800488 SPDY_DVLOG(1) << "OnSetting: " << setting_fields;
QUICHE team82dee2f2019-01-18 12:35:12 -0500489 const auto parameter = static_cast<SpdySettingsId>(setting_fields.parameter);
490 visitor()->OnSetting(parameter, setting_fields.value);
491 if (extension_ != nullptr) {
492 extension_->OnSetting(parameter, setting_fields.value);
493 }
494}
495
496void Http2DecoderAdapter::OnSettingsEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800497 SPDY_DVLOG(1) << "OnSettingsEnd";
QUICHE team82dee2f2019-01-18 12:35:12 -0500498 visitor()->OnSettingsEnd();
499}
500
501void Http2DecoderAdapter::OnSettingsAck(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800502 SPDY_DVLOG(1) << "OnSettingsAck: " << header;
QUICHE team82dee2f2019-01-18 12:35:12 -0500503 if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
504 visitor()->OnSettingsAck();
505 }
506}
507
508void Http2DecoderAdapter::OnPushPromiseStart(
509 const Http2FrameHeader& header,
510 const Http2PushPromiseFields& promise,
511 size_t total_padding_length) {
QUICHE teamded03512019-03-07 14:45:11 -0800512 SPDY_DVLOG(1) << "OnPushPromiseStart: " << header << "; promise: " << promise
513 << "; total_padding_length: " << total_padding_length;
QUICHE team82dee2f2019-01-18 12:35:12 -0500514 if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
515 if (promise.promised_stream_id == 0) {
516 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME);
517 return;
518 }
519 frame_header_ = header;
520 has_frame_header_ = true;
521 ReportReceiveCompressedFrame(header);
522 visitor()->OnPushPromise(header.stream_id, promise.promised_stream_id,
523 header.IsEndHeaders());
524 CommonStartHpackBlock();
525 }
526}
527
528void Http2DecoderAdapter::OnPushPromiseEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800529 SPDY_DVLOG(1) << "OnPushPromiseEnd";
QUICHE team82dee2f2019-01-18 12:35:12 -0500530 CommonHpackFragmentEnd();
531 opt_pad_length_.reset();
532}
533
534void Http2DecoderAdapter::OnPing(const Http2FrameHeader& header,
535 const Http2PingFields& ping) {
QUICHE teamded03512019-03-07 14:45:11 -0800536 SPDY_DVLOG(1) << "OnPing: " << header << "; ping: " << ping;
QUICHE team82dee2f2019-01-18 12:35:12 -0500537 if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
538 visitor()->OnPing(ToSpdyPingId(ping), false);
539 }
540}
541
542void Http2DecoderAdapter::OnPingAck(const Http2FrameHeader& header,
543 const Http2PingFields& ping) {
QUICHE teamded03512019-03-07 14:45:11 -0800544 SPDY_DVLOG(1) << "OnPingAck: " << header << "; ping: " << ping;
QUICHE team82dee2f2019-01-18 12:35:12 -0500545 if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
546 visitor()->OnPing(ToSpdyPingId(ping), true);
547 }
548}
549
550void Http2DecoderAdapter::OnGoAwayStart(const Http2FrameHeader& header,
551 const Http2GoAwayFields& goaway) {
QUICHE teamded03512019-03-07 14:45:11 -0800552 SPDY_DVLOG(1) << "OnGoAwayStart: " << header << "; goaway: " << goaway;
QUICHE team82dee2f2019-01-18 12:35:12 -0500553 if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
554 frame_header_ = header;
555 has_frame_header_ = true;
556 SpdyErrorCode error_code =
557 ParseErrorCode(static_cast<uint32_t>(goaway.error_code));
558 visitor()->OnGoAway(goaway.last_stream_id, error_code);
559 }
560}
561
562void Http2DecoderAdapter::OnGoAwayOpaqueData(const char* data, size_t len) {
QUICHE teamded03512019-03-07 14:45:11 -0800563 SPDY_DVLOG(1) << "OnGoAwayOpaqueData: len=" << len;
QUICHE team82dee2f2019-01-18 12:35:12 -0500564 visitor()->OnGoAwayFrameData(data, len);
565}
566
567void Http2DecoderAdapter::OnGoAwayEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800568 SPDY_DVLOG(1) << "OnGoAwayEnd";
QUICHE team82dee2f2019-01-18 12:35:12 -0500569 visitor()->OnGoAwayFrameData(nullptr, 0);
570}
571
572void Http2DecoderAdapter::OnWindowUpdate(const Http2FrameHeader& header,
573 uint32_t increment) {
QUICHE teamded03512019-03-07 14:45:11 -0800574 SPDY_DVLOG(1) << "OnWindowUpdate: " << header << "; increment=" << increment;
QUICHE team82dee2f2019-01-18 12:35:12 -0500575 if (IsOkToStartFrame(header)) {
576 visitor()->OnWindowUpdate(header.stream_id, increment);
577 }
578}
579
580// Per RFC7838, an ALTSVC frame on stream 0 with origin_length == 0, or one on
581// a stream other than stream 0 with origin_length != 0 MUST be ignored. All
582// frames are decoded by Http2DecoderAdapter, and it is left to the consumer
583// (listener) to implement this behavior.
584void Http2DecoderAdapter::OnAltSvcStart(const Http2FrameHeader& header,
585 size_t origin_length,
586 size_t value_length) {
QUICHE teamded03512019-03-07 14:45:11 -0800587 SPDY_DVLOG(1) << "OnAltSvcStart: " << header
588 << "; origin_length: " << origin_length
589 << "; value_length: " << value_length;
QUICHE team82dee2f2019-01-18 12:35:12 -0500590 if (!IsOkToStartFrame(header)) {
591 return;
592 }
593 frame_header_ = header;
594 has_frame_header_ = true;
595 alt_svc_origin_.clear();
596 alt_svc_value_.clear();
597}
598
599void Http2DecoderAdapter::OnAltSvcOriginData(const char* data, size_t len) {
QUICHE teamded03512019-03-07 14:45:11 -0800600 SPDY_DVLOG(1) << "OnAltSvcOriginData: len=" << len;
QUICHE team82dee2f2019-01-18 12:35:12 -0500601 alt_svc_origin_.append(data, len);
602}
603
604// Called when decoding the Alt-Svc-Field-Value of an ALTSVC;
605// the field is uninterpreted.
606void Http2DecoderAdapter::OnAltSvcValueData(const char* data, size_t len) {
QUICHE teamded03512019-03-07 14:45:11 -0800607 SPDY_DVLOG(1) << "OnAltSvcValueData: len=" << len;
QUICHE team82dee2f2019-01-18 12:35:12 -0500608 alt_svc_value_.append(data, len);
609}
610
611void Http2DecoderAdapter::OnAltSvcEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800612 SPDY_DVLOG(1) << "OnAltSvcEnd: origin.size(): " << alt_svc_origin_.size()
613 << "; value.size(): " << alt_svc_value_.size();
QUICHE team82dee2f2019-01-18 12:35:12 -0500614 SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
615 if (!SpdyAltSvcWireFormat::ParseHeaderFieldValue(alt_svc_value_,
616 &altsvc_vector)) {
617 DLOG(ERROR) << "SpdyAltSvcWireFormat::ParseHeaderFieldValue failed.";
618 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME);
619 return;
620 }
621 visitor()->OnAltSvc(frame_header_.stream_id, alt_svc_origin_, altsvc_vector);
622 // We assume that ALTSVC frames are rare, so get rid of the storage.
623 alt_svc_origin_.clear();
624 alt_svc_origin_.shrink_to_fit();
625 alt_svc_value_.clear();
626 alt_svc_value_.shrink_to_fit();
627}
628
629// Except for BLOCKED frames, all other unknown frames are either dropped or
630// passed to a registered extension.
631void Http2DecoderAdapter::OnUnknownStart(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800632 SPDY_DVLOG(1) << "OnUnknownStart: " << header;
QUICHE team82dee2f2019-01-18 12:35:12 -0500633 if (IsOkToStartFrame(header)) {
634 if (extension_ != nullptr) {
635 const uint8_t type = static_cast<uint8_t>(header.type);
636 const uint8_t flags = static_cast<uint8_t>(header.flags);
637 handling_extension_payload_ = extension_->OnFrameHeader(
638 header.stream_id, header.payload_length, type, flags);
639 }
640 }
641}
642
643void Http2DecoderAdapter::OnUnknownPayload(const char* data, size_t len) {
644 if (handling_extension_payload_) {
645 extension_->OnFramePayload(data, len);
646 } else {
QUICHE teamded03512019-03-07 14:45:11 -0800647 SPDY_DVLOG(1) << "OnUnknownPayload: len=" << len;
QUICHE team82dee2f2019-01-18 12:35:12 -0500648 }
649}
650
651void Http2DecoderAdapter::OnUnknownEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800652 SPDY_DVLOG(1) << "OnUnknownEnd";
QUICHE team82dee2f2019-01-18 12:35:12 -0500653 handling_extension_payload_ = false;
654}
655
656void Http2DecoderAdapter::OnPaddingTooLong(const Http2FrameHeader& header,
657 size_t missing_length) {
QUICHE teamded03512019-03-07 14:45:11 -0800658 SPDY_DVLOG(1) << "OnPaddingTooLong: " << header
659 << "; missing_length: " << missing_length;
QUICHE team82dee2f2019-01-18 12:35:12 -0500660 if (header.type == Http2FrameType::DATA) {
661 if (header.payload_length == 0) {
662 DCHECK_EQ(1u, missing_length);
663 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS);
664 return;
665 }
666 visitor()->OnStreamPadding(header.stream_id, 1);
667 }
668 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_PADDING);
669}
670
671void Http2DecoderAdapter::OnFrameSizeError(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800672 SPDY_DVLOG(1) << "OnFrameSizeError: " << header;
QUICHE team82dee2f2019-01-18 12:35:12 -0500673 size_t recv_limit = recv_frame_size_limit_;
674 if (header.payload_length > recv_limit) {
675 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_OVERSIZED_PAYLOAD);
676 return;
677 }
678 if (header.type != Http2FrameType::DATA &&
679 header.payload_length > recv_limit) {
680 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_CONTROL_PAYLOAD_TOO_LARGE);
681 return;
682 }
683 switch (header.type) {
684 case Http2FrameType::GOAWAY:
685 case Http2FrameType::ALTSVC:
686 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME);
687 break;
688 default:
689 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME_SIZE);
690 }
691}
692
693// Decodes the input up to the next frame boundary (i.e. at most one frame),
694// stopping early if an error is detected.
695size_t Http2DecoderAdapter::ProcessInputFrame(const char* data, size_t len) {
696 DCHECK_NE(spdy_state_, SpdyState::SPDY_ERROR);
697 DecodeBuffer db(data, len);
698 DecodeStatus status = frame_decoder_->DecodeFrame(&db);
699 if (spdy_state_ != SpdyState::SPDY_ERROR) {
700 DetermineSpdyState(status);
701 } else {
QUICHE teamded03512019-03-07 14:45:11 -0800702 SPDY_VLOG(1) << "ProcessInputFrame spdy_framer_error_="
703 << SpdyFramerErrorToString(spdy_framer_error_);
QUICHE team82dee2f2019-01-18 12:35:12 -0500704 if (spdy_framer_error_ == SpdyFramerError::SPDY_INVALID_PADDING &&
705 has_frame_header_ && frame_type() != Http2FrameType::DATA) {
706 // spdy_framer_test checks that all of the available frame payload
707 // has been consumed, so do that.
708 size_t total = remaining_total_payload();
709 if (total <= frame_header().payload_length) {
710 size_t avail = db.MinLengthRemaining(total);
QUICHE teamded03512019-03-07 14:45:11 -0800711 SPDY_VLOG(1) << "Skipping past " << avail << " bytes, of " << total
712 << " total remaining in the frame's payload.";
QUICHE team82dee2f2019-01-18 12:35:12 -0500713 db.AdvanceCursor(avail);
714 } else {
715 SPDY_BUG << "Total remaining (" << total
716 << ") should not be greater than the payload length; "
717 << frame_header();
718 }
719 }
720 }
721 return db.Offset();
722}
723
724// After decoding, determine the next SpdyState. Only called if the current
725// state is NOT SpdyState::SPDY_ERROR (i.e. if none of the callback methods
726// detected an error condition), because otherwise we assume that the callback
727// method has set spdy_framer_error_ appropriately.
728void Http2DecoderAdapter::DetermineSpdyState(DecodeStatus status) {
729 DCHECK_EQ(spdy_framer_error_, SPDY_NO_ERROR);
730 DCHECK(!HasError()) << spdy_framer_error_;
731 switch (status) {
732 case DecodeStatus::kDecodeDone:
QUICHE teamded03512019-03-07 14:45:11 -0800733 SPDY_DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeDone";
QUICHE team82dee2f2019-01-18 12:35:12 -0500734 ResetBetweenFrames();
735 break;
736 case DecodeStatus::kDecodeInProgress:
QUICHE teamded03512019-03-07 14:45:11 -0800737 SPDY_DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeInProgress";
QUICHE team82dee2f2019-01-18 12:35:12 -0500738 if (decoded_frame_header_) {
739 if (IsDiscardingPayload()) {
740 set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD);
741 } else if (has_frame_header_ && frame_type() == Http2FrameType::DATA) {
742 if (IsReadingPaddingLength()) {
743 set_spdy_state(SpdyState::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
744 } else if (IsSkippingPadding()) {
745 set_spdy_state(SpdyState::SPDY_CONSUME_PADDING);
746 } else {
747 set_spdy_state(SpdyState::SPDY_FORWARD_STREAM_FRAME);
748 }
749 } else {
750 set_spdy_state(SpdyState::SPDY_CONTROL_FRAME_PAYLOAD);
751 }
752 } else {
753 set_spdy_state(SpdyState::SPDY_READING_COMMON_HEADER);
754 }
755 break;
756 case DecodeStatus::kDecodeError:
QUICHE teamded03512019-03-07 14:45:11 -0800757 SPDY_VLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeError";
QUICHE team82dee2f2019-01-18 12:35:12 -0500758 if (IsDiscardingPayload()) {
759 if (remaining_total_payload() == 0) {
760 // Push the Http2FrameDecoder out of state kDiscardPayload now
761 // since doing so requires no input.
762 DecodeBuffer tmp("", 0);
763 DecodeStatus status = frame_decoder_->DecodeFrame(&tmp);
764 if (status != DecodeStatus::kDecodeDone) {
765 SPDY_BUG << "Expected to be done decoding the frame, not "
766 << status;
767 SetSpdyErrorAndNotify(SPDY_INTERNAL_FRAMER_ERROR);
768 } else if (spdy_framer_error_ != SPDY_NO_ERROR) {
769 SPDY_BUG << "Expected to have no error, not "
770 << SpdyFramerErrorToString(spdy_framer_error_);
771 } else {
772 ResetBetweenFrames();
773 }
774 } else {
775 set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD);
776 }
777 } else {
778 SetSpdyErrorAndNotify(SPDY_INVALID_CONTROL_FRAME);
779 }
780 break;
781 }
782}
783
784void Http2DecoderAdapter::ResetBetweenFrames() {
785 CorruptFrameHeader(&frame_header_);
786 decoded_frame_header_ = false;
787 has_frame_header_ = false;
788 set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME);
789}
790
791// ResetInternal is called from the constructor, and during tests, but not
792// otherwise (i.e. not between every frame).
793void Http2DecoderAdapter::ResetInternal() {
794 set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME);
795 spdy_framer_error_ = SpdyFramerError::SPDY_NO_ERROR;
796
797 decoded_frame_header_ = false;
798 has_frame_header_ = false;
799 on_headers_called_ = false;
800 on_hpack_fragment_called_ = false;
801 latched_probable_http_response_ = false;
802 has_expected_frame_type_ = false;
803
804 CorruptFrameHeader(&frame_header_);
805 CorruptFrameHeader(&hpack_first_frame_header_);
806
807 frame_decoder_ = SpdyMakeUnique<Http2FrameDecoder>(this);
808 hpack_decoder_ = nullptr;
809}
810
811void Http2DecoderAdapter::set_spdy_state(SpdyState v) {
QUICHE teamded03512019-03-07 14:45:11 -0800812 SPDY_DVLOG(2) << "set_spdy_state(" << StateToString(v) << ")";
QUICHE team82dee2f2019-01-18 12:35:12 -0500813 spdy_state_ = v;
814}
815
816void Http2DecoderAdapter::SetSpdyErrorAndNotify(SpdyFramerError error) {
817 if (HasError()) {
818 DCHECK_EQ(spdy_state_, SpdyState::SPDY_ERROR);
819 } else {
QUICHE teamded03512019-03-07 14:45:11 -0800820 SPDY_VLOG(2) << "SetSpdyErrorAndNotify(" << SpdyFramerErrorToString(error)
821 << ")";
QUICHE team82dee2f2019-01-18 12:35:12 -0500822 DCHECK_NE(error, SpdyFramerError::SPDY_NO_ERROR);
823 spdy_framer_error_ = error;
824 set_spdy_state(SpdyState::SPDY_ERROR);
825 frame_decoder_->set_listener(&no_op_listener_);
826 visitor()->OnError(error);
827 }
828}
829
830bool Http2DecoderAdapter::HasError() const {
831 if (spdy_state_ == SpdyState::SPDY_ERROR) {
832 DCHECK_NE(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR);
833 return true;
834 } else {
835 DCHECK_EQ(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR);
836 return false;
837 }
838}
839
840const Http2FrameHeader& Http2DecoderAdapter::frame_header() const {
841 DCHECK(has_frame_header_);
842 return frame_header_;
843}
844
845uint32_t Http2DecoderAdapter::stream_id() const {
846 return frame_header().stream_id;
847}
848
849Http2FrameType Http2DecoderAdapter::frame_type() const {
850 return frame_header().type;
851}
852
853size_t Http2DecoderAdapter::remaining_total_payload() const {
854 DCHECK(has_frame_header_);
855 size_t remaining = frame_decoder_->remaining_payload();
856 if (IsPaddable(frame_type()) && frame_header_.IsPadded()) {
857 remaining += frame_decoder_->remaining_padding();
858 }
859 return remaining;
860}
861
862bool Http2DecoderAdapter::IsReadingPaddingLength() {
863 bool result = frame_header_.IsPadded() && !opt_pad_length_;
QUICHE teamded03512019-03-07 14:45:11 -0800864 SPDY_DVLOG(2) << "Http2DecoderAdapter::IsReadingPaddingLength: " << result;
QUICHE team82dee2f2019-01-18 12:35:12 -0500865 return result;
866}
867bool Http2DecoderAdapter::IsSkippingPadding() {
868 bool result = frame_header_.IsPadded() && opt_pad_length_ &&
869 frame_decoder_->remaining_payload() == 0 &&
870 frame_decoder_->remaining_padding() > 0;
QUICHE teamded03512019-03-07 14:45:11 -0800871 SPDY_DVLOG(2) << "Http2DecoderAdapter::IsSkippingPadding: " << result;
QUICHE team82dee2f2019-01-18 12:35:12 -0500872 return result;
873}
874bool Http2DecoderAdapter::IsDiscardingPayload() {
875 bool result = decoded_frame_header_ && frame_decoder_->IsDiscardingPayload();
QUICHE teamded03512019-03-07 14:45:11 -0800876 SPDY_DVLOG(2) << "Http2DecoderAdapter::IsDiscardingPayload: " << result;
QUICHE team82dee2f2019-01-18 12:35:12 -0500877 return result;
878}
879// Called from OnXyz or OnXyzStart methods to decide whether it is OK to
880// handle the callback.
881bool Http2DecoderAdapter::IsOkToStartFrame(const Http2FrameHeader& header) {
QUICHE teamded03512019-03-07 14:45:11 -0800882 SPDY_DVLOG(3) << "IsOkToStartFrame";
QUICHE team82dee2f2019-01-18 12:35:12 -0500883 if (HasError()) {
QUICHE teamded03512019-03-07 14:45:11 -0800884 SPDY_VLOG(2) << "HasError()";
QUICHE team82dee2f2019-01-18 12:35:12 -0500885 return false;
886 }
887 DCHECK(!has_frame_header_);
888 if (has_expected_frame_type_ && header.type != expected_frame_type_) {
QUICHE teamded03512019-03-07 14:45:11 -0800889 SPDY_VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not "
890 << header.type;
QUICHE team82dee2f2019-01-18 12:35:12 -0500891 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME);
892 return false;
893 }
894
895 return true;
896}
897
898bool Http2DecoderAdapter::HasRequiredStreamId(uint32_t stream_id) {
QUICHE teamded03512019-03-07 14:45:11 -0800899 SPDY_DVLOG(3) << "HasRequiredStreamId: " << stream_id;
QUICHE team82dee2f2019-01-18 12:35:12 -0500900 if (HasError()) {
QUICHE teamded03512019-03-07 14:45:11 -0800901 SPDY_VLOG(2) << "HasError()";
QUICHE team82dee2f2019-01-18 12:35:12 -0500902 return false;
903 }
904 if (stream_id != 0) {
905 return true;
906 }
QUICHE teamded03512019-03-07 14:45:11 -0800907 SPDY_VLOG(1) << "Stream Id is required, but zero provided";
QUICHE team82dee2f2019-01-18 12:35:12 -0500908 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID);
909 return false;
910}
911
912bool Http2DecoderAdapter::HasRequiredStreamId(const Http2FrameHeader& header) {
913 return HasRequiredStreamId(header.stream_id);
914}
915
916bool Http2DecoderAdapter::HasRequiredStreamIdZero(uint32_t stream_id) {
QUICHE teamded03512019-03-07 14:45:11 -0800917 SPDY_DVLOG(3) << "HasRequiredStreamIdZero: " << stream_id;
QUICHE team82dee2f2019-01-18 12:35:12 -0500918 if (HasError()) {
QUICHE teamded03512019-03-07 14:45:11 -0800919 SPDY_VLOG(2) << "HasError()";
QUICHE team82dee2f2019-01-18 12:35:12 -0500920 return false;
921 }
922 if (stream_id == 0) {
923 return true;
924 }
QUICHE teamded03512019-03-07 14:45:11 -0800925 SPDY_VLOG(1) << "Stream Id was not zero, as required: " << stream_id;
QUICHE team82dee2f2019-01-18 12:35:12 -0500926 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID);
927 return false;
928}
929
930bool Http2DecoderAdapter::HasRequiredStreamIdZero(
931 const Http2FrameHeader& header) {
932 return HasRequiredStreamIdZero(header.stream_id);
933}
934
935void Http2DecoderAdapter::ReportReceiveCompressedFrame(
936 const Http2FrameHeader& header) {
937 if (debug_visitor() != nullptr) {
938 size_t total = header.payload_length + Http2FrameHeader::EncodedSize();
939 debug_visitor()->OnReceiveCompressedFrame(
940 header.stream_id, ToSpdyFrameType(header.type), total);
941 }
942}
943
944HpackDecoderAdapter* Http2DecoderAdapter::GetHpackDecoder() {
945 if (hpack_decoder_ == nullptr) {
946 hpack_decoder_ = SpdyMakeUnique<HpackDecoderAdapter>();
947 }
948 return hpack_decoder_.get();
949}
950
951void Http2DecoderAdapter::CommonStartHpackBlock() {
QUICHE teamded03512019-03-07 14:45:11 -0800952 SPDY_DVLOG(1) << "CommonStartHpackBlock";
QUICHE team82dee2f2019-01-18 12:35:12 -0500953 DCHECK(!has_hpack_first_frame_header_);
954 if (!frame_header_.IsEndHeaders()) {
955 hpack_first_frame_header_ = frame_header_;
956 has_hpack_first_frame_header_ = true;
957 } else {
958 CorruptFrameHeader(&hpack_first_frame_header_);
959 }
960 on_hpack_fragment_called_ = false;
961 SpdyHeadersHandlerInterface* handler =
962 visitor()->OnHeaderFrameStart(stream_id());
963 if (handler == nullptr) {
964 SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr";
965 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INTERNAL_FRAMER_ERROR);
966 return;
967 }
968 GetHpackDecoder()->HandleControlFrameHeadersStart(handler);
969}
970
971// SpdyFramer calls HandleControlFrameHeadersData even if there are zero
972// fragment bytes in the first frame, so do the same.
973void Http2DecoderAdapter::MaybeAnnounceEmptyFirstHpackFragment() {
974 if (!on_hpack_fragment_called_) {
975 OnHpackFragment(nullptr, 0);
976 DCHECK(on_hpack_fragment_called_);
977 }
978}
979
980void Http2DecoderAdapter::CommonHpackFragmentEnd() {
QUICHE teamded03512019-03-07 14:45:11 -0800981 SPDY_DVLOG(1) << "CommonHpackFragmentEnd: stream_id=" << stream_id();
QUICHE team82dee2f2019-01-18 12:35:12 -0500982 if (HasError()) {
QUICHE teamded03512019-03-07 14:45:11 -0800983 SPDY_VLOG(1) << "HasError(), returning";
QUICHE team82dee2f2019-01-18 12:35:12 -0500984 return;
985 }
986 DCHECK(has_frame_header_);
987 MaybeAnnounceEmptyFirstHpackFragment();
988 if (frame_header_.IsEndHeaders()) {
989 DCHECK_EQ(has_hpack_first_frame_header_,
990 frame_type() == Http2FrameType::CONTINUATION)
991 << frame_header();
992 has_expected_frame_type_ = false;
993 if (GetHpackDecoder()->HandleControlFrameHeadersComplete(nullptr)) {
994 visitor()->OnHeaderFrameEnd(stream_id());
995 } else {
996 SetSpdyErrorAndNotify(SpdyFramerError::SPDY_DECOMPRESS_FAILURE);
997 return;
998 }
999 const Http2FrameHeader& first = frame_type() == Http2FrameType::CONTINUATION
1000 ? hpack_first_frame_header_
1001 : frame_header_;
1002 if (first.type == Http2FrameType::HEADERS && first.IsEndStream()) {
1003 visitor()->OnStreamEnd(first.stream_id);
1004 }
1005 has_hpack_first_frame_header_ = false;
1006 CorruptFrameHeader(&hpack_first_frame_header_);
1007 } else {
1008 DCHECK(has_hpack_first_frame_header_);
1009 has_expected_frame_type_ = true;
1010 expected_frame_type_ = Http2FrameType::CONTINUATION;
1011 }
1012}
1013
1014} // namespace http2
1015
1016namespace spdy {
1017
1018bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data,
1019 size_t len) {
1020 return true;
1021}
1022
1023} // namespace spdy