xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/spdy/core/http2_frame_decoder_adapter.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 "quiche/spdy/core/http2_frame_decoder_adapter.h"
6 
7 // Logging policy: If an error in the input is detected, QUICHE_VLOG(n) is used
8 // so that the option exists to debug the situation. Otherwise, this code mostly
9 // uses QUICHE_DVLOG so that the logging does not slow down production code when
10 // things are working OK.
11 
12 #include <stddef.h>
13 
14 #include <cstdint>
15 #include <cstring>
16 #include <memory>
17 #include <string>
18 
19 #include "absl/strings/string_view.h"
20 #include "quiche/http2/decoder/decode_buffer.h"
21 #include "quiche/http2/decoder/decode_status.h"
22 #include "quiche/http2/decoder/http2_frame_decoder.h"
23 #include "quiche/http2/hpack/decoder/hpack_decoding_error.h"
24 #include "quiche/http2/http2_constants.h"
25 #include "quiche/http2/http2_structures.h"
26 #include "quiche/common/platform/api/quiche_bug_tracker.h"
27 #include "quiche/common/platform/api/quiche_logging.h"
28 #include "quiche/common/quiche_endian.h"
29 #include "quiche/spdy/core/hpack/hpack_decoder_adapter.h"
30 #include "quiche/spdy/core/hpack/hpack_header_table.h"
31 #include "quiche/spdy/core/spdy_alt_svc_wire_format.h"
32 #include "quiche/spdy/core/spdy_headers_handler_interface.h"
33 #include "quiche/spdy/core/spdy_protocol.h"
34 
35 using ::spdy::ExtensionVisitorInterface;
36 using ::spdy::HpackDecoderAdapter;
37 using ::spdy::HpackHeaderTable;
38 using ::spdy::ParseErrorCode;
39 using ::spdy::ParseFrameType;
40 using ::spdy::SpdyAltSvcWireFormat;
41 using ::spdy::SpdyErrorCode;
42 using ::spdy::SpdyFramerDebugVisitorInterface;
43 using ::spdy::SpdyFramerVisitorInterface;
44 using ::spdy::SpdyFrameType;
45 using ::spdy::SpdyHeadersHandlerInterface;
46 using ::spdy::SpdyKnownSettingsId;
47 using ::spdy::SpdySettingsId;
48 
49 namespace http2 {
50 namespace {
51 
52 const bool kHasPriorityFields = true;
53 const bool kNotHasPriorityFields = false;
54 
IsPaddable(Http2FrameType type)55 bool IsPaddable(Http2FrameType type) {
56   return type == Http2FrameType::DATA || type == Http2FrameType::HEADERS ||
57          type == Http2FrameType::PUSH_PROMISE;
58 }
59 
ToSpdyFrameType(Http2FrameType type)60 SpdyFrameType ToSpdyFrameType(Http2FrameType type) {
61   return ParseFrameType(static_cast<uint8_t>(type));
62 }
63 
ToSpdyPingId(const Http2PingFields & ping)64 uint64_t ToSpdyPingId(const Http2PingFields& ping) {
65   uint64_t v;
66   std::memcpy(&v, ping.opaque_bytes, Http2PingFields::EncodedSize());
67   return quiche::QuicheEndian::NetToHost64(v);
68 }
69 
70 // Overwrites the fields of the header with invalid values, for the purpose
71 // of identifying reading of unset fields. Only takes effect for debug builds.
72 // In Address Sanatizer builds, it also marks the fields as un-readable.
73 #ifndef NDEBUG
CorruptFrameHeader(Http2FrameHeader * header)74 void CorruptFrameHeader(Http2FrameHeader* header) {
75   // Beyond a valid payload length, which is 2^24 - 1.
76   header->payload_length = 0x1010dead;
77   // An unsupported frame type.
78   header->type = Http2FrameType(0x80);
79   QUICHE_DCHECK(!IsSupportedHttp2FrameType(header->type));
80   // Frame flag bits that aren't used by any supported frame type.
81   header->flags = Http2FrameFlag(0xd2);
82   // A stream id with the reserved high-bit (R in the RFC) set.
83   // 2129510127 when the high-bit is cleared.
84   header->stream_id = 0xfeedbeef;
85 }
86 #else
CorruptFrameHeader(Http2FrameHeader *)87 void CorruptFrameHeader(Http2FrameHeader* /*header*/) {}
88 #endif
89 
HpackDecodingErrorToSpdyFramerError(HpackDecodingError error)90 Http2DecoderAdapter::SpdyFramerError HpackDecodingErrorToSpdyFramerError(
91     HpackDecodingError error) {
92   switch (error) {
93     case HpackDecodingError::kOk:
94       return Http2DecoderAdapter::SpdyFramerError::SPDY_NO_ERROR;
95     case HpackDecodingError::kIndexVarintError:
96       return Http2DecoderAdapter::SpdyFramerError::
97           SPDY_HPACK_INDEX_VARINT_ERROR;
98     case HpackDecodingError::kNameLengthVarintError:
99       return Http2DecoderAdapter::SpdyFramerError::
100           SPDY_HPACK_NAME_LENGTH_VARINT_ERROR;
101     case HpackDecodingError::kValueLengthVarintError:
102       return Http2DecoderAdapter::SpdyFramerError::
103           SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR;
104     case HpackDecodingError::kNameTooLong:
105       return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_NAME_TOO_LONG;
106     case HpackDecodingError::kValueTooLong:
107       return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_VALUE_TOO_LONG;
108     case HpackDecodingError::kNameHuffmanError:
109       return Http2DecoderAdapter::SpdyFramerError::
110           SPDY_HPACK_NAME_HUFFMAN_ERROR;
111     case HpackDecodingError::kValueHuffmanError:
112       return Http2DecoderAdapter::SpdyFramerError::
113           SPDY_HPACK_VALUE_HUFFMAN_ERROR;
114     case HpackDecodingError::kMissingDynamicTableSizeUpdate:
115       return Http2DecoderAdapter::SpdyFramerError::
116           SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE;
117     case HpackDecodingError::kInvalidIndex:
118       return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_INVALID_INDEX;
119     case HpackDecodingError::kInvalidNameIndex:
120       return Http2DecoderAdapter::SpdyFramerError::
121           SPDY_HPACK_INVALID_NAME_INDEX;
122     case HpackDecodingError::kDynamicTableSizeUpdateNotAllowed:
123       return Http2DecoderAdapter::SpdyFramerError::
124           SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED;
125     case HpackDecodingError::kInitialDynamicTableSizeUpdateIsAboveLowWaterMark:
126       return Http2DecoderAdapter::SpdyFramerError::
127           SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK;
128     case HpackDecodingError::kDynamicTableSizeUpdateIsAboveAcknowledgedSetting:
129       return Http2DecoderAdapter::SpdyFramerError::
130           SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING;
131     case HpackDecodingError::kTruncatedBlock:
132       return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_TRUNCATED_BLOCK;
133     case HpackDecodingError::kFragmentTooLong:
134       return Http2DecoderAdapter::SpdyFramerError::SPDY_HPACK_FRAGMENT_TOO_LONG;
135     case HpackDecodingError::kCompressedHeaderSizeExceedsLimit:
136       return Http2DecoderAdapter::SpdyFramerError::
137           SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT;
138   }
139 
140   return Http2DecoderAdapter::SpdyFramerError::SPDY_DECOMPRESS_FAILURE;
141 }
142 
143 }  // namespace
144 
StateToString(int state)145 const char* Http2DecoderAdapter::StateToString(int state) {
146   switch (state) {
147     case SPDY_ERROR:
148       return "ERROR";
149     case SPDY_FRAME_COMPLETE:
150       return "FRAME_COMPLETE";
151     case SPDY_READY_FOR_FRAME:
152       return "READY_FOR_FRAME";
153     case SPDY_READING_COMMON_HEADER:
154       return "READING_COMMON_HEADER";
155     case SPDY_CONTROL_FRAME_PAYLOAD:
156       return "CONTROL_FRAME_PAYLOAD";
157     case SPDY_READ_DATA_FRAME_PADDING_LENGTH:
158       return "SPDY_READ_DATA_FRAME_PADDING_LENGTH";
159     case SPDY_CONSUME_PADDING:
160       return "SPDY_CONSUME_PADDING";
161     case SPDY_IGNORE_REMAINING_PAYLOAD:
162       return "IGNORE_REMAINING_PAYLOAD";
163     case SPDY_FORWARD_STREAM_FRAME:
164       return "FORWARD_STREAM_FRAME";
165     case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
166       return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
167     case SPDY_CONTROL_FRAME_HEADER_BLOCK:
168       return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
169     case SPDY_GOAWAY_FRAME_PAYLOAD:
170       return "SPDY_GOAWAY_FRAME_PAYLOAD";
171     case SPDY_SETTINGS_FRAME_HEADER:
172       return "SPDY_SETTINGS_FRAME_HEADER";
173     case SPDY_SETTINGS_FRAME_PAYLOAD:
174       return "SPDY_SETTINGS_FRAME_PAYLOAD";
175     case SPDY_ALTSVC_FRAME_PAYLOAD:
176       return "SPDY_ALTSVC_FRAME_PAYLOAD";
177   }
178   return "UNKNOWN_STATE";
179 }
180 
SpdyFramerErrorToString(SpdyFramerError spdy_framer_error)181 const char* Http2DecoderAdapter::SpdyFramerErrorToString(
182     SpdyFramerError spdy_framer_error) {
183   switch (spdy_framer_error) {
184     case SPDY_NO_ERROR:
185       return "NO_ERROR";
186     case SPDY_INVALID_STREAM_ID:
187       return "INVALID_STREAM_ID";
188     case SPDY_INVALID_CONTROL_FRAME:
189       return "INVALID_CONTROL_FRAME";
190     case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
191       return "CONTROL_PAYLOAD_TOO_LARGE";
192     case SPDY_DECOMPRESS_FAILURE:
193       return "DECOMPRESS_FAILURE";
194     case SPDY_INVALID_PADDING:
195       return "INVALID_PADDING";
196     case SPDY_INVALID_DATA_FRAME_FLAGS:
197       return "INVALID_DATA_FRAME_FLAGS";
198     case SPDY_UNEXPECTED_FRAME:
199       return "UNEXPECTED_FRAME";
200     case SPDY_INTERNAL_FRAMER_ERROR:
201       return "INTERNAL_FRAMER_ERROR";
202     case SPDY_INVALID_CONTROL_FRAME_SIZE:
203       return "INVALID_CONTROL_FRAME_SIZE";
204     case SPDY_OVERSIZED_PAYLOAD:
205       return "OVERSIZED_PAYLOAD";
206     case SPDY_HPACK_INDEX_VARINT_ERROR:
207       return "HPACK_INDEX_VARINT_ERROR";
208     case SPDY_HPACK_NAME_LENGTH_VARINT_ERROR:
209       return "HPACK_NAME_LENGTH_VARINT_ERROR";
210     case SPDY_HPACK_VALUE_LENGTH_VARINT_ERROR:
211       return "HPACK_VALUE_LENGTH_VARINT_ERROR";
212     case SPDY_HPACK_NAME_TOO_LONG:
213       return "HPACK_NAME_TOO_LONG";
214     case SPDY_HPACK_VALUE_TOO_LONG:
215       return "HPACK_VALUE_TOO_LONG";
216     case SPDY_HPACK_NAME_HUFFMAN_ERROR:
217       return "HPACK_NAME_HUFFMAN_ERROR";
218     case SPDY_HPACK_VALUE_HUFFMAN_ERROR:
219       return "HPACK_VALUE_HUFFMAN_ERROR";
220     case SPDY_HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE:
221       return "HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE";
222     case SPDY_HPACK_INVALID_INDEX:
223       return "HPACK_INVALID_INDEX";
224     case SPDY_HPACK_INVALID_NAME_INDEX:
225       return "HPACK_INVALID_NAME_INDEX";
226     case SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED:
227       return "HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED";
228     case SPDY_HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK:
229       return "HPACK_INITIAL_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK";
230     case SPDY_HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING:
231       return "HPACK_DYNAMIC_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING";
232     case SPDY_HPACK_TRUNCATED_BLOCK:
233       return "HPACK_TRUNCATED_BLOCK";
234     case SPDY_HPACK_FRAGMENT_TOO_LONG:
235       return "HPACK_FRAGMENT_TOO_LONG";
236     case SPDY_HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT:
237       return "HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT";
238     case SPDY_STOP_PROCESSING:
239       return "STOP_PROCESSING";
240     case LAST_ERROR:
241       return "UNKNOWN_ERROR";
242   }
243   return "UNKNOWN_ERROR";
244 }
245 
Http2DecoderAdapter()246 Http2DecoderAdapter::Http2DecoderAdapter() : frame_decoder_(this) {
247   QUICHE_DVLOG(1) << "Http2DecoderAdapter ctor";
248 
249   CorruptFrameHeader(&frame_header_);
250   CorruptFrameHeader(&hpack_first_frame_header_);
251 }
252 
253 Http2DecoderAdapter::~Http2DecoderAdapter() = default;
254 
set_visitor(SpdyFramerVisitorInterface * visitor)255 void Http2DecoderAdapter::set_visitor(SpdyFramerVisitorInterface* visitor) {
256   visitor_ = visitor;
257 }
258 
set_debug_visitor(SpdyFramerDebugVisitorInterface * debug_visitor)259 void Http2DecoderAdapter::set_debug_visitor(
260     SpdyFramerDebugVisitorInterface* debug_visitor) {
261   debug_visitor_ = debug_visitor;
262 }
263 
set_extension_visitor(ExtensionVisitorInterface * visitor)264 void Http2DecoderAdapter::set_extension_visitor(
265     ExtensionVisitorInterface* visitor) {
266   extension_ = visitor;
267 }
268 
ProcessInput(const char * data,size_t len)269 size_t Http2DecoderAdapter::ProcessInput(const char* data, size_t len) {
270   size_t total_processed = 0;
271   while (len > 0 && spdy_state_ != SPDY_ERROR) {
272     // Process one at a time so that we update the adapter's internal
273     // state appropriately.
274     const size_t processed = ProcessInputFrame(data, len);
275 
276     // We had some data, and weren't in an error state, so should have
277     // processed/consumed at least one byte of it, even if we then ended up
278     // in an error state.
279     QUICHE_DCHECK(processed > 0)
280         << "processed=" << processed << "   spdy_state_=" << spdy_state_
281         << "   spdy_framer_error_=" << spdy_framer_error_;
282 
283     data += processed;
284     len -= processed;
285     total_processed += processed;
286     if (processed == 0) {
287       break;
288     }
289   }
290   return total_processed;
291 }
292 
state() const293 Http2DecoderAdapter::SpdyState Http2DecoderAdapter::state() const {
294   return spdy_state_;
295 }
296 
spdy_framer_error() const297 Http2DecoderAdapter::SpdyFramerError Http2DecoderAdapter::spdy_framer_error()
298     const {
299   return spdy_framer_error_;
300 }
301 
probable_http_response() const302 bool Http2DecoderAdapter::probable_http_response() const {
303   return latched_probable_http_response_;
304 }
305 
StopProcessing()306 void Http2DecoderAdapter::StopProcessing() {
307   SetSpdyErrorAndNotify(SpdyFramerError::SPDY_STOP_PROCESSING,
308                         "Ignoring further events on this connection.");
309 }
310 
SetMaxFrameSize(size_t max_frame_size)311 void Http2DecoderAdapter::SetMaxFrameSize(size_t max_frame_size) {
312   max_frame_size_ = max_frame_size;
313   frame_decoder_.set_maximum_payload_size(max_frame_size);
314 }
315 
316 // ===========================================================================
317 // Implementations of the methods declared by Http2FrameDecoderListener.
318 
319 // Called once the common frame header has been decoded for any frame.
320 // This function is largely based on Http2DecoderAdapter::ValidateFrameHeader
321 // and some parts of Http2DecoderAdapter::ProcessCommonHeader.
OnFrameHeader(const Http2FrameHeader & header)322 bool Http2DecoderAdapter::OnFrameHeader(const Http2FrameHeader& header) {
323   QUICHE_DVLOG(1) << "OnFrameHeader: " << header;
324   decoded_frame_header_ = true;
325   if (!latched_probable_http_response_) {
326     latched_probable_http_response_ = header.IsProbableHttpResponse();
327   }
328   const uint8_t raw_frame_type = static_cast<uint8_t>(header.type);
329   visitor()->OnCommonHeader(header.stream_id, header.payload_length,
330                             raw_frame_type, header.flags);
331   if (has_expected_frame_type_ && header.type != expected_frame_type_) {
332     // Report an unexpected frame error and close the connection if we
333     // expect a known frame type (probably CONTINUATION) and receive an
334     // unknown frame.
335     QUICHE_VLOG(1) << "The framer was expecting to receive a "
336                    << expected_frame_type_
337                    << " frame, but instead received an unknown frame of type "
338                    << header.type;
339     SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
340     return false;
341   }
342   if (!IsSupportedHttp2FrameType(header.type)) {
343     if (extension_ != nullptr) {
344       // Unknown frames will be passed to the registered extension.
345       return true;
346     }
347     // In HTTP2 we ignore unknown frame types for extensibility, as long as
348     // the rest of the control frame header is valid.
349     // We rely on the visitor to check validity of stream_id.
350     bool valid_stream =
351         visitor()->OnUnknownFrame(header.stream_id, raw_frame_type);
352     if (!valid_stream) {
353       // Report an invalid frame error if the stream_id is not valid.
354       QUICHE_VLOG(1) << "Unknown control frame type " << header.type
355                      << " received on invalid stream " << header.stream_id;
356       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
357       return false;
358     } else {
359       QUICHE_DVLOG(1) << "Ignoring unknown frame type " << header.type;
360       return true;
361     }
362   }
363 
364   SpdyFrameType frame_type = ToSpdyFrameType(header.type);
365   if (!IsValidHTTP2FrameStreamId(header.stream_id, frame_type)) {
366     QUICHE_VLOG(1) << "The framer received an invalid streamID of "
367                    << header.stream_id << " for a frame of type "
368                    << header.type;
369     SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
370     return false;
371   }
372 
373   if (has_expected_frame_type_ && header.type != expected_frame_type_) {
374     QUICHE_VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not "
375                    << header.type;
376     SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
377     return false;
378   }
379 
380   if (!has_expected_frame_type_ &&
381       header.type == Http2FrameType::CONTINUATION) {
382     QUICHE_VLOG(1) << "Got CONTINUATION frame when not expected.";
383     SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
384     return false;
385   }
386 
387   if (header.type == Http2FrameType::DATA) {
388     // For some reason SpdyFramer still rejects invalid DATA frame flags.
389     uint8_t valid_flags = Http2FrameFlag::PADDED | Http2FrameFlag::END_STREAM;
390     if (header.HasAnyFlags(~valid_flags)) {
391       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS, "");
392       return false;
393     }
394   }
395 
396   return true;
397 }
398 
OnDataStart(const Http2FrameHeader & header)399 void Http2DecoderAdapter::OnDataStart(const Http2FrameHeader& header) {
400   QUICHE_DVLOG(1) << "OnDataStart: " << header;
401 
402   if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
403     frame_header_ = header;
404     has_frame_header_ = true;
405     visitor()->OnDataFrameHeader(header.stream_id, header.payload_length,
406                                  header.IsEndStream());
407   }
408 }
409 
OnDataPayload(const char * data,size_t len)410 void Http2DecoderAdapter::OnDataPayload(const char* data, size_t len) {
411   QUICHE_DVLOG(1) << "OnDataPayload: len=" << len;
412   QUICHE_DCHECK(has_frame_header_);
413   QUICHE_DCHECK_EQ(frame_header_.type, Http2FrameType::DATA);
414   visitor()->OnStreamFrameData(frame_header().stream_id, data, len);
415 }
416 
OnDataEnd()417 void Http2DecoderAdapter::OnDataEnd() {
418   QUICHE_DVLOG(1) << "OnDataEnd";
419   QUICHE_DCHECK(has_frame_header_);
420   QUICHE_DCHECK_EQ(frame_header_.type, Http2FrameType::DATA);
421   if (frame_header().IsEndStream()) {
422     visitor()->OnStreamEnd(frame_header().stream_id);
423   }
424   opt_pad_length_.reset();
425 }
426 
OnHeadersStart(const Http2FrameHeader & header)427 void Http2DecoderAdapter::OnHeadersStart(const Http2FrameHeader& header) {
428   QUICHE_DVLOG(1) << "OnHeadersStart: " << header;
429   if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
430     frame_header_ = header;
431     has_frame_header_ = true;
432     if (header.HasPriority()) {
433       // Once we've got the priority fields, then we can report the arrival
434       // of this HEADERS frame.
435       on_headers_called_ = false;
436       return;
437     }
438     on_headers_called_ = true;
439     ReportReceiveCompressedFrame(header);
440     visitor()->OnHeaders(header.stream_id, header.payload_length,
441                          kNotHasPriorityFields,
442                          0,      // priority
443                          0,      // parent_stream_id
444                          false,  // exclusive
445                          header.IsEndStream(), header.IsEndHeaders());
446     CommonStartHpackBlock();
447   }
448 }
449 
OnHeadersPriority(const Http2PriorityFields & priority)450 void Http2DecoderAdapter::OnHeadersPriority(
451     const Http2PriorityFields& priority) {
452   QUICHE_DVLOG(1) << "OnHeadersPriority: " << priority;
453   QUICHE_DCHECK(has_frame_header_);
454   QUICHE_DCHECK_EQ(frame_type(), Http2FrameType::HEADERS) << frame_header_;
455   QUICHE_DCHECK(frame_header_.HasPriority());
456   QUICHE_DCHECK(!on_headers_called_);
457   on_headers_called_ = true;
458   ReportReceiveCompressedFrame(frame_header_);
459   if (!visitor()) {
460     QUICHE_BUG(spdy_bug_1_1)
461         << "Visitor is nullptr, handling priority in headers failed."
462         << " priority:" << priority << " frame_header:" << frame_header_;
463     return;
464   }
465   visitor()->OnHeaders(
466       frame_header_.stream_id, frame_header_.payload_length, kHasPriorityFields,
467       priority.weight, priority.stream_dependency, priority.is_exclusive,
468       frame_header_.IsEndStream(), frame_header_.IsEndHeaders());
469   CommonStartHpackBlock();
470 }
471 
OnHpackFragment(const char * data,size_t len)472 void Http2DecoderAdapter::OnHpackFragment(const char* data, size_t len) {
473   QUICHE_DVLOG(1) << "OnHpackFragment: len=" << len;
474   on_hpack_fragment_called_ = true;
475   auto& decoder = GetHpackDecoder();
476   if (!decoder.HandleControlFrameHeadersData(data, len)) {
477     SetSpdyErrorAndNotify(HpackDecodingErrorToSpdyFramerError(decoder.error()),
478                           "");
479     return;
480   }
481 }
482 
OnHeadersEnd()483 void Http2DecoderAdapter::OnHeadersEnd() {
484   QUICHE_DVLOG(1) << "OnHeadersEnd";
485   CommonHpackFragmentEnd();
486   opt_pad_length_.reset();
487 }
488 
OnPriorityFrame(const Http2FrameHeader & header,const Http2PriorityFields & priority)489 void Http2DecoderAdapter::OnPriorityFrame(const Http2FrameHeader& header,
490                                           const Http2PriorityFields& priority) {
491   QUICHE_DVLOG(1) << "OnPriorityFrame: " << header
492                   << "; priority: " << priority;
493   if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
494     visitor()->OnPriority(header.stream_id, priority.stream_dependency,
495                           priority.weight, priority.is_exclusive);
496   }
497 }
498 
OnContinuationStart(const Http2FrameHeader & header)499 void Http2DecoderAdapter::OnContinuationStart(const Http2FrameHeader& header) {
500   QUICHE_DVLOG(1) << "OnContinuationStart: " << header;
501   if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
502     QUICHE_DCHECK(has_hpack_first_frame_header_);
503     if (header.stream_id != hpack_first_frame_header_.stream_id) {
504       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
505       return;
506     }
507     frame_header_ = header;
508     has_frame_header_ = true;
509     ReportReceiveCompressedFrame(header);
510     visitor()->OnContinuation(header.stream_id, header.payload_length,
511                               header.IsEndHeaders());
512   }
513 }
514 
OnContinuationEnd()515 void Http2DecoderAdapter::OnContinuationEnd() {
516   QUICHE_DVLOG(1) << "OnContinuationEnd";
517   CommonHpackFragmentEnd();
518 }
519 
OnPadLength(size_t trailing_length)520 void Http2DecoderAdapter::OnPadLength(size_t trailing_length) {
521   QUICHE_DVLOG(1) << "OnPadLength: " << trailing_length;
522   opt_pad_length_ = trailing_length;
523   QUICHE_DCHECK_LT(trailing_length, 256u);
524   if (frame_header_.type == Http2FrameType::DATA) {
525     visitor()->OnStreamPadLength(stream_id(), trailing_length);
526   }
527 }
528 
OnPadding(const char *,size_t skipped_length)529 void Http2DecoderAdapter::OnPadding(const char* /*padding*/,
530                                     size_t skipped_length) {
531   QUICHE_DVLOG(1) << "OnPadding: " << skipped_length;
532   if (frame_header_.type == Http2FrameType::DATA) {
533     visitor()->OnStreamPadding(stream_id(), skipped_length);
534   } else {
535     MaybeAnnounceEmptyFirstHpackFragment();
536   }
537 }
538 
OnRstStream(const Http2FrameHeader & header,Http2ErrorCode http2_error_code)539 void Http2DecoderAdapter::OnRstStream(const Http2FrameHeader& header,
540                                       Http2ErrorCode http2_error_code) {
541   QUICHE_DVLOG(1) << "OnRstStream: " << header << "; code=" << http2_error_code;
542   if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
543     SpdyErrorCode error_code =
544         ParseErrorCode(static_cast<uint32_t>(http2_error_code));
545     visitor()->OnRstStream(header.stream_id, error_code);
546   }
547 }
548 
OnSettingsStart(const Http2FrameHeader & header)549 void Http2DecoderAdapter::OnSettingsStart(const Http2FrameHeader& header) {
550   QUICHE_DVLOG(1) << "OnSettingsStart: " << header;
551   if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
552     frame_header_ = header;
553     has_frame_header_ = true;
554     visitor()->OnSettings();
555   }
556 }
557 
OnSetting(const Http2SettingFields & setting_fields)558 void Http2DecoderAdapter::OnSetting(const Http2SettingFields& setting_fields) {
559   QUICHE_DVLOG(1) << "OnSetting: " << setting_fields;
560   const auto parameter = static_cast<SpdySettingsId>(setting_fields.parameter);
561   visitor()->OnSetting(parameter, setting_fields.value);
562   SpdyKnownSettingsId known_id;
563   if (extension_ != nullptr && !spdy::ParseSettingsId(parameter, &known_id)) {
564     extension_->OnSetting(parameter, setting_fields.value);
565   }
566 }
567 
OnSettingsEnd()568 void Http2DecoderAdapter::OnSettingsEnd() {
569   QUICHE_DVLOG(1) << "OnSettingsEnd";
570   visitor()->OnSettingsEnd();
571 }
572 
OnSettingsAck(const Http2FrameHeader & header)573 void Http2DecoderAdapter::OnSettingsAck(const Http2FrameHeader& header) {
574   QUICHE_DVLOG(1) << "OnSettingsAck: " << header;
575   if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
576     visitor()->OnSettingsAck();
577   }
578 }
579 
OnPushPromiseStart(const Http2FrameHeader & header,const Http2PushPromiseFields & promise,size_t total_padding_length)580 void Http2DecoderAdapter::OnPushPromiseStart(
581     const Http2FrameHeader& header, const Http2PushPromiseFields& promise,
582     size_t total_padding_length) {
583   QUICHE_DVLOG(1) << "OnPushPromiseStart: " << header
584                   << "; promise: " << promise
585                   << "; total_padding_length: " << total_padding_length;
586   if (IsOkToStartFrame(header) && HasRequiredStreamId(header)) {
587     if (promise.promised_stream_id == 0) {
588       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
589       return;
590     }
591     frame_header_ = header;
592     has_frame_header_ = true;
593     ReportReceiveCompressedFrame(header);
594     visitor()->OnPushPromise(header.stream_id, promise.promised_stream_id,
595                              header.IsEndHeaders());
596     CommonStartHpackBlock();
597   }
598 }
599 
OnPushPromiseEnd()600 void Http2DecoderAdapter::OnPushPromiseEnd() {
601   QUICHE_DVLOG(1) << "OnPushPromiseEnd";
602   CommonHpackFragmentEnd();
603   opt_pad_length_.reset();
604 }
605 
OnPing(const Http2FrameHeader & header,const Http2PingFields & ping)606 void Http2DecoderAdapter::OnPing(const Http2FrameHeader& header,
607                                  const Http2PingFields& ping) {
608   QUICHE_DVLOG(1) << "OnPing: " << header << "; ping: " << ping;
609   if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
610     visitor()->OnPing(ToSpdyPingId(ping), false);
611   }
612 }
613 
OnPingAck(const Http2FrameHeader & header,const Http2PingFields & ping)614 void Http2DecoderAdapter::OnPingAck(const Http2FrameHeader& header,
615                                     const Http2PingFields& ping) {
616   QUICHE_DVLOG(1) << "OnPingAck: " << header << "; ping: " << ping;
617   if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
618     visitor()->OnPing(ToSpdyPingId(ping), true);
619   }
620 }
621 
OnGoAwayStart(const Http2FrameHeader & header,const Http2GoAwayFields & goaway)622 void Http2DecoderAdapter::OnGoAwayStart(const Http2FrameHeader& header,
623                                         const Http2GoAwayFields& goaway) {
624   QUICHE_DVLOG(1) << "OnGoAwayStart: " << header << "; goaway: " << goaway;
625   if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
626     frame_header_ = header;
627     has_frame_header_ = true;
628     SpdyErrorCode error_code =
629         ParseErrorCode(static_cast<uint32_t>(goaway.error_code));
630     visitor()->OnGoAway(goaway.last_stream_id, error_code);
631   }
632 }
633 
OnGoAwayOpaqueData(const char * data,size_t len)634 void Http2DecoderAdapter::OnGoAwayOpaqueData(const char* data, size_t len) {
635   QUICHE_DVLOG(1) << "OnGoAwayOpaqueData: len=" << len;
636   visitor()->OnGoAwayFrameData(data, len);
637 }
638 
OnGoAwayEnd()639 void Http2DecoderAdapter::OnGoAwayEnd() {
640   QUICHE_DVLOG(1) << "OnGoAwayEnd";
641   visitor()->OnGoAwayFrameData(nullptr, 0);
642 }
643 
OnWindowUpdate(const Http2FrameHeader & header,uint32_t increment)644 void Http2DecoderAdapter::OnWindowUpdate(const Http2FrameHeader& header,
645                                          uint32_t increment) {
646   QUICHE_DVLOG(1) << "OnWindowUpdate: " << header
647                   << "; increment=" << increment;
648   if (IsOkToStartFrame(header)) {
649     visitor()->OnWindowUpdate(header.stream_id, increment);
650   }
651 }
652 
653 // Per RFC7838, an ALTSVC frame on stream 0 with origin_length == 0, or one on
654 // a stream other than stream 0 with origin_length != 0 MUST be ignored.  All
655 // frames are decoded by Http2DecoderAdapter, and it is left to the consumer
656 // (listener) to implement this behavior.
OnAltSvcStart(const Http2FrameHeader & header,size_t origin_length,size_t value_length)657 void Http2DecoderAdapter::OnAltSvcStart(const Http2FrameHeader& header,
658                                         size_t origin_length,
659                                         size_t value_length) {
660   QUICHE_DVLOG(1) << "OnAltSvcStart: " << header
661                   << "; origin_length: " << origin_length
662                   << "; value_length: " << value_length;
663   if (!IsOkToStartFrame(header)) {
664     return;
665   }
666   frame_header_ = header;
667   has_frame_header_ = true;
668   alt_svc_origin_.clear();
669   alt_svc_value_.clear();
670 }
671 
OnAltSvcOriginData(const char * data,size_t len)672 void Http2DecoderAdapter::OnAltSvcOriginData(const char* data, size_t len) {
673   QUICHE_DVLOG(1) << "OnAltSvcOriginData: len=" << len;
674   alt_svc_origin_.append(data, len);
675 }
676 
677 // Called when decoding the Alt-Svc-Field-Value of an ALTSVC;
678 // the field is uninterpreted.
OnAltSvcValueData(const char * data,size_t len)679 void Http2DecoderAdapter::OnAltSvcValueData(const char* data, size_t len) {
680   QUICHE_DVLOG(1) << "OnAltSvcValueData: len=" << len;
681   alt_svc_value_.append(data, len);
682 }
683 
OnAltSvcEnd()684 void Http2DecoderAdapter::OnAltSvcEnd() {
685   QUICHE_DVLOG(1) << "OnAltSvcEnd: origin.size(): " << alt_svc_origin_.size()
686                   << "; value.size(): " << alt_svc_value_.size();
687   SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector;
688   if (!SpdyAltSvcWireFormat::ParseHeaderFieldValue(alt_svc_value_,
689                                                    &altsvc_vector)) {
690     QUICHE_DLOG(ERROR) << "SpdyAltSvcWireFormat::ParseHeaderFieldValue failed.";
691     SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
692     return;
693   }
694   visitor()->OnAltSvc(frame_header_.stream_id, alt_svc_origin_, altsvc_vector);
695   // We assume that ALTSVC frames are rare, so get rid of the storage.
696   alt_svc_origin_.clear();
697   alt_svc_origin_.shrink_to_fit();
698   alt_svc_value_.clear();
699   alt_svc_value_.shrink_to_fit();
700 }
701 
OnPriorityUpdateStart(const Http2FrameHeader & header,const Http2PriorityUpdateFields & priority_update)702 void Http2DecoderAdapter::OnPriorityUpdateStart(
703     const Http2FrameHeader& header,
704     const Http2PriorityUpdateFields& priority_update) {
705   QUICHE_DVLOG(1) << "OnPriorityUpdateStart: " << header
706                   << "; prioritized_stream_id: "
707                   << priority_update.prioritized_stream_id;
708   if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header) &&
709       HasRequiredStreamId(priority_update.prioritized_stream_id)) {
710     frame_header_ = header;
711     has_frame_header_ = true;
712     prioritized_stream_id_ = priority_update.prioritized_stream_id;
713   }
714 }
715 
OnPriorityUpdatePayload(const char * data,size_t len)716 void Http2DecoderAdapter::OnPriorityUpdatePayload(const char* data,
717                                                   size_t len) {
718   QUICHE_DVLOG(1) << "OnPriorityUpdatePayload: len=" << len;
719   priority_field_value_.append(data, len);
720 }
721 
OnPriorityUpdateEnd()722 void Http2DecoderAdapter::OnPriorityUpdateEnd() {
723   QUICHE_DVLOG(1) << "OnPriorityUpdateEnd: priority_field_value.size(): "
724                   << priority_field_value_.size();
725   visitor()->OnPriorityUpdate(prioritized_stream_id_, priority_field_value_);
726   priority_field_value_.clear();
727 }
728 
OnUnknownStart(const Http2FrameHeader & header)729 void Http2DecoderAdapter::OnUnknownStart(const Http2FrameHeader& header) {
730   QUICHE_DVLOG(1) << "OnUnknownStart: " << header;
731   if (IsOkToStartFrame(header)) {
732     frame_header_ = header;
733     has_frame_header_ = true;
734     const uint8_t type = static_cast<uint8_t>(header.type);
735     const uint8_t flags = static_cast<uint8_t>(header.flags);
736     if (extension_ != nullptr) {
737       handling_extension_payload_ = extension_->OnFrameHeader(
738           header.stream_id, header.payload_length, type, flags);
739     }
740     visitor()->OnUnknownFrameStart(header.stream_id, header.payload_length,
741                                    type, flags);
742   }
743 }
744 
OnUnknownPayload(const char * data,size_t len)745 void Http2DecoderAdapter::OnUnknownPayload(const char* data, size_t len) {
746   if (handling_extension_payload_) {
747     extension_->OnFramePayload(data, len);
748   } else {
749     QUICHE_DVLOG(1) << "OnUnknownPayload: len=" << len;
750   }
751   visitor()->OnUnknownFramePayload(frame_header_.stream_id,
752                                    absl::string_view(data, len));
753 }
754 
OnUnknownEnd()755 void Http2DecoderAdapter::OnUnknownEnd() {
756   QUICHE_DVLOG(1) << "OnUnknownEnd";
757   handling_extension_payload_ = false;
758 }
759 
OnPaddingTooLong(const Http2FrameHeader & header,size_t missing_length)760 void Http2DecoderAdapter::OnPaddingTooLong(const Http2FrameHeader& header,
761                                            size_t missing_length) {
762   QUICHE_DVLOG(1) << "OnPaddingTooLong: " << header
763                   << "; missing_length: " << missing_length;
764   if (header.type == Http2FrameType::DATA) {
765     if (header.payload_length == 0) {
766       QUICHE_DCHECK_EQ(1u, missing_length);
767       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_DATA_FRAME_FLAGS, "");
768       return;
769     }
770     visitor()->OnStreamPadding(header.stream_id, 1);
771   }
772   SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_PADDING, "");
773 }
774 
OnFrameSizeError(const Http2FrameHeader & header)775 void Http2DecoderAdapter::OnFrameSizeError(const Http2FrameHeader& header) {
776   QUICHE_DVLOG(1) << "OnFrameSizeError: " << header;
777   if (header.payload_length > max_frame_size_) {
778     if (header.type == Http2FrameType::DATA) {
779       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_OVERSIZED_PAYLOAD, "");
780     } else {
781       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
782                             "");
783     }
784     return;
785   }
786   switch (header.type) {
787     case Http2FrameType::GOAWAY:
788     case Http2FrameType::ALTSVC:
789       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME, "");
790       break;
791     default:
792       SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_CONTROL_FRAME_SIZE,
793                             "");
794   }
795 }
796 
797 // Decodes the input up to the next frame boundary (i.e. at most one frame),
798 // stopping early if an error is detected.
ProcessInputFrame(const char * data,size_t len)799 size_t Http2DecoderAdapter::ProcessInputFrame(const char* data, size_t len) {
800   QUICHE_DCHECK_NE(spdy_state_, SpdyState::SPDY_ERROR);
801   DecodeBuffer db(data, len);
802   DecodeStatus status = frame_decoder_.DecodeFrame(&db);
803   if (spdy_state_ != SpdyState::SPDY_ERROR) {
804     DetermineSpdyState(status);
805   } else {
806     QUICHE_VLOG(1) << "ProcessInputFrame spdy_framer_error_="
807                    << SpdyFramerErrorToString(spdy_framer_error_);
808     if (spdy_framer_error_ == SpdyFramerError::SPDY_INVALID_PADDING &&
809         has_frame_header_ && frame_type() != Http2FrameType::DATA) {
810       // spdy_framer_test checks that all of the available frame payload
811       // has been consumed, so do that.
812       size_t total = remaining_total_payload();
813       if (total <= frame_header().payload_length) {
814         size_t avail = db.MinLengthRemaining(total);
815         QUICHE_VLOG(1) << "Skipping past " << avail << " bytes, of " << total
816                        << " total remaining in the frame's payload.";
817         db.AdvanceCursor(avail);
818       } else {
819         QUICHE_BUG(spdy_bug_1_2)
820             << "Total remaining (" << total
821             << ") should not be greater than the payload length; "
822             << frame_header();
823       }
824     }
825   }
826   return db.Offset();
827 }
828 
829 // After decoding, determine the next SpdyState. Only called if the current
830 // state is NOT SpdyState::SPDY_ERROR (i.e. if none of the callback methods
831 // detected an error condition), because otherwise we assume that the callback
832 // method has set spdy_framer_error_ appropriately.
DetermineSpdyState(DecodeStatus status)833 void Http2DecoderAdapter::DetermineSpdyState(DecodeStatus status) {
834   QUICHE_DCHECK_EQ(spdy_framer_error_, SPDY_NO_ERROR);
835   QUICHE_DCHECK(!HasError()) << spdy_framer_error_;
836   switch (status) {
837     case DecodeStatus::kDecodeDone:
838       QUICHE_DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeDone";
839       ResetBetweenFrames();
840       break;
841     case DecodeStatus::kDecodeInProgress:
842       QUICHE_DVLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeInProgress";
843       if (decoded_frame_header_) {
844         if (IsDiscardingPayload()) {
845           set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD);
846         } else if (has_frame_header_ && frame_type() == Http2FrameType::DATA) {
847           if (IsReadingPaddingLength()) {
848             set_spdy_state(SpdyState::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
849           } else if (IsSkippingPadding()) {
850             set_spdy_state(SpdyState::SPDY_CONSUME_PADDING);
851           } else {
852             set_spdy_state(SpdyState::SPDY_FORWARD_STREAM_FRAME);
853           }
854         } else {
855           set_spdy_state(SpdyState::SPDY_CONTROL_FRAME_PAYLOAD);
856         }
857       } else {
858         set_spdy_state(SpdyState::SPDY_READING_COMMON_HEADER);
859       }
860       break;
861     case DecodeStatus::kDecodeError:
862       QUICHE_VLOG(1) << "ProcessInputFrame -> DecodeStatus::kDecodeError";
863       if (IsDiscardingPayload()) {
864         if (remaining_total_payload() == 0) {
865           // Push the Http2FrameDecoder out of state kDiscardPayload now
866           // since doing so requires no input.
867           DecodeBuffer tmp("", 0);
868           DecodeStatus decode_status = frame_decoder_.DecodeFrame(&tmp);
869           if (decode_status != DecodeStatus::kDecodeDone) {
870             QUICHE_BUG(spdy_bug_1_3)
871                 << "Expected to be done decoding the frame, not "
872                 << decode_status;
873             SetSpdyErrorAndNotify(SPDY_INTERNAL_FRAMER_ERROR, "");
874           } else if (spdy_framer_error_ != SPDY_NO_ERROR) {
875             QUICHE_BUG(spdy_bug_1_4)
876                 << "Expected to have no error, not "
877                 << SpdyFramerErrorToString(spdy_framer_error_);
878           } else {
879             ResetBetweenFrames();
880           }
881         } else {
882           set_spdy_state(SpdyState::SPDY_IGNORE_REMAINING_PAYLOAD);
883         }
884       } else {
885         SetSpdyErrorAndNotify(SPDY_INVALID_CONTROL_FRAME, "");
886       }
887       break;
888   }
889 }
890 
ResetBetweenFrames()891 void Http2DecoderAdapter::ResetBetweenFrames() {
892   CorruptFrameHeader(&frame_header_);
893   decoded_frame_header_ = false;
894   has_frame_header_ = false;
895   set_spdy_state(SpdyState::SPDY_READY_FOR_FRAME);
896 }
897 
set_spdy_state(SpdyState v)898 void Http2DecoderAdapter::set_spdy_state(SpdyState v) {
899   QUICHE_DVLOG(2) << "set_spdy_state(" << StateToString(v) << ")";
900   spdy_state_ = v;
901 }
902 
SetSpdyErrorAndNotify(SpdyFramerError error,std::string detailed_error)903 void Http2DecoderAdapter::SetSpdyErrorAndNotify(SpdyFramerError error,
904                                                 std::string detailed_error) {
905   if (HasError()) {
906     QUICHE_DCHECK_EQ(spdy_state_, SpdyState::SPDY_ERROR);
907   } else {
908     QUICHE_VLOG(2) << "SetSpdyErrorAndNotify(" << SpdyFramerErrorToString(error)
909                    << ")";
910     QUICHE_DCHECK_NE(error, SpdyFramerError::SPDY_NO_ERROR);
911     spdy_framer_error_ = error;
912     set_spdy_state(SpdyState::SPDY_ERROR);
913     frame_decoder_.set_listener(&no_op_listener_);
914     visitor()->OnError(error, detailed_error);
915   }
916 }
917 
HasError() const918 bool Http2DecoderAdapter::HasError() const {
919   if (spdy_state_ == SpdyState::SPDY_ERROR) {
920     QUICHE_DCHECK_NE(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR);
921     return true;
922   } else {
923     QUICHE_DCHECK_EQ(spdy_framer_error(), SpdyFramerError::SPDY_NO_ERROR);
924     return false;
925   }
926 }
927 
frame_header() const928 const Http2FrameHeader& Http2DecoderAdapter::frame_header() const {
929   QUICHE_DCHECK(has_frame_header_);
930   return frame_header_;
931 }
932 
stream_id() const933 uint32_t Http2DecoderAdapter::stream_id() const {
934   return frame_header().stream_id;
935 }
936 
frame_type() const937 Http2FrameType Http2DecoderAdapter::frame_type() const {
938   return frame_header().type;
939 }
940 
remaining_total_payload() const941 size_t Http2DecoderAdapter::remaining_total_payload() const {
942   QUICHE_DCHECK(has_frame_header_);
943   size_t remaining = frame_decoder_.remaining_payload();
944   if (IsPaddable(frame_type()) && frame_header_.IsPadded()) {
945     remaining += frame_decoder_.remaining_padding();
946   }
947   return remaining;
948 }
949 
IsReadingPaddingLength()950 bool Http2DecoderAdapter::IsReadingPaddingLength() {
951   bool result = frame_header_.IsPadded() && !opt_pad_length_;
952   QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsReadingPaddingLength: " << result;
953   return result;
954 }
IsSkippingPadding()955 bool Http2DecoderAdapter::IsSkippingPadding() {
956   bool result = frame_header_.IsPadded() && opt_pad_length_ &&
957                 frame_decoder_.remaining_payload() == 0 &&
958                 frame_decoder_.remaining_padding() > 0;
959   QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsSkippingPadding: " << result;
960   return result;
961 }
IsDiscardingPayload()962 bool Http2DecoderAdapter::IsDiscardingPayload() {
963   bool result = decoded_frame_header_ && frame_decoder_.IsDiscardingPayload();
964   QUICHE_DVLOG(2) << "Http2DecoderAdapter::IsDiscardingPayload: " << result;
965   return result;
966 }
967 // Called from OnXyz or OnXyzStart methods to decide whether it is OK to
968 // handle the callback.
IsOkToStartFrame(const Http2FrameHeader & header)969 bool Http2DecoderAdapter::IsOkToStartFrame(const Http2FrameHeader& header) {
970   QUICHE_DVLOG(3) << "IsOkToStartFrame";
971   if (HasError()) {
972     QUICHE_VLOG(2) << "HasError()";
973     return false;
974   }
975   QUICHE_DCHECK(!has_frame_header_);
976   if (has_expected_frame_type_ && header.type != expected_frame_type_) {
977     QUICHE_VLOG(1) << "Expected frame type " << expected_frame_type_ << ", not "
978                    << header.type;
979     SetSpdyErrorAndNotify(SpdyFramerError::SPDY_UNEXPECTED_FRAME, "");
980     return false;
981   }
982 
983   return true;
984 }
985 
HasRequiredStreamId(uint32_t stream_id)986 bool Http2DecoderAdapter::HasRequiredStreamId(uint32_t stream_id) {
987   QUICHE_DVLOG(3) << "HasRequiredStreamId: " << stream_id;
988   if (HasError()) {
989     QUICHE_VLOG(2) << "HasError()";
990     return false;
991   }
992   if (stream_id != 0) {
993     return true;
994   }
995   QUICHE_VLOG(1) << "Stream Id is required, but zero provided";
996   SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
997   return false;
998 }
999 
HasRequiredStreamId(const Http2FrameHeader & header)1000 bool Http2DecoderAdapter::HasRequiredStreamId(const Http2FrameHeader& header) {
1001   return HasRequiredStreamId(header.stream_id);
1002 }
1003 
HasRequiredStreamIdZero(uint32_t stream_id)1004 bool Http2DecoderAdapter::HasRequiredStreamIdZero(uint32_t stream_id) {
1005   QUICHE_DVLOG(3) << "HasRequiredStreamIdZero: " << stream_id;
1006   if (HasError()) {
1007     QUICHE_VLOG(2) << "HasError()";
1008     return false;
1009   }
1010   if (stream_id == 0) {
1011     return true;
1012   }
1013   QUICHE_VLOG(1) << "Stream Id was not zero, as required: " << stream_id;
1014   SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INVALID_STREAM_ID, "");
1015   return false;
1016 }
1017 
HasRequiredStreamIdZero(const Http2FrameHeader & header)1018 bool Http2DecoderAdapter::HasRequiredStreamIdZero(
1019     const Http2FrameHeader& header) {
1020   return HasRequiredStreamIdZero(header.stream_id);
1021 }
1022 
ReportReceiveCompressedFrame(const Http2FrameHeader & header)1023 void Http2DecoderAdapter::ReportReceiveCompressedFrame(
1024     const Http2FrameHeader& header) {
1025   if (debug_visitor() != nullptr) {
1026     size_t total = header.payload_length + Http2FrameHeader::EncodedSize();
1027     debug_visitor()->OnReceiveCompressedFrame(
1028         header.stream_id, ToSpdyFrameType(header.type), total);
1029   }
1030 }
1031 
CommonStartHpackBlock()1032 void Http2DecoderAdapter::CommonStartHpackBlock() {
1033   QUICHE_DVLOG(1) << "CommonStartHpackBlock";
1034   QUICHE_DCHECK(!has_hpack_first_frame_header_);
1035   if (!frame_header_.IsEndHeaders()) {
1036     hpack_first_frame_header_ = frame_header_;
1037     has_hpack_first_frame_header_ = true;
1038   } else {
1039     CorruptFrameHeader(&hpack_first_frame_header_);
1040   }
1041   on_hpack_fragment_called_ = false;
1042   SpdyHeadersHandlerInterface* handler =
1043       visitor()->OnHeaderFrameStart(stream_id());
1044   if (handler == nullptr) {
1045     QUICHE_BUG(spdy_bug_1_5) << "visitor_->OnHeaderFrameStart returned nullptr";
1046     SetSpdyErrorAndNotify(SpdyFramerError::SPDY_INTERNAL_FRAMER_ERROR, "");
1047     return;
1048   }
1049   GetHpackDecoder().HandleControlFrameHeadersStart(handler);
1050 }
1051 
1052 // SpdyFramer calls HandleControlFrameHeadersData even if there are zero
1053 // fragment bytes in the first frame, so do the same.
MaybeAnnounceEmptyFirstHpackFragment()1054 void Http2DecoderAdapter::MaybeAnnounceEmptyFirstHpackFragment() {
1055   if (!on_hpack_fragment_called_) {
1056     OnHpackFragment(nullptr, 0);
1057     QUICHE_DCHECK(on_hpack_fragment_called_);
1058   }
1059 }
1060 
CommonHpackFragmentEnd()1061 void Http2DecoderAdapter::CommonHpackFragmentEnd() {
1062   QUICHE_DVLOG(1) << "CommonHpackFragmentEnd: stream_id=" << stream_id();
1063   if (HasError()) {
1064     QUICHE_VLOG(1) << "HasError(), returning";
1065     return;
1066   }
1067   QUICHE_DCHECK(has_frame_header_);
1068   MaybeAnnounceEmptyFirstHpackFragment();
1069   if (frame_header_.IsEndHeaders()) {
1070     QUICHE_DCHECK_EQ(has_hpack_first_frame_header_,
1071                      frame_type() == Http2FrameType::CONTINUATION)
1072         << frame_header();
1073     has_expected_frame_type_ = false;
1074     auto& decoder = GetHpackDecoder();
1075     if (decoder.HandleControlFrameHeadersComplete()) {
1076       visitor()->OnHeaderFrameEnd(stream_id());
1077     } else {
1078       SetSpdyErrorAndNotify(
1079           HpackDecodingErrorToSpdyFramerError(decoder.error()), "");
1080       return;
1081     }
1082     const Http2FrameHeader& first = frame_type() == Http2FrameType::CONTINUATION
1083                                         ? hpack_first_frame_header_
1084                                         : frame_header_;
1085     if (first.type == Http2FrameType::HEADERS && first.IsEndStream()) {
1086       visitor()->OnStreamEnd(first.stream_id);
1087     }
1088     has_hpack_first_frame_header_ = false;
1089     CorruptFrameHeader(&hpack_first_frame_header_);
1090   } else {
1091     QUICHE_DCHECK(has_hpack_first_frame_header_);
1092     has_expected_frame_type_ = true;
1093     expected_frame_type_ = Http2FrameType::CONTINUATION;
1094   }
1095 }
1096 
1097 }  // namespace http2
1098 
1099 namespace spdy {
1100 
OnGoAwayFrameData(const char *,size_t)1101 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* /*goaway_data*/,
1102                                                    size_t /*len*/) {
1103   return true;
1104 }
1105 
1106 }  // namespace spdy
1107