Commit 3bbd3f68 authored by Michael Warres's avatar Michael Warres Committed by Commit Bot

Implement QpackDecoderStreamReceiver.

Merge internal change: 223386522

R=zhongyi@chromium.org

Change-Id: Iad4ddf1eb5b18e6e48730ccafd0aad3e595c60d2
Reviewed-on: https://chromium-review.googlesource.com/c/1394428
Commit-Queue: Michael Warres <mpw@chromium.org>
Reviewed-by: default avatarZhongyi Shi <zhongyi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#619827}
parent 8e3170c0
...@@ -1315,6 +1315,8 @@ component("net") { ...@@ -1315,6 +1315,8 @@ component("net") {
"third_party/quic/core/qpack/qpack_constants.h", "third_party/quic/core/qpack/qpack_constants.h",
"third_party/quic/core/qpack/qpack_decoder.cc", "third_party/quic/core/qpack/qpack_decoder.cc",
"third_party/quic/core/qpack/qpack_decoder.h", "third_party/quic/core/qpack/qpack_decoder.h",
"third_party/quic/core/qpack/qpack_decoder_stream_receiver.cc",
"third_party/quic/core/qpack/qpack_decoder_stream_receiver.h",
"third_party/quic/core/qpack/qpack_decoder_stream_sender.cc", "third_party/quic/core/qpack/qpack_decoder_stream_sender.cc",
"third_party/quic/core/qpack/qpack_decoder_stream_sender.h", "third_party/quic/core/qpack/qpack_decoder_stream_sender.h",
"third_party/quic/core/qpack/qpack_encoder.cc", "third_party/quic/core/qpack/qpack_encoder.cc",
...@@ -5091,6 +5093,7 @@ test("net_unittests") { ...@@ -5091,6 +5093,7 @@ test("net_unittests") {
"third_party/quic/core/http/spdy_utils_test.cc", "third_party/quic/core/http/spdy_utils_test.cc",
"third_party/quic/core/legacy_quic_stream_id_manager_test.cc", "third_party/quic/core/legacy_quic_stream_id_manager_test.cc",
"third_party/quic/core/packet_number_indexed_queue_test.cc", "third_party/quic/core/packet_number_indexed_queue_test.cc",
"third_party/quic/core/qpack/qpack_decoder_stream_receiver_test.cc",
"third_party/quic/core/qpack/qpack_decoder_stream_sender_test.cc", "third_party/quic/core/qpack/qpack_decoder_stream_sender_test.cc",
"third_party/quic/core/qpack/qpack_decoder_test.cc", "third_party/quic/core/qpack/qpack_decoder_test.cc",
"third_party/quic/core/qpack/qpack_encoder_stream_receiver_test.cc", "third_party/quic/core/qpack/qpack_encoder_stream_receiver_test.cc",
......
// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/third_party/quic/core/qpack/qpack_decoder_stream_receiver.h"
#include "net/third_party/quic/core/qpack/qpack_constants.h"
#include "net/third_party/quiche/src/http2/decoder/decode_buffer.h"
#include "net/third_party/quiche/src/http2/decoder/decode_status.h"
namespace quic {
QpackDecoderStreamReceiver::QpackDecoderStreamReceiver(Delegate* delegate)
: instruction_decoder_(QpackDecoderStreamLanguage(), this),
delegate_(delegate),
error_detected_(false) {
DCHECK(delegate_);
}
void QpackDecoderStreamReceiver::Decode(QuicStringPiece data) {
if (data.empty() || error_detected_) {
return;
}
instruction_decoder_.Decode(data);
}
bool QpackDecoderStreamReceiver::OnInstructionDecoded(
const QpackInstruction* instruction) {
if (instruction == TableStateSynchronizeInstruction()) {
delegate_->OnTableStateSynchronize(instruction_decoder_.varint());
return true;
}
if (instruction == HeaderAcknowledgementInstruction()) {
delegate_->OnHeaderAcknowledgement(instruction_decoder_.varint());
return true;
}
DCHECK_EQ(instruction, StreamCancellationInstruction());
delegate_->OnStreamCancellation(instruction_decoder_.varint());
return true;
}
void QpackDecoderStreamReceiver::OnError(QuicStringPiece error_message) {
DCHECK(!error_detected_);
error_detected_ = true;
delegate_->OnErrorDetected(error_message);
}
} // namespace quic
// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_THIRD_PARTY_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
#define NET_THIRD_PARTY_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
#include <cstdint>
#include "net/third_party/quic/core/qpack/qpack_instruction_decoder.h"
#include "net/third_party/quic/platform/api/quic_export.h"
#include "net/third_party/quic/platform/api/quic_string_piece.h"
namespace quic {
// This class decodes data received on the decoder stream.
class QUIC_EXPORT_PRIVATE QpackDecoderStreamReceiver
: public QpackInstructionDecoder::Delegate {
public:
// An interface for handling instructions decoded from the decoder stream, see
// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#rfc.section.5.3
class Delegate {
public:
virtual ~Delegate() = default;
// 5.3.1 Table State Synchronize
virtual void OnTableStateSynchronize(uint64_t insert_count) = 0;
// 5.3.2 Header Acknowledgement
virtual void OnHeaderAcknowledgement(uint64_t stream_id) = 0;
// 5.3.3 Stream Cancellation
virtual void OnStreamCancellation(uint64_t stream_id) = 0;
// Decoding error
virtual void OnErrorDetected(QuicStringPiece error_message) = 0;
};
explicit QpackDecoderStreamReceiver(Delegate* delegate);
QpackDecoderStreamReceiver() = delete;
QpackDecoderStreamReceiver(const QpackDecoderStreamReceiver&) = delete;
QpackDecoderStreamReceiver& operator=(const QpackDecoderStreamReceiver&) =
delete;
// Decode data and call appropriate Delegate method after each decoded
// instruction. Once an error occurs, Delegate::OnErrorDetected() is called,
// and all further data is ignored.
void Decode(QuicStringPiece data);
// QpackInstructionDecoder::Delegate implementation.
bool OnInstructionDecoded(const QpackInstruction* instruction) override;
void OnError(QuicStringPiece error_message) override;
private:
QpackInstructionDecoder instruction_decoder_;
Delegate* const delegate_;
// True if a decoding error has been detected.
bool error_detected_;
};
} // namespace quic
#endif // NET_THIRD_PARTY_QUIC_CORE_QPACK_QPACK_DECODER_STREAM_RECEIVER_H_
// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/third_party/quic/core/qpack/qpack_decoder_stream_receiver.h"
#include "net/third_party/quic/platform/api/quic_test.h"
#include "net/third_party/quic/platform/api/quic_text_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::Eq;
using testing::StrictMock;
namespace quic {
namespace test {
namespace {
class MockDelegate : public QpackDecoderStreamReceiver::Delegate {
public:
~MockDelegate() override = default;
MOCK_METHOD1(OnTableStateSynchronize, void(uint64_t insert_count));
MOCK_METHOD1(OnHeaderAcknowledgement, void(uint64_t stream_id));
MOCK_METHOD1(OnStreamCancellation, void(uint64_t stream_id));
MOCK_METHOD1(OnErrorDetected, void(QuicStringPiece error_message));
};
class QpackDecoderStreamReceiverTest : public QuicTest {
protected:
QpackDecoderStreamReceiverTest() : stream_(&delegate_) {}
QpackDecoderStreamReceiver stream_;
StrictMock<MockDelegate> delegate_;
};
TEST_F(QpackDecoderStreamReceiverTest, TableStateSynchronize) {
EXPECT_CALL(delegate_, OnTableStateSynchronize(0));
stream_.Decode(QuicTextUtils::HexDecode("00"));
EXPECT_CALL(delegate_, OnTableStateSynchronize(10));
stream_.Decode(QuicTextUtils::HexDecode("0a"));
EXPECT_CALL(delegate_, OnTableStateSynchronize(63));
stream_.Decode(QuicTextUtils::HexDecode("3f00"));
EXPECT_CALL(delegate_, OnTableStateSynchronize(200));
stream_.Decode(QuicTextUtils::HexDecode("3f8901"));
EXPECT_CALL(delegate_, OnErrorDetected(Eq("Encoded integer too large.")));
stream_.Decode(QuicTextUtils::HexDecode("3fffffffffffffffffffff"));
}
TEST_F(QpackDecoderStreamReceiverTest, HeaderAcknowledgement) {
EXPECT_CALL(delegate_, OnHeaderAcknowledgement(0));
stream_.Decode(QuicTextUtils::HexDecode("80"));
EXPECT_CALL(delegate_, OnHeaderAcknowledgement(37));
stream_.Decode(QuicTextUtils::HexDecode("a5"));
EXPECT_CALL(delegate_, OnHeaderAcknowledgement(127));
stream_.Decode(QuicTextUtils::HexDecode("ff00"));
EXPECT_CALL(delegate_, OnHeaderAcknowledgement(503));
stream_.Decode(QuicTextUtils::HexDecode("fff802"));
EXPECT_CALL(delegate_, OnErrorDetected(Eq("Encoded integer too large.")));
stream_.Decode(QuicTextUtils::HexDecode("ffffffffffffffffffffff"));
}
TEST_F(QpackDecoderStreamReceiverTest, StreamCancellation) {
EXPECT_CALL(delegate_, OnStreamCancellation(0));
stream_.Decode(QuicTextUtils::HexDecode("40"));
EXPECT_CALL(delegate_, OnStreamCancellation(19));
stream_.Decode(QuicTextUtils::HexDecode("53"));
EXPECT_CALL(delegate_, OnStreamCancellation(63));
stream_.Decode(QuicTextUtils::HexDecode("7f00"));
EXPECT_CALL(delegate_, OnStreamCancellation(110));
stream_.Decode(QuicTextUtils::HexDecode("7f2f"));
EXPECT_CALL(delegate_, OnErrorDetected(Eq("Encoded integer too large.")));
stream_.Decode(QuicTextUtils::HexDecode("7fffffffffffffffffffff"));
}
} // namespace
} // namespace test
} // namespace quic
...@@ -20,7 +20,7 @@ class MockSenderDelegate : public QpackDecoderStreamSender::Delegate { ...@@ -20,7 +20,7 @@ class MockSenderDelegate : public QpackDecoderStreamSender::Delegate {
public: public:
~MockSenderDelegate() override = default; ~MockSenderDelegate() override = default;
MOCK_METHOD1(Write, void(QuicStringPiece)); MOCK_METHOD1(Write, void(QuicStringPiece data));
}; };
class QpackDecoderStreamSenderTest : public QuicTest { class QpackDecoderStreamSenderTest : public QuicTest {
......
...@@ -20,7 +20,7 @@ class MockSenderDelegate : public QpackEncoderStreamSender::Delegate { ...@@ -20,7 +20,7 @@ class MockSenderDelegate : public QpackEncoderStreamSender::Delegate {
public: public:
~MockSenderDelegate() override = default; ~MockSenderDelegate() override = default;
MOCK_METHOD1(Write, void(QuicStringPiece)); MOCK_METHOD1(Write, void(QuicStringPiece data));
}; };
class QpackEncoderStreamSenderTest : public QuicTest { class QpackEncoderStreamSenderTest : public QuicTest {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment