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