@@ -38,8 +38,9 @@ TEST(Request, HasVariableChecksHeaders) {
3838 EXPECT_TRUE (r.hasVariable (" Host" ));
3939 EXPECT_TRUE (r.hasVariable (" X-Test" ));
4040 EXPECT_FALSE (r.hasVariable (" Missing" ));
41- // Map is case-sensitive on the contained keys.
42- EXPECT_FALSE (r.hasVariable (" host" ));
41+ // Header names are case-insensitive (RFC 7230 3.2).
42+ EXPECT_TRUE (r.hasVariable (" host" ));
43+ EXPECT_TRUE (r.hasVariable (" x-test" ));
4344}
4445
4546TEST (Request, ReadHeaderReturnsValueOrEmpty) {
@@ -49,6 +50,17 @@ TEST(Request, ReadHeaderReturnsValueOrEmpty) {
4950 EXPECT_EQ (r.readHeader (" Missing" ), " " );
5051}
5152
53+ TEST (Request, ReadHeaderIsCaseInsensitive) {
54+ // Clients send the legacy credential header as either `password` or
55+ // `Password` (e.g. Go's net/http canonicalizes to `Password`); both must
56+ // resolve to the same value. See session_manager_interface::is_logged_in.
57+ const Request::headers_type h{{" Password" , " secret" }};
58+ const auto r = make_request (" GET" , " /" , " " , h);
59+ EXPECT_EQ (r.readHeader (" password" ), " secret" );
60+ EXPECT_EQ (r.readHeader (" Password" ), " secret" );
61+ EXPECT_EQ (r.readHeader (" PASSWORD" ), " secret" );
62+ }
63+
5264TEST (Request, ReadHeaderDoesNotMutateHeaders) {
5365 const Request::headers_type h{{" Host" , " example.com" }};
5466 auto r = make_request (" GET" , " /" , " " , h);
0 commit comments