Add ACCEPT_CH HTTP/3 frame type struct; add HttpFramesTest. PiperOrigin-RevId: 345227858 Change-Id: I7368e52b7ba70c59d40c79f62f9d5ac1465a405f
diff --git a/quic/core/http/http_frames.h b/quic/core/http/http_frames.h index ed7ad2c..4959879 100644 --- a/quic/core/http/http_frames.h +++ b/quic/core/http/http_frames.h
@@ -5,9 +5,11 @@ #ifndef QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_ #define QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_ +#include <algorithm> #include <cstdint> #include <map> #include <ostream> +#include <sstream> #include "absl/strings/string_view.h" #include "net/third_party/quiche/src/quic/core/http/spdy_utils.h" @@ -28,6 +30,8 @@ MAX_PUSH_ID = 0xD, // https://tools.ietf.org/html/draft-ietf-httpbis-priority-01 PRIORITY_UPDATE = 0XF, + // https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02 + ACCEPT_CH = 0x89, // https://tools.ietf.org/html/draft-ietf-httpbis-priority-02 PRIORITY_UPDATE_REQUEST_STREAM = 0xF0700, }; @@ -176,6 +180,42 @@ } }; +// ACCEPT_CH +// https://tools.ietf.org/html/draft-davidben-http-client-hint-reliability-02 +// +struct QUIC_EXPORT_PRIVATE AcceptChFrame { + struct QUIC_EXPORT_PRIVATE OriginValuePair { + std::string origin; + std::string value; + bool operator==(const OriginValuePair& rhs) const { + return origin == rhs.origin && value == rhs.value; + } + }; + + std::vector<OriginValuePair> entries; + + bool operator==(const AcceptChFrame& rhs) const { + return entries.size() == rhs.entries.size() && + std::equal(entries.begin(), entries.end(), rhs.entries.begin()); + } + + std::string ToString() const { + std::stringstream s; + s << *this; + return s.str(); + } + + friend QUIC_EXPORT_PRIVATE std::ostream& operator<<( + std::ostream& os, + const AcceptChFrame& frame) { + os << "ACCEPT_CH frame with " << frame.entries.size() << " entries: "; + for (auto& entry : frame.entries) { + os << "origin: " << entry.origin << "; value: " << entry.value; + } + return os; + } +}; + } // namespace quic #endif // QUICHE_QUIC_CORE_HTTP_HTTP_FRAMES_H_
diff --git a/quic/core/http/http_frames_test.cc b/quic/core/http/http_frames_test.cc new file mode 100644 index 0000000..d2027c6 --- /dev/null +++ b/quic/core/http/http_frames_test.cc
@@ -0,0 +1,131 @@ +// Copyright (c) 2020 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 "net/third_party/quiche/src/quic/core/http/http_frames.h" + +#include <sstream> + +#include "net/third_party/quiche/src/quic/core/http/http_constants.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" + +namespace quic { +namespace test { + +TEST(HttpFramesTest, CancelPushFrame) { + CancelPushFrame a{1}; + EXPECT_TRUE(a == a); + + CancelPushFrame b{1}; + EXPECT_TRUE(a == b); + + b.push_id = 2; + EXPECT_FALSE(a == b); +} + +TEST(HttpFramesTest, SettingsFrame) { + SettingsFrame a; + EXPECT_TRUE(a == a); + EXPECT_EQ("", a.ToString()); + + SettingsFrame b; + b.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1; + EXPECT_FALSE(a == b); + EXPECT_TRUE(b == b); + + a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2; + EXPECT_FALSE(a == b); + a.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 1; + EXPECT_TRUE(a == b); + + EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", b.ToString()); + std::stringstream s; + s << b; + EXPECT_EQ("SETTINGS_QPACK_MAX_TABLE_CAPACITY = 1; ", s.str()); +} + +TEST(HttpFramesTest, PushPromiseFrame) { + PushPromiseFrame a{1, ""}; + EXPECT_TRUE(a == a); + + PushPromiseFrame b{2, ""}; + EXPECT_FALSE(a == b); + + b.push_id = 1; + EXPECT_TRUE(a == b); + + b.headers = "foo"; + EXPECT_FALSE(a == b); + EXPECT_TRUE(b == b); +} + +TEST(HttpFramesTest, GoAwayFrame) { + GoAwayFrame a{1}; + EXPECT_TRUE(a == a); + + GoAwayFrame b{2}; + EXPECT_FALSE(a == b); + + b.id = 1; + EXPECT_TRUE(a == b); +} + +TEST(HttpFramesTest, MaxPushIdFrame) { + MaxPushIdFrame a{1}; + EXPECT_TRUE(a == a); + + MaxPushIdFrame b{2}; + EXPECT_FALSE(a == b); + + b.push_id = 1; + EXPECT_TRUE(a == b); +} + +TEST(HttpFramesTest, PriorityUpdateFrame) { + PriorityUpdateFrame a{REQUEST_STREAM, 0, ""}; + EXPECT_TRUE(a == a); + PriorityUpdateFrame b{REQUEST_STREAM, 4, ""}; + EXPECT_FALSE(a == b); + a.prioritized_element_id = 4; + EXPECT_TRUE(a == b); + + a.prioritized_element_type = PUSH_STREAM; + EXPECT_FALSE(a == b); + b.prioritized_element_type = PUSH_STREAM; + EXPECT_TRUE(a == b); + + a.priority_field_value = "foo"; + EXPECT_FALSE(a == b); + + EXPECT_EQ( + "Priority Frame : {prioritized_element_type: 128, " + "prioritized_element_id: 4, priority_field_value: foo}", + a.ToString()); + std::stringstream s; + s << a; + EXPECT_EQ( + "Priority Frame : {prioritized_element_type: 128, " + "prioritized_element_id: 4, priority_field_value: foo}", + s.str()); +} + +TEST(HttpFramesTest, AcceptChFrame) { + AcceptChFrame a; + EXPECT_TRUE(a == a); + EXPECT_EQ("ACCEPT_CH frame with 0 entries: ", a.ToString()); + + AcceptChFrame b{{{"foo", "bar"}}}; + EXPECT_FALSE(a == b); + + a.entries.push_back({"foo", "bar"}); + EXPECT_TRUE(a == b); + + EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar", + a.ToString()); + std::stringstream s; + s << a; + EXPECT_EQ("ACCEPT_CH frame with 1 entries: origin: foo; value: bar", s.str()); +} + +} // namespace test +} // namespace quic