blob: 45ad667f0d0475ac5f4e22f60e5030b1187f017c [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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
vasilvv872e7a32019-03-12 16:42:44 -07005#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -05006#include <tuple>
7
QUICHE teama6ef0a62019-03-07 20:34:33 -05008#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test_utils.h"
9#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test_utils.h"
10#include "net/third_party/quiche/src/quic/core/qpack/qpack_test_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
13#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
14
15using ::testing::Combine;
16using ::testing::Values;
17
18namespace quic {
19namespace test {
20namespace {
21
22class QpackRoundTripTest
23 : public QuicTestWithParam<std::tuple<FragmentMode, FragmentMode>> {
24 public:
25 QpackRoundTripTest()
26 : encoding_fragment_mode_(std::get<0>(GetParam())),
27 decoding_fragment_mode_(std::get<1>(GetParam())) {}
28 ~QpackRoundTripTest() override = default;
29
30 spdy::SpdyHeaderBlock EncodeThenDecode(
31 const spdy::SpdyHeaderBlock& header_list) {
32 NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
33 NoopEncoderStreamSenderDelegate encoder_stream_sender_delegate;
vasilvvc48c8712019-03-11 13:38:16 -070034 std::string encoded_header_block = QpackEncode(
QUICHE teama6ef0a62019-03-07 20:34:33 -050035 &decoder_stream_error_delegate, &encoder_stream_sender_delegate,
36 FragmentModeToFragmentSizeGenerator(encoding_fragment_mode_),
37 &header_list);
38
39 TestHeadersHandler handler;
40 NoopEncoderStreamErrorDelegate encoder_stream_error_delegate;
41 NoopDecoderStreamSenderDelegate decoder_stream_sender_delegate;
42 QpackDecode(&encoder_stream_error_delegate, &decoder_stream_sender_delegate,
43 &handler,
44 FragmentModeToFragmentSizeGenerator(decoding_fragment_mode_),
45 encoded_header_block);
46
47 EXPECT_TRUE(handler.decoding_completed());
48 EXPECT_FALSE(handler.decoding_error_detected());
49
50 return handler.ReleaseHeaderList();
51 }
52
53 private:
54 const FragmentMode encoding_fragment_mode_;
55 const FragmentMode decoding_fragment_mode_;
56};
57
58INSTANTIATE_TEST_SUITE_P(
59 ,
60 QpackRoundTripTest,
61 Combine(Values(FragmentMode::kSingleChunk, FragmentMode::kOctetByOctet),
62 Values(FragmentMode::kSingleChunk, FragmentMode::kOctetByOctet)));
63
64TEST_P(QpackRoundTripTest, Empty) {
65 spdy::SpdyHeaderBlock header_list;
66 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
67 EXPECT_EQ(header_list, output);
68}
69
70TEST_P(QpackRoundTripTest, EmptyName) {
71 spdy::SpdyHeaderBlock header_list;
72 header_list["foo"] = "bar";
73 header_list[""] = "bar";
74
75 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
76 EXPECT_EQ(header_list, output);
77}
78
79TEST_P(QpackRoundTripTest, EmptyValue) {
80 spdy::SpdyHeaderBlock header_list;
81 header_list["foo"] = "";
82 header_list[""] = "";
83
84 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
85 EXPECT_EQ(header_list, output);
86}
87
88TEST_P(QpackRoundTripTest, MultipleWithLongEntries) {
89 spdy::SpdyHeaderBlock header_list;
90 header_list["foo"] = "bar";
91 header_list[":path"] = "/";
vasilvvc48c8712019-03-11 13:38:16 -070092 header_list["foobaar"] = std::string(127, 'Z');
93 header_list[std::string(1000, 'b')] = std::string(1000, 'c');
QUICHE teama6ef0a62019-03-07 20:34:33 -050094
95 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
96 EXPECT_EQ(header_list, output);
97}
98
99TEST_P(QpackRoundTripTest, StaticTable) {
100 {
101 spdy::SpdyHeaderBlock header_list;
102 header_list[":method"] = "GET";
103 header_list["accept-encoding"] = "gzip, deflate";
104 header_list["cache-control"] = "";
105 header_list["foo"] = "bar";
106 header_list[":path"] = "/";
107
108 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
109 EXPECT_EQ(header_list, output);
110 }
111 {
112 spdy::SpdyHeaderBlock header_list;
113 header_list[":method"] = "POST";
114 header_list["accept-encoding"] = "brotli";
115 header_list["cache-control"] = "foo";
116 header_list["foo"] = "bar";
117 header_list[":path"] = "/";
118
119 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
120 EXPECT_EQ(header_list, output);
121 }
122 {
123 spdy::SpdyHeaderBlock header_list;
124 header_list[":method"] = "CONNECT";
125 header_list["accept-encoding"] = "";
126 header_list["foo"] = "bar";
127 header_list[":path"] = "/";
128
129 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
130 EXPECT_EQ(header_list, output);
131 }
132}
133
bnc78053612019-04-25 20:08:12 -0700134TEST_P(QpackRoundTripTest, ValueHasNullCharacter) {
135 spdy::SpdyHeaderBlock header_list;
136 header_list["foo"] = QuicStringPiece("bar\0bar\0baz", 11);
137
138 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
139 EXPECT_EQ(header_list, output);
140}
141
QUICHE teama6ef0a62019-03-07 20:34:33 -0500142} // namespace
143} // namespace test
144} // namespace quic