Add a new ExtractQuicVersionFromAltSvcEntry method to SpdyUtils for parsing QUIC versions out of Alt-Svc entries. Will be used in both Chrome and Envoy.
PiperOrigin-RevId: 427540864
diff --git a/quic/core/http/spdy_utils.cc b/quic/core/http/spdy_utils.cc
index 74c9c53..5b74407 100644
--- a/quic/core/http/spdy_utils.cc
+++ b/quic/core/http/spdy_utils.cc
@@ -13,6 +13,7 @@
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
+#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_flag_utils.h"
#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_logging.h"
@@ -194,4 +195,23 @@
(*headers)["datagram-flow-id"] = absl::StrCat(flow_id);
}
+// static
+ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ const spdy::SpdyAltSvcWireFormat::AlternativeService&
+ alternative_service_entry,
+ const ParsedQuicVersionVector& supported_versions) {
+ for (const ParsedQuicVersion& version : supported_versions) {
+ if (version.AlpnDeferToRFCv1()) {
+ // Versions with share an ALPN with v1 are currently unable to be
+ // advertised with Alt-Svc.
+ continue;
+ }
+ if (AlpnForVersion(version) == alternative_service_entry.protocol_id) {
+ return version;
+ }
+ }
+
+ return ParsedQuicVersion::Unsupported();
+}
+
} // namespace quic
diff --git a/quic/core/http/spdy_utils.h b/quic/core/http/spdy_utils.h
index 01fae4f..85099ab 100644
--- a/quic/core/http/spdy_utils.h
+++ b/quic/core/http/spdy_utils.h
@@ -14,6 +14,7 @@
#include "quic/core/http/quic_header_list.h"
#include "quic/core/quic_packets.h"
#include "quic/platform/api/quic_export.h"
+#include "spdy/core/spdy_alt_svc_wire_format.h"
#include "spdy/core/spdy_header_block.h"
namespace quic {
@@ -61,6 +62,14 @@
// Adds the "datagram-flow-id" header.
static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers,
QuicDatagramStreamId flow_id);
+
+ // Returns the advertised QUIC version from the specified alternative service
+ // advertisement, or ParsedQuicVersion::Unsupported() if no supported version
+ // is advertised.
+ static ParsedQuicVersion ExtractQuicVersionFromAltSvcEntry(
+ const spdy::SpdyAltSvcWireFormat::AlternativeService&
+ alternative_service_entry,
+ const ParsedQuicVersionVector& supported_versions);
};
} // namespace quic
diff --git a/quic/core/http/spdy_utils_test.cc b/quic/core/http/spdy_utils_test.cc
index 918739d..85c5cec 100644
--- a/quic/core/http/spdy_utils_test.cc
+++ b/quic/core/http/spdy_utils_test.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "quic/core/http/spdy_utils.h"
+
#include <memory>
#include <string>
#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
-#include "quic/core/http/spdy_utils.h"
+#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_test.h"
using spdy::SpdyHeaderBlock;
@@ -408,5 +410,33 @@
ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42);
}
+using ExtractQuicVersionFromAltSvcEntry = QuicTest;
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) {
+ ParsedQuicVersionVector supported_versions = AllSupportedVersions();
+ spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+ for (const ParsedQuicVersion& version : supported_versions) {
+ entry.protocol_id = AlpnForVersion(version);
+ ParsedQuicVersion expected_version = version;
+ // Versions with share an ALPN with v1 are currently unable to be
+ // advertised with Alt-Svc.
+ if (entry.protocol_id == AlpnForVersion(ParsedQuicVersion::RFCv1()) &&
+ version != ParsedQuicVersion::RFCv1()) {
+ expected_version = ParsedQuicVersion::RFCv1();
+ }
+ EXPECT_EQ(expected_version, SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ entry, supported_versions))
+ << "version: " << version;
+ }
+}
+
+TEST_F(ExtractQuicVersionFromAltSvcEntry, UnsupportedVersion) {
+ spdy::SpdyAltSvcWireFormat::AlternativeService entry;
+ entry.protocol_id = "quic";
+ EXPECT_EQ(ParsedQuicVersion::Unsupported(),
+ SpdyUtils::ExtractQuicVersionFromAltSvcEntry(
+ entry, AllSupportedVersions()));
+}
+
} // namespace test
} // namespace quic