xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/noop_header_validator_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #include "quiche/http2/adapter/noop_header_validator.h"
2 
3 #include <optional>
4 #include <utility>
5 #include <vector>
6 
7 #include "absl/strings/str_cat.h"
8 #include "quiche/common/platform/api/quiche_test.h"
9 
10 namespace http2 {
11 namespace adapter {
12 namespace test {
13 
14 using ::testing::Optional;
15 
16 using Header = std::pair<absl::string_view, absl::string_view>;
17 constexpr Header kSampleRequestPseudoheaders[] = {{":authority", "www.foo.com"},
18                                                   {":method", "GET"},
19                                                   {":path", "/foo"},
20                                                   {":scheme", "https"}};
21 
TEST(NoopHeaderValidatorTest,HeaderNameEmpty)22 TEST(NoopHeaderValidatorTest, HeaderNameEmpty) {
23   NoopHeaderValidator v;
24   NoopHeaderValidator::HeaderStatus status =
25       v.ValidateSingleHeader("", "value");
26   EXPECT_EQ(NoopHeaderValidator::HEADER_OK, status);
27 }
28 
TEST(NoopHeaderValidatorTest,HeaderValueEmpty)29 TEST(NoopHeaderValidatorTest, HeaderValueEmpty) {
30   NoopHeaderValidator v;
31   NoopHeaderValidator::HeaderStatus status = v.ValidateSingleHeader("name", "");
32   EXPECT_EQ(NoopHeaderValidator::HEADER_OK, status);
33 }
34 
TEST(NoopHeaderValidatorTest,ExceedsMaxSize)35 TEST(NoopHeaderValidatorTest, ExceedsMaxSize) {
36   NoopHeaderValidator v;
37   v.SetMaxFieldSize(64u);
38   NoopHeaderValidator::HeaderStatus status =
39       v.ValidateSingleHeader("name", "value");
40   EXPECT_EQ(NoopHeaderValidator::HEADER_OK, status);
41   status = v.ValidateSingleHeader(
42       "name2",
43       "Antidisestablishmentariansism is supercalifragilisticexpialodocious.");
44   EXPECT_EQ(NoopHeaderValidator::HEADER_OK, status);
45 }
46 
TEST(NoopHeaderValidatorTest,AnyNameCharIsValid)47 TEST(NoopHeaderValidatorTest, AnyNameCharIsValid) {
48   NoopHeaderValidator v;
49   char pseudo_name[] = ":met hod";
50   char name[] = "na me";
51   for (int i = std::numeric_limits<char>::min();
52        i < std::numeric_limits<char>::max(); ++i) {
53     char c = static_cast<char>(i);
54     // Test a pseudo-header name with this char.
55     pseudo_name[3] = c;
56     auto sv = absl::string_view(pseudo_name, 8);
57     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
58               v.ValidateSingleHeader(sv, "value"));
59     // Test a regular header name with this char.
60     name[2] = c;
61     sv = absl::string_view(name, 5);
62     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
63               v.ValidateSingleHeader(sv, "value"));
64   }
65 }
66 
TEST(NoopHeaderValidatorTest,AnyValueCharIsValid)67 TEST(NoopHeaderValidatorTest, AnyValueCharIsValid) {
68   NoopHeaderValidator v;
69   char value[] = "val ue";
70   for (int i = std::numeric_limits<char>::min();
71        i < std::numeric_limits<char>::max(); ++i) {
72     char c = static_cast<char>(i);
73     value[3] = c;
74     auto sv = absl::string_view(value, 6);
75     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
76               v.ValidateSingleHeader("name", sv));
77   }
78 }
79 
TEST(NoopHeaderValidatorTest,AnyStatusIsValid)80 TEST(NoopHeaderValidatorTest, AnyStatusIsValid) {
81   NoopHeaderValidator v;
82 
83   for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
84     v.StartHeaderBlock();
85     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
86               v.ValidateSingleHeader(":status", "bar"));
87     EXPECT_TRUE(v.FinishHeaderBlock(type));
88 
89     v.StartHeaderBlock();
90     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
91               v.ValidateSingleHeader(":status", "10"));
92     EXPECT_TRUE(v.FinishHeaderBlock(type));
93 
94     v.StartHeaderBlock();
95     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
96               v.ValidateSingleHeader(":status", "9000"));
97     EXPECT_TRUE(v.FinishHeaderBlock(type));
98 
99     v.StartHeaderBlock();
100     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
101               v.ValidateSingleHeader(":status", "400"));
102     EXPECT_TRUE(v.FinishHeaderBlock(type));
103   }
104 }
105 
TEST(NoopHeaderValidatorTest,AnyAuthorityCharIsValid)106 TEST(NoopHeaderValidatorTest, AnyAuthorityCharIsValid) {
107   char value[] = "ho st.example.com";
108   for (int i = std::numeric_limits<char>::min();
109        i < std::numeric_limits<char>::max(); ++i) {
110     char c = static_cast<char>(i);
111     value[2] = c;
112     auto sv = absl::string_view(value, 17);
113     for (absl::string_view key : {":authority", "host"}) {
114       NoopHeaderValidator v;
115       v.StartHeaderBlock();
116       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
117                 v.ValidateSingleHeader(key, sv));
118     }
119   }
120 }
121 
TEST(NoopHeaderValidatorTest,RequestHostAndAuthority)122 TEST(NoopHeaderValidatorTest, RequestHostAndAuthority) {
123   NoopHeaderValidator v;
124   v.StartHeaderBlock();
125   for (Header to_add : kSampleRequestPseudoheaders) {
126     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
127               v.ValidateSingleHeader(to_add.first, to_add.second));
128   }
129   // If both "host" and ":authority" have the same value, validation succeeds.
130   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
131             v.ValidateSingleHeader("host", "www.foo.com"));
132   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
133 
134   v.StartHeaderBlock();
135   for (Header to_add : kSampleRequestPseudoheaders) {
136     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
137               v.ValidateSingleHeader(to_add.first, to_add.second));
138   }
139   // If "host" and ":authority" have different values, validation still
140   // succeeds.
141   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
142             v.ValidateSingleHeader("host", "www.bar.com"));
143 }
144 
TEST(NoopHeaderValidatorTest,RequestPseudoHeaders)145 TEST(NoopHeaderValidatorTest, RequestPseudoHeaders) {
146   NoopHeaderValidator v;
147   for (Header to_skip : kSampleRequestPseudoheaders) {
148     v.StartHeaderBlock();
149     for (Header to_add : kSampleRequestPseudoheaders) {
150       if (to_add != to_skip) {
151         EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
152                   v.ValidateSingleHeader(to_add.first, to_add.second));
153       }
154     }
155     // Even if a pseudo-header is missing, final validation will succeed.
156     EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
157   }
158 
159   // When all pseudo-headers are present, final validation will succeed.
160   v.StartHeaderBlock();
161   for (Header to_add : kSampleRequestPseudoheaders) {
162     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
163               v.ValidateSingleHeader(to_add.first, to_add.second));
164   }
165   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
166 
167   // When an extra pseudo-header is present, final validation will still
168   // succeed.
169   v.StartHeaderBlock();
170   for (Header to_add : kSampleRequestPseudoheaders) {
171     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
172               v.ValidateSingleHeader(to_add.first, to_add.second));
173   }
174   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
175             v.ValidateSingleHeader(":extra", "blah"));
176   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
177 
178   // When a required pseudo-header is repeated, final validation will succeed.
179   for (Header to_repeat : kSampleRequestPseudoheaders) {
180     v.StartHeaderBlock();
181     for (Header to_add : kSampleRequestPseudoheaders) {
182       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
183                 v.ValidateSingleHeader(to_add.first, to_add.second));
184       if (to_add == to_repeat) {
185         EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
186                   v.ValidateSingleHeader(to_add.first, to_add.second));
187       }
188     }
189     EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
190   }
191 }
192 
TEST(NoopHeaderValidatorTest,WebsocketPseudoHeaders)193 TEST(NoopHeaderValidatorTest, WebsocketPseudoHeaders) {
194   NoopHeaderValidator v;
195   v.StartHeaderBlock();
196   for (Header to_add : kSampleRequestPseudoheaders) {
197     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
198               v.ValidateSingleHeader(to_add.first, to_add.second));
199   }
200   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
201             v.ValidateSingleHeader(":protocol", "websocket"));
202   // Validation always succeeds.
203   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
204 
205   // This is a no-op for NoopHeaderValidator.
206   v.SetAllowExtendedConnect();
207 
208   v.StartHeaderBlock();
209   for (Header to_add : kSampleRequestPseudoheaders) {
210     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
211               v.ValidateSingleHeader(to_add.first, to_add.second));
212   }
213   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
214             v.ValidateSingleHeader(":protocol", "websocket"));
215   // The validator does not check for a CONNECT request.
216   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
217 
218   v.StartHeaderBlock();
219   for (Header to_add : kSampleRequestPseudoheaders) {
220     if (to_add.first == ":method") {
221       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
222                 v.ValidateSingleHeader(to_add.first, "CONNECT"));
223     } else {
224       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
225                 v.ValidateSingleHeader(to_add.first, to_add.second));
226     }
227   }
228   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
229             v.ValidateSingleHeader(":protocol", "websocket"));
230   // After allowing the method, `:protocol` is acepted for CONNECT requests.
231   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
232 }
233 
TEST(NoopHeaderValidatorTest,AsteriskPathPseudoHeader)234 TEST(NoopHeaderValidatorTest, AsteriskPathPseudoHeader) {
235   NoopHeaderValidator v;
236 
237   // The validator does not perform any path validation.
238   v.StartHeaderBlock();
239   for (Header to_add : kSampleRequestPseudoheaders) {
240     if (to_add.first == ":path") {
241       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
242                 v.ValidateSingleHeader(to_add.first, "*"));
243     } else {
244       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
245                 v.ValidateSingleHeader(to_add.first, to_add.second));
246     }
247   }
248   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
249 
250   v.StartHeaderBlock();
251   for (Header to_add : kSampleRequestPseudoheaders) {
252     if (to_add.first == ":path") {
253       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
254                 v.ValidateSingleHeader(to_add.first, "*"));
255     } else if (to_add.first == ":method") {
256       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
257                 v.ValidateSingleHeader(to_add.first, "OPTIONS"));
258     } else {
259       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
260                 v.ValidateSingleHeader(to_add.first, to_add.second));
261     }
262   }
263   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
264 }
265 
TEST(NoopHeaderValidatorTest,InvalidPathPseudoHeader)266 TEST(NoopHeaderValidatorTest, InvalidPathPseudoHeader) {
267   NoopHeaderValidator v;
268 
269   // An empty path is allowed.
270   v.StartHeaderBlock();
271   for (Header to_add : kSampleRequestPseudoheaders) {
272     if (to_add.first == ":path") {
273       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
274                 v.ValidateSingleHeader(to_add.first, ""));
275     } else {
276       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
277                 v.ValidateSingleHeader(to_add.first, to_add.second));
278     }
279   }
280   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
281 
282   // A path that does not start with a slash is allowed.
283   v.StartHeaderBlock();
284   for (Header to_add : kSampleRequestPseudoheaders) {
285     if (to_add.first == ":path") {
286       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
287                 v.ValidateSingleHeader(to_add.first, "shawarma"));
288     } else {
289       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
290                 v.ValidateSingleHeader(to_add.first, to_add.second));
291     }
292   }
293   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::REQUEST));
294 }
295 
TEST(NoopHeaderValidatorTest,ResponsePseudoHeaders)296 TEST(NoopHeaderValidatorTest, ResponsePseudoHeaders) {
297   NoopHeaderValidator v;
298 
299   for (HeaderType type : {HeaderType::RESPONSE, HeaderType::RESPONSE_100}) {
300     // When `:status` is missing, validation succeeds.
301     v.StartHeaderBlock();
302     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
303               v.ValidateSingleHeader("foo", "bar"));
304     EXPECT_TRUE(v.FinishHeaderBlock(type));
305 
306     // When all pseudo-headers are present, final validation succeeds.
307     v.StartHeaderBlock();
308     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
309               v.ValidateSingleHeader(":status", "199"));
310     EXPECT_TRUE(v.FinishHeaderBlock(type));
311     EXPECT_EQ("199", v.status_header());
312 
313     // When `:status` is repeated, validation succeeds.
314     v.StartHeaderBlock();
315     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
316               v.ValidateSingleHeader(":status", "199"));
317     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
318               v.ValidateSingleHeader(":status", "299"));
319     EXPECT_TRUE(v.FinishHeaderBlock(type));
320 
321     // When an extra pseudo-header is present, final validation succeeds.
322     v.StartHeaderBlock();
323     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
324               v.ValidateSingleHeader(":status", "199"));
325     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
326               v.ValidateSingleHeader(":extra", "blorp"));
327     EXPECT_TRUE(v.FinishHeaderBlock(type));
328   }
329 }
330 
TEST(NoopHeaderValidatorTest,ResponseWithHost)331 TEST(NoopHeaderValidatorTest, ResponseWithHost) {
332   NoopHeaderValidator v;
333 
334   v.StartHeaderBlock();
335   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
336             v.ValidateSingleHeader(":status", "200"));
337   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
338             v.ValidateSingleHeader("host", "myserver.com"));
339   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
340 }
341 
TEST(NoopHeaderValidatorTest,Response204)342 TEST(NoopHeaderValidatorTest, Response204) {
343   NoopHeaderValidator v;
344 
345   v.StartHeaderBlock();
346   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
347             v.ValidateSingleHeader(":status", "204"));
348   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
349             v.ValidateSingleHeader("x-content", "is not present"));
350   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
351 }
352 
TEST(NoopHeaderValidatorTest,ResponseWithMultipleIdenticalContentLength)353 TEST(NoopHeaderValidatorTest, ResponseWithMultipleIdenticalContentLength) {
354   NoopHeaderValidator v;
355 
356   v.StartHeaderBlock();
357   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
358             v.ValidateSingleHeader(":status", "200"));
359   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
360             v.ValidateSingleHeader("content-length", "13"));
361   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
362             v.ValidateSingleHeader("content-length", "13"));
363 }
364 
TEST(NoopHeaderValidatorTest,ResponseWithMultipleDifferingContentLength)365 TEST(NoopHeaderValidatorTest, ResponseWithMultipleDifferingContentLength) {
366   NoopHeaderValidator v;
367 
368   v.StartHeaderBlock();
369   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
370             v.ValidateSingleHeader(":status", "200"));
371   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
372             v.ValidateSingleHeader("content-length", "13"));
373   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
374             v.ValidateSingleHeader("content-length", "17"));
375 }
376 
TEST(NoopHeaderValidatorTest,Response204WithContentLengthZero)377 TEST(NoopHeaderValidatorTest, Response204WithContentLengthZero) {
378   NoopHeaderValidator v;
379 
380   v.StartHeaderBlock();
381   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
382             v.ValidateSingleHeader(":status", "204"));
383   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
384             v.ValidateSingleHeader("x-content", "is not present"));
385   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
386             v.ValidateSingleHeader("content-length", "0"));
387   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
388 }
389 
TEST(NoopHeaderValidatorTest,Response204WithContentLength)390 TEST(NoopHeaderValidatorTest, Response204WithContentLength) {
391   NoopHeaderValidator v;
392 
393   v.StartHeaderBlock();
394   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
395             v.ValidateSingleHeader(":status", "204"));
396   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
397             v.ValidateSingleHeader("x-content", "is not present"));
398   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
399             v.ValidateSingleHeader("content-length", "1"));
400 }
401 
TEST(NoopHeaderValidatorTest,Response100)402 TEST(NoopHeaderValidatorTest, Response100) {
403   NoopHeaderValidator v;
404 
405   v.StartHeaderBlock();
406   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
407             v.ValidateSingleHeader(":status", "100"));
408   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
409             v.ValidateSingleHeader("x-content", "is not present"));
410   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
411 }
412 
TEST(NoopHeaderValidatorTest,Response100WithContentLengthZero)413 TEST(NoopHeaderValidatorTest, Response100WithContentLengthZero) {
414   NoopHeaderValidator v;
415 
416   v.StartHeaderBlock();
417   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
418             v.ValidateSingleHeader(":status", "100"));
419   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
420             v.ValidateSingleHeader("x-content", "is not present"));
421   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
422             v.ValidateSingleHeader("content-length", "0"));
423   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE));
424 }
425 
TEST(NoopHeaderValidatorTest,Response100WithContentLength)426 TEST(NoopHeaderValidatorTest, Response100WithContentLength) {
427   NoopHeaderValidator v;
428 
429   v.StartHeaderBlock();
430   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
431             v.ValidateSingleHeader(":status", "100"));
432   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
433             v.ValidateSingleHeader("x-content", "is not present"));
434   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
435             v.ValidateSingleHeader("content-length", "1"));
436 }
437 
TEST(NoopHeaderValidatorTest,ResponseTrailerPseudoHeaders)438 TEST(NoopHeaderValidatorTest, ResponseTrailerPseudoHeaders) {
439   NoopHeaderValidator v;
440 
441   // When no pseudo-headers are present, validation will succeed.
442   v.StartHeaderBlock();
443   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
444             v.ValidateSingleHeader("foo", "bar"));
445   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));
446 
447   // When a pseudo-header is present, validation will succeed.
448   v.StartHeaderBlock();
449   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
450             v.ValidateSingleHeader(":status", "200"));
451   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
452             v.ValidateSingleHeader("foo", "bar"));
453   EXPECT_TRUE(v.FinishHeaderBlock(HeaderType::RESPONSE_TRAILER));
454 }
455 
TEST(NoopHeaderValidatorTest,ValidContentLength)456 TEST(NoopHeaderValidatorTest, ValidContentLength) {
457   NoopHeaderValidator v;
458 
459   v.StartHeaderBlock();
460   EXPECT_EQ(v.content_length(), std::nullopt);
461   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
462             v.ValidateSingleHeader("content-length", "41"));
463   EXPECT_EQ(v.content_length(), std::nullopt);
464 
465   v.StartHeaderBlock();
466   EXPECT_EQ(v.content_length(), std::nullopt);
467   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
468             v.ValidateSingleHeader("content-length", "42"));
469   EXPECT_EQ(v.content_length(), std::nullopt);
470 }
471 
TEST(NoopHeaderValidatorTest,InvalidContentLength)472 TEST(NoopHeaderValidatorTest, InvalidContentLength) {
473   NoopHeaderValidator v;
474 
475   v.StartHeaderBlock();
476   EXPECT_EQ(v.content_length(), std::nullopt);
477   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
478             v.ValidateSingleHeader("content-length", ""));
479   EXPECT_EQ(v.content_length(), std::nullopt);
480   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
481             v.ValidateSingleHeader("content-length", "nan"));
482   EXPECT_EQ(v.content_length(), std::nullopt);
483   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
484             v.ValidateSingleHeader("content-length", "-42"));
485   EXPECT_EQ(v.content_length(), std::nullopt);
486   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
487             v.ValidateSingleHeader("content-length", "42"));
488   EXPECT_EQ(v.content_length(), std::nullopt);
489 }
490 
TEST(NoopHeaderValidatorTest,TeHeader)491 TEST(NoopHeaderValidatorTest, TeHeader) {
492   NoopHeaderValidator v;
493 
494   v.StartHeaderBlock();
495   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
496             v.ValidateSingleHeader("te", "trailers"));
497 
498   v.StartHeaderBlock();
499   EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
500             v.ValidateSingleHeader("te", "trailers, deflate"));
501 }
502 
TEST(NoopHeaderValidatorTest,ConnectionSpecificHeaders)503 TEST(NoopHeaderValidatorTest, ConnectionSpecificHeaders) {
504   const std::vector<Header> connection_headers = {
505       {"connection", "keep-alive"}, {"proxy-connection", "keep-alive"},
506       {"keep-alive", "timeout=42"}, {"transfer-encoding", "chunked"},
507       {"upgrade", "h2c"},
508   };
509   for (const auto& [connection_key, connection_value] : connection_headers) {
510     NoopHeaderValidator v;
511     v.StartHeaderBlock();
512     for (const auto& [sample_key, sample_value] : kSampleRequestPseudoheaders) {
513       EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
514                 v.ValidateSingleHeader(sample_key, sample_value));
515     }
516     EXPECT_EQ(NoopHeaderValidator::HEADER_OK,
517               v.ValidateSingleHeader(connection_key, connection_value));
518   }
519 }
520 
521 }  // namespace test
522 }  // namespace adapter
523 }  // namespace http2
524