xref: /aosp_15_r20/external/cronet/net/spdy/alps_decoder_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2021 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/spdy/alps_decoder.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/test/metrics/histogram_tester.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
9*6777b538SAndroid Build Coastguard Worker #include "net/base/features.h"
10*6777b538SAndroid Build Coastguard Worker #include "net/base/hex_utils.h"
11*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
12*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker using ::spdy::AcceptChOriginValuePair;
15*6777b538SAndroid Build Coastguard Worker using ::testing::ElementsAre;
16*6777b538SAndroid Build Coastguard Worker using ::testing::IsEmpty;
17*6777b538SAndroid Build Coastguard Worker using ::testing::Pair;
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker namespace net {
20*6777b538SAndroid Build Coastguard Worker namespace {
21*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,EmptyInput)22*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, EmptyInput) {
23*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
24*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetAcceptCh(), IsEmpty());
25*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetSettings(), IsEmpty());
26*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, decoder.settings_frame_count());
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error = decoder.Decode({});
29*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetAcceptCh(), IsEmpty());
32*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetSettings(), IsEmpty());
33*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, decoder.settings_frame_count());
34*6777b538SAndroid Build Coastguard Worker }
35*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,EmptyAcceptChFrame)36*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, EmptyAcceptChFrame) {
37*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
38*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
39*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("000000"       // length
40*6777b538SAndroid Build Coastguard Worker                                "89"           // type ACCEPT_CH
41*6777b538SAndroid Build Coastguard Worker                                "00"           // flags
42*6777b538SAndroid Build Coastguard Worker                                "00000000"));  // stream ID
43*6777b538SAndroid Build Coastguard Worker 
44*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
45*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetAcceptCh(), IsEmpty());
46*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetSettings(), IsEmpty());
47*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, decoder.settings_frame_count());
48*6777b538SAndroid Build Coastguard Worker }
49*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,EmptySettingsFrame)50*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, EmptySettingsFrame) {
51*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
52*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
53*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("000000"       // length
54*6777b538SAndroid Build Coastguard Worker                                "04"           // type SETTINGS
55*6777b538SAndroid Build Coastguard Worker                                "00"           // flags
56*6777b538SAndroid Build Coastguard Worker                                "00000000"));  // stream ID
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
59*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetAcceptCh(), IsEmpty());
60*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetSettings(), IsEmpty());
61*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, decoder.settings_frame_count());
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,ParseSettingsAndAcceptChFrames)64*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, ParseSettingsAndAcceptChFrames) {
65*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
66*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error = decoder.Decode(HexDecode(
67*6777b538SAndroid Build Coastguard Worker       // ACCEPT_CH frame
68*6777b538SAndroid Build Coastguard Worker       "00003d"                    // length
69*6777b538SAndroid Build Coastguard Worker       "89"                        // type ACCEPT_CH
70*6777b538SAndroid Build Coastguard Worker       "00"                        // flags
71*6777b538SAndroid Build Coastguard Worker       "00000000"                  // stream ID
72*6777b538SAndroid Build Coastguard Worker       "0017"                      // origin length
73*6777b538SAndroid Build Coastguard Worker       "68747470733a2f2f7777772e"  //
74*6777b538SAndroid Build Coastguard Worker       "6578616d706c652e636f6d"    // origin "https://www.example.com"
75*6777b538SAndroid Build Coastguard Worker       "0003"                      // value length
76*6777b538SAndroid Build Coastguard Worker       "666f6f"                    // value "foo"
77*6777b538SAndroid Build Coastguard Worker       "0018"                      // origin length
78*6777b538SAndroid Build Coastguard Worker       "68747470733a2f2f6d61696c"  //
79*6777b538SAndroid Build Coastguard Worker       "2e6578616d706c652e636f6d"  // origin "https://mail.example.com"
80*6777b538SAndroid Build Coastguard Worker       "0003"                      // value length
81*6777b538SAndroid Build Coastguard Worker       "626172"                    // value "bar"
82*6777b538SAndroid Build Coastguard Worker       // SETTINGS frame
83*6777b538SAndroid Build Coastguard Worker       "00000c"       // length
84*6777b538SAndroid Build Coastguard Worker       "04"           // type
85*6777b538SAndroid Build Coastguard Worker       "00"           // flags
86*6777b538SAndroid Build Coastguard Worker       "00000000"     // stream ID
87*6777b538SAndroid Build Coastguard Worker       "0dab"         // identifier
88*6777b538SAndroid Build Coastguard Worker       "01020304"     // value
89*6777b538SAndroid Build Coastguard Worker       "1234"         // identifier
90*6777b538SAndroid Build Coastguard Worker       "fedcba98"));  // value
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
93*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
94*6777b538SAndroid Build Coastguard Worker       decoder.GetAcceptCh(),
95*6777b538SAndroid Build Coastguard Worker       ElementsAre(AcceptChOriginValuePair{"https://www.example.com", "foo"},
96*6777b538SAndroid Build Coastguard Worker                   AcceptChOriginValuePair{"https://mail.example.com", "bar"}));
97*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetSettings(),
98*6777b538SAndroid Build Coastguard Worker               ElementsAre(Pair(0x0dab, 0x01020304), Pair(0x1234, 0xfedcba98)));
99*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, decoder.settings_frame_count());
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,ParseLargeAcceptChFrame)102*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, ParseLargeAcceptChFrame) {
103*6777b538SAndroid Build Coastguard Worker   std::string frame = HexDecode(
104*6777b538SAndroid Build Coastguard Worker       // ACCEPT_CH frame
105*6777b538SAndroid Build Coastguard Worker       "0001ab"                    // length: 427 total bytes
106*6777b538SAndroid Build Coastguard Worker       "89"                        // type ACCEPT_CH
107*6777b538SAndroid Build Coastguard Worker       "00"                        // flags
108*6777b538SAndroid Build Coastguard Worker       "00000000"                  // stream ID
109*6777b538SAndroid Build Coastguard Worker       "0017"                      // origin length
110*6777b538SAndroid Build Coastguard Worker       "68747470733a2f2f7777772e"  //
111*6777b538SAndroid Build Coastguard Worker       "6578616d706c652e636f6d"    // origin "https://www.example.com"
112*6777b538SAndroid Build Coastguard Worker       "0190"                      // value length (400 in hex)
113*6777b538SAndroid Build Coastguard Worker   );
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   // The Accept-CH tokens payload is a string of 400 'x' characters.
116*6777b538SAndroid Build Coastguard Worker   const std::string accept_ch_tokens(400, 'x');
117*6777b538SAndroid Build Coastguard Worker   // Append the value bytes to the frame.
118*6777b538SAndroid Build Coastguard Worker   frame += accept_ch_tokens;
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
121*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error = decoder.Decode(frame);
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
124*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetAcceptCh(),
125*6777b538SAndroid Build Coastguard Worker               ElementsAre(AcceptChOriginValuePair{"https://www.example.com",
126*6777b538SAndroid Build Coastguard Worker                                                   accept_ch_tokens}));
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,DisableAlpsParsing)129*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, DisableAlpsParsing) {
130*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list;
131*6777b538SAndroid Build Coastguard Worker   feature_list.InitAndDisableFeature(features::kAlpsParsing);
132*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
133*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error = decoder.Decode(HexDecode(
134*6777b538SAndroid Build Coastguard Worker       // ACCEPT_CH frame
135*6777b538SAndroid Build Coastguard Worker       "00003d"                    // length
136*6777b538SAndroid Build Coastguard Worker       "89"                        // type ACCEPT_CH
137*6777b538SAndroid Build Coastguard Worker       "00"                        // flags
138*6777b538SAndroid Build Coastguard Worker       "00000000"                  // stream ID
139*6777b538SAndroid Build Coastguard Worker       "0017"                      // origin length
140*6777b538SAndroid Build Coastguard Worker       "68747470733a2f2f7777772e"  //
141*6777b538SAndroid Build Coastguard Worker       "6578616d706c652e636f6d"    // origin "https://www.example.com"
142*6777b538SAndroid Build Coastguard Worker       "0003"                      // value length
143*6777b538SAndroid Build Coastguard Worker       "666f6f"                    // value "foo"
144*6777b538SAndroid Build Coastguard Worker       "0018"                      // origin length
145*6777b538SAndroid Build Coastguard Worker       "68747470733a2f2f6d61696c"  //
146*6777b538SAndroid Build Coastguard Worker       "2e6578616d706c652e636f6d"  // origin "https://mail.example.com"
147*6777b538SAndroid Build Coastguard Worker       "0003"                      // value length
148*6777b538SAndroid Build Coastguard Worker       "626172"                    // value "bar"
149*6777b538SAndroid Build Coastguard Worker       ));
150*6777b538SAndroid Build Coastguard Worker 
151*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
152*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetAcceptCh(), IsEmpty());
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,DisableAlpsClientHintParsing)155*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, DisableAlpsClientHintParsing) {
156*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list;
157*6777b538SAndroid Build Coastguard Worker   feature_list.InitAndDisableFeature(features::kAlpsClientHintParsing);
158*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
159*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error = decoder.Decode(HexDecode(
160*6777b538SAndroid Build Coastguard Worker       // ACCEPT_CH frame
161*6777b538SAndroid Build Coastguard Worker       "00003d"                    // length
162*6777b538SAndroid Build Coastguard Worker       "89"                        // type ACCEPT_CH
163*6777b538SAndroid Build Coastguard Worker       "00"                        // flags
164*6777b538SAndroid Build Coastguard Worker       "00000000"                  // stream ID
165*6777b538SAndroid Build Coastguard Worker       "0017"                      // origin length
166*6777b538SAndroid Build Coastguard Worker       "68747470733a2f2f7777772e"  //
167*6777b538SAndroid Build Coastguard Worker       "6578616d706c652e636f6d"    // origin "https://www.example.com"
168*6777b538SAndroid Build Coastguard Worker       "0003"                      // value length
169*6777b538SAndroid Build Coastguard Worker       "666f6f"                    // value "foo"
170*6777b538SAndroid Build Coastguard Worker       "0018"                      // origin length
171*6777b538SAndroid Build Coastguard Worker       "68747470733a2f2f6d61696c"  //
172*6777b538SAndroid Build Coastguard Worker       "2e6578616d706c652e636f6d"  // origin "https://mail.example.com"
173*6777b538SAndroid Build Coastguard Worker       "0003"                      // value length
174*6777b538SAndroid Build Coastguard Worker       "626172"                    // value "bar"
175*6777b538SAndroid Build Coastguard Worker       ));
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
178*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetAcceptCh(), IsEmpty());
179*6777b538SAndroid Build Coastguard Worker }
180*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,IncompleteFrame)181*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, IncompleteFrame) {
182*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
183*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
184*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("00000c"    // length
185*6777b538SAndroid Build Coastguard Worker                                "04"        // type
186*6777b538SAndroid Build Coastguard Worker                                "00"        // flags
187*6777b538SAndroid Build Coastguard Worker                                "00000000"  // stream ID
188*6777b538SAndroid Build Coastguard Worker                                "0dab"      // identifier
189*6777b538SAndroid Build Coastguard Worker                                "01"));     // first byte of value
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNotOnFrameBoundary, error);
192*6777b538SAndroid Build Coastguard Worker }
193*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,TwoSettingsFrames)194*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, TwoSettingsFrames) {
195*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
196*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
197*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("000006"       // length
198*6777b538SAndroid Build Coastguard Worker                                "04"           // type SETTINGS
199*6777b538SAndroid Build Coastguard Worker                                "00"           // flags
200*6777b538SAndroid Build Coastguard Worker                                "00000000"     // stream ID
201*6777b538SAndroid Build Coastguard Worker                                "0dab"         // identifier
202*6777b538SAndroid Build Coastguard Worker                                "01020304"     // value
203*6777b538SAndroid Build Coastguard Worker                                "000006"       // length
204*6777b538SAndroid Build Coastguard Worker                                "04"           // type SETTINGS
205*6777b538SAndroid Build Coastguard Worker                                "00"           // flags
206*6777b538SAndroid Build Coastguard Worker                                "00000000"     // stream ID
207*6777b538SAndroid Build Coastguard Worker                                "1234"         // identifier
208*6777b538SAndroid Build Coastguard Worker                                "fedcba98"));  // value
209*6777b538SAndroid Build Coastguard Worker 
210*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
211*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, decoder.settings_frame_count());
212*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetSettings(),
213*6777b538SAndroid Build Coastguard Worker               ElementsAre(Pair(0x0dab, 0x01020304), Pair(0x1234, 0xfedcba98)));
214*6777b538SAndroid Build Coastguard Worker }
215*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,AcceptChOnInvalidStream)216*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, AcceptChOnInvalidStream) {
217*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
218*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error = decoder.Decode(
219*6777b538SAndroid Build Coastguard Worker       HexDecode("00001e"                    // length
220*6777b538SAndroid Build Coastguard Worker                 "89"                        // type ACCEPT_CH
221*6777b538SAndroid Build Coastguard Worker                 "00"                        // flags
222*6777b538SAndroid Build Coastguard Worker                 "00000001"                  // invalid stream ID: should be zero
223*6777b538SAndroid Build Coastguard Worker                 "0017"                      // origin length
224*6777b538SAndroid Build Coastguard Worker                 "68747470733a2f2f7777772e"  //
225*6777b538SAndroid Build Coastguard Worker                 "6578616d706c652e636f6d"    // origin "https://www.example.com"
226*6777b538SAndroid Build Coastguard Worker                 "0003"                      // value length
227*6777b538SAndroid Build Coastguard Worker                 "666f6f"));                 // value "foo"
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kAcceptChInvalidStream, error);
230*6777b538SAndroid Build Coastguard Worker }
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker // According to
233*6777b538SAndroid Build Coastguard Worker // https://davidben.github.io/http-client-hint-reliability/ \
234*6777b538SAndroid Build Coastguard Worker // draft-davidben-http-client-hint-reliability.html#name-http-2-accept_ch-frame
235*6777b538SAndroid Build Coastguard Worker // "If a user agent receives an ACCEPT_CH frame whose stream [...] flags
236*6777b538SAndroid Build Coastguard Worker // field is non-zero, it MUST respond with a connection error [...]."
TEST(AlpsDecoderTest,AcceptChWithInvalidFlags)237*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, AcceptChWithInvalidFlags) {
238*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
239*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error = decoder.Decode(
240*6777b538SAndroid Build Coastguard Worker       HexDecode("00001e"                    // length
241*6777b538SAndroid Build Coastguard Worker                 "89"                        // type ACCEPT_CH
242*6777b538SAndroid Build Coastguard Worker                 "02"                        // invalid flags: should be zero
243*6777b538SAndroid Build Coastguard Worker                 "00000000"                  // stream ID
244*6777b538SAndroid Build Coastguard Worker                 "0017"                      // origin length
245*6777b538SAndroid Build Coastguard Worker                 "68747470733a2f2f7777772e"  //
246*6777b538SAndroid Build Coastguard Worker                 "6578616d706c652e636f6d"    // origin "https://www.example.com"
247*6777b538SAndroid Build Coastguard Worker                 "0003"                      // value length
248*6777b538SAndroid Build Coastguard Worker                 "666f6f"));                 // value "foo"
249*6777b538SAndroid Build Coastguard Worker 
250*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kAcceptChWithFlags, error);
251*6777b538SAndroid Build Coastguard Worker }
252*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,SettingsOnInvalidStream)253*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, SettingsOnInvalidStream) {
254*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
255*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
256*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("000006"    // length
257*6777b538SAndroid Build Coastguard Worker                                "04"        // type SETTINGS
258*6777b538SAndroid Build Coastguard Worker                                "00"        // flags
259*6777b538SAndroid Build Coastguard Worker                                "00000001"  // invalid stream ID: should be zero
260*6777b538SAndroid Build Coastguard Worker                                "1234"      // identifier
261*6777b538SAndroid Build Coastguard Worker                                "fedcba98"));  // value
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kFramingError, error);
264*6777b538SAndroid Build Coastguard Worker }
265*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,SettingsAck)266*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, SettingsAck) {
267*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
268*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
269*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("000000"       // length
270*6777b538SAndroid Build Coastguard Worker                                "04"           // type SETTINGS
271*6777b538SAndroid Build Coastguard Worker                                "01"           // ACK flag
272*6777b538SAndroid Build Coastguard Worker                                "00000000"));  // stream ID
273*6777b538SAndroid Build Coastguard Worker 
274*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kSettingsWithAck, error);
275*6777b538SAndroid Build Coastguard Worker }
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker // According to https://httpwg.org/specs/rfc7540.html#FrameHeader:
278*6777b538SAndroid Build Coastguard Worker // "Flags that have no defined semantics for a particular frame type MUST be
279*6777b538SAndroid Build Coastguard Worker // ignored [...]"
TEST(AlpsDecoderTest,SettingsWithInvalidFlags)280*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, SettingsWithInvalidFlags) {
281*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
282*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
283*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("000006"       // length
284*6777b538SAndroid Build Coastguard Worker                                "04"           // type SETTINGS
285*6777b538SAndroid Build Coastguard Worker                                "02"           // invalid flag
286*6777b538SAndroid Build Coastguard Worker                                "00000000"     // stream ID
287*6777b538SAndroid Build Coastguard Worker                                "1234"         // identifier
288*6777b538SAndroid Build Coastguard Worker                                "fedcba98"));  // value
289*6777b538SAndroid Build Coastguard Worker 
290*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
291*6777b538SAndroid Build Coastguard Worker }
292*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,ForbiddenFrame)293*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, ForbiddenFrame) {
294*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
295*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
296*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("000003"     // length
297*6777b538SAndroid Build Coastguard Worker                                "00"         // frame type DATA
298*6777b538SAndroid Build Coastguard Worker                                "01"         // flags END_STREAM
299*6777b538SAndroid Build Coastguard Worker                                "00000001"   // stream ID
300*6777b538SAndroid Build Coastguard Worker                                "666f6f"));  // payload "foo"
301*6777b538SAndroid Build Coastguard Worker 
302*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kForbiddenFrame, error);
303*6777b538SAndroid Build Coastguard Worker }
304*6777b538SAndroid Build Coastguard Worker 
TEST(AlpsDecoderTest,UnknownFrame)305*6777b538SAndroid Build Coastguard Worker TEST(AlpsDecoderTest, UnknownFrame) {
306*6777b538SAndroid Build Coastguard Worker   AlpsDecoder decoder;
307*6777b538SAndroid Build Coastguard Worker   AlpsDecoder::Error error =
308*6777b538SAndroid Build Coastguard Worker       decoder.Decode(HexDecode("000003"     // length
309*6777b538SAndroid Build Coastguard Worker                                "2a"         // unknown frame type
310*6777b538SAndroid Build Coastguard Worker                                "ff"         // flags
311*6777b538SAndroid Build Coastguard Worker                                "00000008"   // stream ID
312*6777b538SAndroid Build Coastguard Worker                                "666f6f"));  // payload "foo"
313*6777b538SAndroid Build Coastguard Worker 
314*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
315*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetAcceptCh(), IsEmpty());
316*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(decoder.GetSettings(), IsEmpty());
317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, decoder.settings_frame_count());
318*6777b538SAndroid Build Coastguard Worker }
319*6777b538SAndroid Build Coastguard Worker 
320*6777b538SAndroid Build Coastguard Worker class AlpsDecoderTestWithFeature : public ::testing::TestWithParam<bool> {
321*6777b538SAndroid Build Coastguard Worker  public:
ShouldKillSessionOnAcceptChMalformed()322*6777b538SAndroid Build Coastguard Worker   bool ShouldKillSessionOnAcceptChMalformed() { return GetParam(); }
323*6777b538SAndroid Build Coastguard Worker 
324*6777b538SAndroid Build Coastguard Worker  private:
SetUp()325*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
326*6777b538SAndroid Build Coastguard Worker     feature_list_.InitWithFeatureState(
327*6777b538SAndroid Build Coastguard Worker         features::kShouldKillSessionOnAcceptChMalformed,
328*6777b538SAndroid Build Coastguard Worker         ShouldKillSessionOnAcceptChMalformed());
329*6777b538SAndroid Build Coastguard Worker   }
330*6777b538SAndroid Build Coastguard Worker 
331*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList feature_list_;
332*6777b538SAndroid Build Coastguard Worker };
333*6777b538SAndroid Build Coastguard Worker 
334*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All, AlpsDecoderTestWithFeature, testing::Bool());
335*6777b538SAndroid Build Coastguard Worker 
TEST_P(AlpsDecoderTestWithFeature,MalformedAcceptChFrame)336*6777b538SAndroid Build Coastguard Worker TEST_P(AlpsDecoderTestWithFeature, MalformedAcceptChFrame) {
337*6777b538SAndroid Build Coastguard Worker   // Correct, complete payload.
338*6777b538SAndroid Build Coastguard Worker   std::string payload = HexDecode(
339*6777b538SAndroid Build Coastguard Worker       "0017"  // origin length
340*6777b538SAndroid Build Coastguard Worker       "68747470733a2f2f7777772e"
341*6777b538SAndroid Build Coastguard Worker       "6578616d706c652e636f6d"  // origin "https://www.example.com"
342*6777b538SAndroid Build Coastguard Worker       "0003"                    // value length
343*6777b538SAndroid Build Coastguard Worker       "666f6f");                // value "foo"
344*6777b538SAndroid Build Coastguard Worker 
345*6777b538SAndroid Build Coastguard Worker   for (uint8_t payload_length = 1; payload_length < payload.length();
346*6777b538SAndroid Build Coastguard Worker        payload_length++) {
347*6777b538SAndroid Build Coastguard Worker     base::HistogramTester histogram_tester;
348*6777b538SAndroid Build Coastguard Worker     // First two bytes of length.
349*6777b538SAndroid Build Coastguard Worker     std::string frame = HexDecode("0000");
350*6777b538SAndroid Build Coastguard Worker     // Last byte of length.
351*6777b538SAndroid Build Coastguard Worker     frame.push_back(static_cast<char>(payload_length));
352*6777b538SAndroid Build Coastguard Worker 
353*6777b538SAndroid Build Coastguard Worker     frame.append(
354*6777b538SAndroid Build Coastguard Worker         HexDecode("89"           // type ACCEPT_CH
355*6777b538SAndroid Build Coastguard Worker                   "00"           // flags
356*6777b538SAndroid Build Coastguard Worker                   "00000000"));  // stream ID
357*6777b538SAndroid Build Coastguard Worker     // Incomplete, malformed payload.
358*6777b538SAndroid Build Coastguard Worker     frame.append(payload.data(), payload_length);
359*6777b538SAndroid Build Coastguard Worker 
360*6777b538SAndroid Build Coastguard Worker     AlpsDecoder decoder;
361*6777b538SAndroid Build Coastguard Worker     AlpsDecoder::Error error = decoder.Decode(frame);
362*6777b538SAndroid Build Coastguard Worker     if (ShouldKillSessionOnAcceptChMalformed()) {
363*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(AlpsDecoder::Error::kAcceptChMalformed, error);
364*6777b538SAndroid Build Coastguard Worker       histogram_tester.ExpectUniqueSample(
365*6777b538SAndroid Build Coastguard Worker           "Net.SpdySession.AlpsDecoderStatus.Bypassed",
366*6777b538SAndroid Build Coastguard Worker           static_cast<int>(AlpsDecoder::Error::kNoError), 1);
367*6777b538SAndroid Build Coastguard Worker     } else {
368*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(AlpsDecoder::Error::kNoError, error);
369*6777b538SAndroid Build Coastguard Worker       histogram_tester.ExpectUniqueSample(
370*6777b538SAndroid Build Coastguard Worker           "Net.SpdySession.AlpsDecoderStatus.Bypassed",
371*6777b538SAndroid Build Coastguard Worker           static_cast<int>(AlpsDecoder::Error::kAcceptChMalformed), 1);
372*6777b538SAndroid Build Coastguard Worker     }
373*6777b538SAndroid Build Coastguard Worker   }
374*6777b538SAndroid Build Coastguard Worker }
375*6777b538SAndroid Build Coastguard Worker 
376*6777b538SAndroid Build Coastguard Worker }  // namespace
377*6777b538SAndroid Build Coastguard Worker }  // namespace net
378