1 // Copyright (c) 2018 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/quic/core/qpack/qpack_decoder_stream_receiver.h"
6 
7 #include "absl/strings/string_view.h"
8 #include "quiche/http2/decoder/decode_buffer.h"
9 #include "quiche/http2/decoder/decode_status.h"
10 #include "quiche/quic/core/qpack/qpack_instructions.h"
11 
12 namespace quic {
13 
QpackDecoderStreamReceiver(Delegate * delegate)14 QpackDecoderStreamReceiver::QpackDecoderStreamReceiver(Delegate* delegate)
15     : instruction_decoder_(QpackDecoderStreamLanguage(), this),
16       delegate_(delegate),
17       error_detected_(false) {
18   QUICHE_DCHECK(delegate_);
19 }
20 
Decode(absl::string_view data)21 void QpackDecoderStreamReceiver::Decode(absl::string_view data) {
22   if (data.empty() || error_detected_) {
23     return;
24   }
25 
26   instruction_decoder_.Decode(data);
27 }
28 
OnInstructionDecoded(const QpackInstruction * instruction)29 bool QpackDecoderStreamReceiver::OnInstructionDecoded(
30     const QpackInstruction* instruction) {
31   if (instruction == InsertCountIncrementInstruction()) {
32     delegate_->OnInsertCountIncrement(instruction_decoder_.varint());
33     return true;
34   }
35 
36   if (instruction == HeaderAcknowledgementInstruction()) {
37     delegate_->OnHeaderAcknowledgement(instruction_decoder_.varint());
38     return true;
39   }
40 
41   QUICHE_DCHECK_EQ(instruction, StreamCancellationInstruction());
42   delegate_->OnStreamCancellation(instruction_decoder_.varint());
43   return true;
44 }
45 
OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,absl::string_view error_message)46 void QpackDecoderStreamReceiver::OnInstructionDecodingError(
47     QpackInstructionDecoder::ErrorCode error_code,
48     absl::string_view error_message) {
49   QUICHE_DCHECK(!error_detected_);
50 
51   error_detected_ = true;
52 
53   // There is no string literals on the decoder stream,
54   // the only possible error is INTEGER_TOO_LARGE.
55   QuicErrorCode quic_error_code =
56       (error_code == QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE)
57           ? QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE
58           : QUIC_INTERNAL_ERROR;
59   delegate_->OnErrorDetected(quic_error_code, error_message);
60 }
61 
62 }  // namespace quic
63