Send the path and query parameters of QuicTransport URL in the client indication.
gfe-relnote: n/a (not used in production)
PiperOrigin-RevId: 283837693
Change-Id: I14d5de3a8da4af3af2ee7c00e07ac3feaa4e39f9
diff --git a/quic/quic_transport/quic_transport_client_session.cc b/quic/quic_transport/quic_transport_client_session.cc
index f0110b7..e9487ec 100644
--- a/quic/quic_transport/quic_transport_client_session.cc
+++ b/quic/quic_transport/quic_transport_client_session.cc
@@ -43,7 +43,7 @@
Visitor* owner,
const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
- const QuicServerId& server_id,
+ const GURL& url,
QuicCryptoClientConfig* crypto_config,
url::Origin origin,
ClientVisitor* visitor)
@@ -52,6 +52,7 @@
config,
supported_versions,
/*num_expected_unidirectional_static_streams*/ 0),
+ url_(url),
origin_(origin),
visitor_(visitor) {
for (const ParsedQuicVersion& version : supported_versions) {
@@ -61,8 +62,9 @@
// ProofHandler API is not used by TLS 1.3.
static DummyProofHandler* proof_handler = new DummyProofHandler();
crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
- server_id, this, crypto_config->proof_verifier()->CreateDefaultContext(),
- crypto_config, proof_handler);
+ QuicServerId(url.host(), url.EffectiveIntPort()), this,
+ crypto_config->proof_verifier()->CreateDefaultContext(), crypto_config,
+ proof_handler);
}
QuicStream* QuicTransportClientSession::CreateIncomingStream(QuicStreamId id) {
@@ -153,16 +155,40 @@
QUIC_DLOG(INFO) << "Sending client indication with origin "
<< serialized_origin;
- std::string buffer;
- buffer.resize(/* key */ sizeof(QuicTransportClientIndicationKeys) +
- /* length */ sizeof(uint16_t) + serialized_origin.size());
- QuicDataWriter writer(buffer.size(), &buffer[0]);
- writer.WriteUInt16(
- static_cast<uint16_t>(QuicTransportClientIndicationKeys::kOrigin));
- writer.WriteUInt16(serialized_origin.size());
- writer.WriteStringPiece(serialized_origin);
+ std::string path = url_.PathForRequest();
+ if (path.size() > std::numeric_limits<uint16_t>::max()) {
+ connection()->CloseConnection(
+ QUIC_TRANSPORT_INVALID_CLIENT_INDICATION, "Requested URL path too long",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return "";
+ }
- buffer.resize(writer.length());
+ constexpr size_t kPrefixSize =
+ sizeof(QuicTransportClientIndicationKeys) + sizeof(uint16_t);
+ const size_t buffer_size =
+ 2 * kPrefixSize + serialized_origin.size() + path.size();
+ if (buffer_size > std::numeric_limits<uint16_t>::max()) {
+ connection()->CloseConnection(
+ QUIC_TRANSPORT_INVALID_CLIENT_INDICATION,
+ "Client indication size limit exceeded",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+ return "";
+ }
+
+ std::string buffer;
+ buffer.resize(buffer_size);
+ QuicDataWriter writer(buffer.size(), &buffer[0]);
+ bool success =
+ writer.WriteUInt16(
+ static_cast<uint16_t>(QuicTransportClientIndicationKeys::kOrigin)) &&
+ writer.WriteUInt16(serialized_origin.size()) &&
+ writer.WriteStringPiece(serialized_origin) &&
+ writer.WriteUInt16(
+ static_cast<uint16_t>(QuicTransportClientIndicationKeys::kPath)) &&
+ writer.WriteUInt16(path.size()) && writer.WriteStringPiece(path);
+ QUIC_BUG_IF(!success) << "Failed to serialize client indication";
+ QUIC_BUG_IF(writer.length() != buffer.length())
+ << "Serialized client indication has length different from expected";
return buffer;
}
diff --git a/quic/quic_transport/quic_transport_client_session.h b/quic/quic_transport/quic_transport_client_session.h
index 5872bf1..b3d8f17 100644
--- a/quic/quic_transport/quic_transport_client_session.h
+++ b/quic/quic_transport/quic_transport_client_session.h
@@ -8,6 +8,7 @@
#include <cstdint>
#include <memory>
+#include "url/gurl.h"
#include "url/origin.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
#include "net/third_party/quiche/src/quic/core/quic_config.h"
@@ -47,7 +48,7 @@
Visitor* owner,
const QuicConfig& config,
const ParsedQuicVersionVector& supported_versions,
- const QuicServerId& server_id,
+ const GURL& url,
QuicCryptoClientConfig* crypto_config,
url::Origin origin,
ClientVisitor* visitor);
@@ -116,6 +117,7 @@
void SendClientIndication();
std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
+ GURL url_;
url::Origin origin_;
ClientVisitor* visitor_; // not owned
bool client_indication_sent_ = false;
diff --git a/quic/quic_transport/quic_transport_client_session_test.cc b/quic/quic_transport/quic_transport_client_session_test.cc
index 53213a4..17a4757 100644
--- a/quic/quic_transport/quic_transport_client_session_test.cc
+++ b/quic/quic_transport/quic_transport_client_session_test.cc
@@ -30,8 +30,6 @@
using testing::ElementsAre;
const char* kTestOrigin = "https://test-origin.test";
-constexpr char kTestOriginClientIndication[] =
- "\0\0\0\x18https://test-origin.test";
url::Origin GetTestOrigin() {
GURL origin_url(kTestOrigin);
return url::Origin::Create(origin_url);
@@ -58,15 +56,15 @@
&alarm_factory_,
Perspective::IS_CLIENT,
GetVersions()),
- server_id_("test.example.com", 443),
crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
SetQuicReloadableFlag(quic_supports_tls_handshake, true);
- CreateSession(GetTestOrigin());
+ CreateSession(GetTestOrigin(), "");
}
- void CreateSession(url::Origin origin) {
+ void CreateSession(url::Origin origin, std::string url_suffix) {
session_ = std::make_unique<QuicTransportClientSession>(
- &connection_, nullptr, DefaultQuicConfig(), GetVersions(), server_id_,
+ &connection_, nullptr, DefaultQuicConfig(), GetVersions(),
+ GURL("quic-transport://test.example.com:50000" + url_suffix),
&crypto_config_, origin, &visitor_);
session_->Initialize();
crypto_stream_ = static_cast<QuicCryptoClientStream*>(
@@ -87,7 +85,6 @@
MockQuicConnectionHelper helper_;
PacketSavingConnection connection_;
- QuicServerId server_id_;
QuicCryptoClientConfig crypto_config_;
MockClientVisitor visitor_;
std::unique_ptr<QuicTransportClientSession> session_;
@@ -99,6 +96,39 @@
}
TEST_F(QuicTransportClientSessionTest, SuccessfulConnection) {
+ constexpr char kTestOriginClientIndication[] =
+ "\0\0" // key (0x0000, origin)
+ "\0\x18" // length
+ "https://test-origin.test" // value
+ "\0\x01" // key (0x0001, path)
+ "\0\x01" // length
+ "/"; // value
+
+ Connect();
+ EXPECT_TRUE(session_->IsSessionReady());
+
+ QuicStream* client_indication_stream =
+ QuicSessionPeer::zombie_streams(session_.get())[ClientIndicationStream()]
+ .get();
+ ASSERT_TRUE(client_indication_stream != nullptr);
+ const std::string client_indication = DataInStream(client_indication_stream);
+ const std::string expected_client_indication{
+ kTestOriginClientIndication,
+ QUIC_ARRAYSIZE(kTestOriginClientIndication) - 1};
+ EXPECT_EQ(client_indication, expected_client_indication);
+}
+
+TEST_F(QuicTransportClientSessionTest, SuccessfulConnectionWithPath) {
+ constexpr char kSuffix[] = "/foo/bar?hello=world#not-sent";
+ constexpr char kTestOriginClientIndication[] =
+ "\0\0" // key (0x0000, origin)
+ "\0\x18" // length
+ "https://test-origin.test" // value
+ "\0\x01" // key (0x0001, path)
+ "\0\x14" // length
+ "/foo/bar?hello=world"; // value
+
+ CreateSession(GetTestOrigin(), kSuffix);
Connect();
EXPECT_TRUE(session_->IsSessionReady());
@@ -117,7 +147,7 @@
std::string long_string(68000, 'a');
GURL bad_origin_url{"https://" + long_string + ".example/"};
EXPECT_TRUE(bad_origin_url.is_valid());
- CreateSession(url::Origin::Create(bad_origin_url));
+ CreateSession(url::Origin::Create(bad_origin_url), "");
EXPECT_QUIC_BUG(Connect(), "Client origin too long");
}
diff --git a/quic/quic_transport/quic_transport_integration_test.cc b/quic/quic_transport/quic_transport_integration_test.cc
index 715bd9f..57f5380 100644
--- a/quic/quic_transport/quic_transport_integration_test.cc
+++ b/quic/quic_transport/quic_transport_integration_test.cc
@@ -80,7 +80,7 @@
nullptr,
DefaultQuicConfig(),
GetVersions(),
- QuicServerId("test.example.com", 443),
+ GURL("quic-transport://test.example.com:50000"),
&crypto_config_,
origin,
&visitor_) {
diff --git a/quic/quic_transport/quic_transport_protocol.h b/quic/quic_transport/quic_transport_protocol.h
index 47ed877..f97b8e7 100644
--- a/quic/quic_transport/quic_transport_protocol.h
+++ b/quic/quic_transport/quic_transport_protocol.h
@@ -29,6 +29,7 @@
// The keys of the fields in the client indication.
enum class QuicTransportClientIndicationKeys : uint16_t {
kOrigin = 0x0000,
+ kPath = 0x0001,
};
} // namespace quic