Upon receiving SETTINGS for a QuicSpdyClientSession, serialize the frame and cache it in tls_client_handshaker.
gfe-relnote: unused code. not protected.
PiperOrigin-RevId: 306897017
Change-Id: I94fbf706b7c9846befb80b1363a79dc022e95828
diff --git a/quic/core/crypto/quic_crypto_client_config.h b/quic/core/crypto/quic_crypto_client_config.h
index 3ae19dd..b4675de 100644
--- a/quic/core/crypto/quic_crypto_client_config.h
+++ b/quic/core/crypto/quic_crypto_client_config.h
@@ -71,7 +71,7 @@
virtual void Insert(const QuicServerId& server_id,
bssl::UniquePtr<SSL_SESSION> session,
TransportParameters* params,
- std::vector<uint8_t>* application_states) = 0;
+ ApplicationState* application_states) = 0;
// Lookup is called once at the beginning of each TLS handshake to potentially
// provide the saved state both for the TLS handshake and for sending 0-RTT
diff --git a/quic/core/http/quic_spdy_client_session_base.cc b/quic/core/http/quic_spdy_client_session_base.cc
index a0c70dd..2655259 100644
--- a/quic/core/http/quic_spdy_client_session_base.cc
+++ b/quic/core/http/quic_spdy_client_session_base.cc
@@ -222,4 +222,15 @@
return !HasActiveRequestStreams() && promised_by_id_.empty();
}
+void QuicSpdyClientSessionBase::OnSettingsFrame(const SettingsFrame& frame) {
+ QuicSpdySession::OnSettingsFrame(frame);
+ std::unique_ptr<char[]> buffer;
+ QuicByteCount frame_length =
+ HttpEncoder::SerializeSettingsFrame(frame, &buffer);
+ auto serialized_data = std::make_unique<ApplicationState>(
+ buffer.get(), buffer.get() + frame_length);
+ static_cast<QuicCryptoClientStreamBase*>(GetMutableCryptoStream())
+ ->OnApplicationState(std::move(serialized_data));
+}
+
} // namespace quic
diff --git a/quic/core/http/quic_spdy_client_session_base.h b/quic/core/http/quic_spdy_client_session_base.h
index 7d4ba01..9d702e3 100644
--- a/quic/core/http/quic_spdy_client_session_base.h
+++ b/quic/core/http/quic_spdy_client_session_base.h
@@ -117,6 +117,9 @@
return push_promise_index_;
}
+ // Override to serialize the settings and pass it down to the handshaker.
+ void OnSettingsFrame(const SettingsFrame& frame) override;
+
private:
// For QuicSpdyClientStream to detect that a response corresponds to a
// promise.
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index f702671..65dd43a 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -11,9 +11,12 @@
#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
+#include "net/third_party/quiche/src/quic/core/http/http_frames.h"
#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
#include "net/third_party/quiche/src/quic/core/http/spdy_server_push_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
+#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
@@ -27,6 +30,7 @@
#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
@@ -81,11 +85,14 @@
class QuicSpdyClientSessionTest : public QuicTestWithParam<ParsedQuicVersion> {
protected:
QuicSpdyClientSessionTest()
- : crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
- promised_stream_id_(
+ : promised_stream_id_(
QuicUtils::GetInvalidStreamId(GetParam().transport_version)),
associated_stream_id_(
QuicUtils::GetInvalidStreamId(GetParam().transport_version)) {
+ auto client_cache = std::make_unique<test::SimpleSessionCache>();
+ client_session_cache_ = client_cache.get();
+ crypto_config_ = std::make_unique<QuicCryptoClientConfig>(
+ crypto_test_utils::ProofVerifierForTesting(), std::move(client_cache));
Initialize();
// Advance the time, because timers do not like uninitialized times.
connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -103,7 +110,7 @@
SupportedVersions(GetParam()));
session_ = std::make_unique<TestQuicSpdyClientSession>(
DefaultQuicConfig(), SupportedVersions(GetParam()), connection_,
- QuicServerId(kServerHostname, kPort, false), &crypto_config_,
+ QuicServerId(kServerHostname, kPort, false), crypto_config_.get(),
&push_promise_index_);
session_->Initialize();
push_promise_[":path"] = "/bar";
@@ -171,7 +178,7 @@
stream, AlpnForVersion(connection_->version()));
}
- QuicCryptoClientConfig crypto_config_;
+ std::unique_ptr<QuicCryptoClientConfig> crypto_config_;
MockQuicConnectionHelper helper_;
MockAlarmFactory alarm_factory_;
PacketSavingConnection* connection_;
@@ -181,6 +188,7 @@
std::string promise_url_;
QuicStreamId promised_stream_id_;
QuicStreamId associated_stream_id_;
+ test::SimpleSessionCache* client_session_cache_;
};
INSTANTIATE_TEST_SUITE_P(Tests,
@@ -940,6 +948,43 @@
}
}
+// Test that upon receiving HTTP/3 SETTINGS, the settings are serialized and
+// stored into client session cache.
+TEST_P(QuicSpdyClientSessionTest, OnSettingsFrame) {
+ // This feature is HTTP/3 only
+ if (!VersionUsesHttp3(session_->transport_version())) {
+ return;
+ }
+ CompleteCryptoHandshake();
+ SettingsFrame settings;
+ settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+ settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
+ settings.values[256] = 4; // unknown setting
+ char application_state[] = {// type (SETTINGS)
+ 0x04,
+ // length
+ 0x07,
+ // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
+ 0x01,
+ // content
+ 0x02,
+ // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
+ 0x06,
+ // content
+ 0x05,
+ // identifier (256 in variable length integer)
+ 0x40 + 0x01, 0x00,
+ // content
+ 0x04};
+ ApplicationState expected(std::begin(application_state),
+ std::end(application_state));
+ session_->OnSettingsFrame(settings);
+ EXPECT_EQ(expected,
+ *client_session_cache_
+ ->Lookup(QuicServerId(kServerHostname, kPort, false), nullptr)
+ ->application_state);
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
index f6dd0a7..2ab8637 100644
--- a/quic/core/http/quic_spdy_session.cc
+++ b/quic/core/http/quic_spdy_session.cc
@@ -873,6 +873,7 @@
}
void QuicSpdySession::OnSettingsFrame(const SettingsFrame& frame) {
+ DCHECK(VersionUsesHttp3(transport_version()));
if (debug_visitor_ != nullptr) {
debug_visitor_->OnSettingsFrameReceived(frame);
}
diff --git a/quic/core/http/quic_spdy_session.h b/quic/core/http/quic_spdy_session.h
index 29eca32..d641d51 100644
--- a/quic/core/http/quic_spdy_session.h
+++ b/quic/core/http/quic_spdy_session.h
@@ -247,7 +247,7 @@
bool server_push_enabled() const;
// Called when the control stream receives HTTP/3 SETTINGS.
- void OnSettingsFrame(const SettingsFrame& frame);
+ virtual void OnSettingsFrame(const SettingsFrame& frame);
// Called when a setting is parsed from an incoming SETTINGS frame.
void OnSetting(uint64_t id, uint64_t value);
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index baac324..9e9e214 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -520,6 +520,11 @@
void TlsClientHandshaker::OnApplicationState(
std::unique_ptr<ApplicationState> application_state) {
received_application_state_ = std::move(application_state);
+ if (session_cache_ != nullptr) {
+ // TODO(renjietang): cache the TLS session ticket and insert them together.
+ session_cache_->Insert(server_id_, nullptr, nullptr,
+ received_application_state_.get());
+ }
}
} // namespace quic