| // Copyright 2023 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "quiche/web_transport/web_transport_headers.h" | |
| #include "absl/status/status.h" | |
| #include "quiche/common/platform/api/quiche_test.h" | |
| #include "quiche/common/test_tools/quiche_test_utils.h" | |
| namespace webtransport { | |
| namespace { | |
| using ::quiche::test::IsOkAndHolds; | |
| using ::quiche::test::StatusIs; | |
| using ::testing::ElementsAre; | |
| using ::testing::HasSubstr; | |
| TEST(WebTransportHeaders, ParseSubprotocolRequestHeader) { | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("test"), | |
| IsOkAndHolds(ElementsAre("test"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("moqt-draft01, moqt-draft02"), | |
| IsOkAndHolds(ElementsAre("moqt-draft01", "moqt-draft02"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("moqt-draft01; a=b, moqt-draft02"), | |
| IsOkAndHolds(ElementsAre("moqt-draft01", "moqt-draft02"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("moqt-draft01, moqt-draft02; a=b"), | |
| IsOkAndHolds(ElementsAre("moqt-draft01", "moqt-draft02"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("\"test\""), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found string instead"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("42"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found integer instead"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("a, (b)"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found a nested list instead"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("a, (b c)"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found a nested list instead"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("foo, ?1, bar"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found boolean instead"))); | |
| EXPECT_THAT(ParseSubprotocolRequestHeader("(a"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("parse the header as an sf-list"))); | |
| } | |
| TEST(WebTransportHeaders, SerializeSubprotocolRequestHeader) { | |
| EXPECT_THAT(SerializeSubprotocolRequestHeader({"test"}), | |
| IsOkAndHolds("test")); | |
| EXPECT_THAT(SerializeSubprotocolRequestHeader({"foo", "bar"}), | |
| IsOkAndHolds("foo, bar")); | |
| EXPECT_THAT(SerializeSubprotocolRequestHeader({"moqt-draft01", "a/b/c"}), | |
| IsOkAndHolds("moqt-draft01, a/b/c")); | |
| EXPECT_THAT( | |
| SerializeSubprotocolRequestHeader({"abcd", "0123", "efgh"}), | |
| StatusIs(absl::StatusCode::kInvalidArgument, "Invalid token: 0123")); | |
| } | |
| TEST(WebTransportHeader, ParseSubprotocolResponseHeader) { | |
| EXPECT_THAT(ParseSubprotocolResponseHeader("foo"), IsOkAndHolds("foo")); | |
| EXPECT_THAT(ParseSubprotocolResponseHeader("foo; a=b"), IsOkAndHolds("foo")); | |
| EXPECT_THAT( | |
| ParseSubprotocolResponseHeader("1234"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("found integer"))); | |
| EXPECT_THAT( | |
| ParseSubprotocolResponseHeader("(a"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("parse sf-item"))); | |
| } | |
| TEST(WebTransportHeader, SerializeSubprotocolResponseHeader) { | |
| EXPECT_THAT(SerializeSubprotocolResponseHeader("foo"), IsOkAndHolds("foo")); | |
| EXPECT_THAT(SerializeSubprotocolResponseHeader("moqt-draft01"), | |
| IsOkAndHolds("moqt-draft01")); | |
| EXPECT_THAT(SerializeSubprotocolResponseHeader("123abc"), | |
| StatusIs(absl::StatusCode::kInvalidArgument)); | |
| } | |
| TEST(WebTransportHeader, ParseInitHeader) { | |
| WebTransportInitHeader expected_header; | |
| expected_header.initial_unidi_limit = 100; | |
| expected_header.initial_incoming_bidi_limit = 200; | |
| expected_header.initial_outgoing_bidi_limit = 400; | |
| EXPECT_THAT(ParseInitHeader("br=400, bl=200, u=100"), | |
| IsOkAndHolds(expected_header)); | |
| EXPECT_THAT(ParseInitHeader("br=300, bl=200, u=100, br=400"), | |
| IsOkAndHolds(expected_header)); | |
| EXPECT_THAT(ParseInitHeader("br=400, bl=200; foo=bar, u=100"), | |
| IsOkAndHolds(expected_header)); | |
| EXPECT_THAT(ParseInitHeader("br=400, bl=200, u=100.0"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found decimal instead"))); | |
| EXPECT_THAT(ParseInitHeader("br=400, bl=200, u=?1"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found boolean instead"))); | |
| EXPECT_THAT(ParseInitHeader("br=400, bl=200, u=(a b)"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found a nested list instead"))); | |
| EXPECT_THAT(ParseInitHeader("br=400, bl=200, u=:abcd:"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("found byte sequence instead"))); | |
| EXPECT_THAT(ParseInitHeader("br=400, bl=200, u=-1"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("negative value"))); | |
| EXPECT_THAT(ParseInitHeader("br=400, bl=200, u=18446744073709551615"), | |
| StatusIs(absl::StatusCode::kInvalidArgument, | |
| HasSubstr("Failed to parse"))); | |
| } | |
| TEST(WebTransportHeaders, SerializeInitHeader) { | |
| EXPECT_THAT(SerializeInitHeader(WebTransportInitHeader{}), | |
| IsOkAndHolds("u=0, bl=0, br=0")); | |
| WebTransportInitHeader test_header; | |
| test_header.initial_unidi_limit = 100; | |
| test_header.initial_incoming_bidi_limit = 200; | |
| test_header.initial_outgoing_bidi_limit = 400; | |
| EXPECT_THAT(SerializeInitHeader(test_header), | |
| IsOkAndHolds("u=100, bl=200, br=400")); | |
| } | |
| } // namespace | |
| } // namespace webtransport |