blob: 567676c75d27ffa406830006012e481060c392c7 [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"
renjietangc2aa5cb2019-06-20 12:22:53 -070011#include "net/third_party/quiche/src/quic/core/qpack/qpack_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
14#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
15
16using ::testing::Combine;
17using ::testing::Values;
18
19namespace quic {
20namespace test {
21namespace {
22
bncf21c1ad2019-06-20 20:09:50 -070023class QpackRoundTripTest : public QuicTestWithParam<FragmentMode> {
QUICHE teama6ef0a62019-03-07 20:34:33 -050024 public:
bncf21c1ad2019-06-20 20:09:50 -070025 QpackRoundTripTest() = default;
QUICHE teama6ef0a62019-03-07 20:34:33 -050026 ~QpackRoundTripTest() override = default;
27
28 spdy::SpdyHeaderBlock EncodeThenDecode(
29 const spdy::SpdyHeaderBlock& header_list) {
30 NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
renjietangc2aa5cb2019-06-20 12:22:53 -070031 NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
renjietang8a2df8f2019-08-07 10:43:52 -070032 QpackEncoder encoder(&decoder_stream_error_delegate);
33 encoder.set_qpack_stream_sender_delegate(&encoder_stream_sender_delegate);
bncf21c1ad2019-06-20 20:09:50 -070034 std::string encoded_header_block =
bnc609c24e2019-09-10 05:24:32 -070035 encoder.EncodeHeaderList(/* stream_id = */ 1, header_list, nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -050036
37 TestHeadersHandler handler;
38 NoopEncoderStreamErrorDelegate encoder_stream_error_delegate;
renjietangc2aa5cb2019-06-20 12:22:53 -070039 NoopQpackStreamSenderDelegate decoder_stream_sender_delegate;
bnc4c664c52019-08-04 18:14:12 -070040 // TODO(b/112770235): Test dynamic table and blocked streams.
41 QpackDecode(
42 /* maximum_dynamic_table_capacity = */ 0,
43 /* maximum_blocked_streams = */ 0, &encoder_stream_error_delegate,
44 &decoder_stream_sender_delegate, &handler,
45 FragmentModeToFragmentSizeGenerator(GetParam()), encoded_header_block);
QUICHE teama6ef0a62019-03-07 20:34:33 -050046
47 EXPECT_TRUE(handler.decoding_completed());
48 EXPECT_FALSE(handler.decoding_error_detected());
49
50 return handler.ReleaseHeaderList();
51 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050052};
53
QUICHE team1bfe0d72019-09-23 04:50:47 -070054INSTANTIATE_TEST_SUITE_P(All,
bncf21c1ad2019-06-20 20:09:50 -070055 QpackRoundTripTest,
56 Values(FragmentMode::kSingleChunk,
57 FragmentMode::kOctetByOctet));
QUICHE teama6ef0a62019-03-07 20:34:33 -050058
59TEST_P(QpackRoundTripTest, Empty) {
60 spdy::SpdyHeaderBlock header_list;
61 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
62 EXPECT_EQ(header_list, output);
63}
64
65TEST_P(QpackRoundTripTest, EmptyName) {
66 spdy::SpdyHeaderBlock header_list;
67 header_list["foo"] = "bar";
68 header_list[""] = "bar";
69
70 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
71 EXPECT_EQ(header_list, output);
72}
73
74TEST_P(QpackRoundTripTest, EmptyValue) {
75 spdy::SpdyHeaderBlock header_list;
76 header_list["foo"] = "";
77 header_list[""] = "";
78
79 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
80 EXPECT_EQ(header_list, output);
81}
82
83TEST_P(QpackRoundTripTest, MultipleWithLongEntries) {
84 spdy::SpdyHeaderBlock header_list;
85 header_list["foo"] = "bar";
86 header_list[":path"] = "/";
vasilvvc48c8712019-03-11 13:38:16 -070087 header_list["foobaar"] = std::string(127, 'Z');
88 header_list[std::string(1000, 'b')] = std::string(1000, 'c');
QUICHE teama6ef0a62019-03-07 20:34:33 -050089
90 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
91 EXPECT_EQ(header_list, output);
92}
93
94TEST_P(QpackRoundTripTest, StaticTable) {
95 {
96 spdy::SpdyHeaderBlock header_list;
97 header_list[":method"] = "GET";
98 header_list["accept-encoding"] = "gzip, deflate";
99 header_list["cache-control"] = "";
100 header_list["foo"] = "bar";
101 header_list[":path"] = "/";
102
103 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
104 EXPECT_EQ(header_list, output);
105 }
106 {
107 spdy::SpdyHeaderBlock header_list;
108 header_list[":method"] = "POST";
109 header_list["accept-encoding"] = "brotli";
110 header_list["cache-control"] = "foo";
111 header_list["foo"] = "bar";
112 header_list[":path"] = "/";
113
114 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
115 EXPECT_EQ(header_list, output);
116 }
117 {
118 spdy::SpdyHeaderBlock header_list;
119 header_list[":method"] = "CONNECT";
120 header_list["accept-encoding"] = "";
121 header_list["foo"] = "bar";
122 header_list[":path"] = "/";
123
124 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
125 EXPECT_EQ(header_list, output);
126 }
127}
128
bnc78053612019-04-25 20:08:12 -0700129TEST_P(QpackRoundTripTest, ValueHasNullCharacter) {
130 spdy::SpdyHeaderBlock header_list;
131 header_list["foo"] = QuicStringPiece("bar\0bar\0baz", 11);
132
133 spdy::SpdyHeaderBlock output = EncodeThenDecode(header_list);
134 EXPECT_EQ(header_list, output);
135}
136
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137} // namespace
138} // namespace test
139} // namespace quic