No public description
PiperOrigin-RevId: 661382575
diff --git a/quiche/quic/core/http/http_frames.h b/quiche/quic/core/http/http_frames.h
index 645f5c0..3aac2ef 100644
--- a/quiche/quic/core/http/http_frames.h
+++ b/quiche/quic/core/http/http_frames.h
@@ -112,6 +112,21 @@
bool operator==(const OriginFrame& rhs) const {
return origins == rhs.origins;
}
+
+ std::string ToString() const {
+ std::string result = "Origin Frame: {origins: ";
+ for (const std::string& origin : origins) {
+ absl::StrAppend(&result, "\n", origin);
+ }
+ result += "}";
+ return result;
+ }
+
+ friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
+ const OriginFrame& s) {
+ os << s.ToString();
+ return os;
+ }
};
// https://httpwg.org/http-extensions/draft-ietf-httpbis-priority.html
diff --git a/quiche/quic/core/http/quic_send_control_stream.cc b/quiche/quic/core/http/quic_send_control_stream.cc
index 9c328aa..76c4442 100644
--- a/quiche/quic/core/http/quic_send_control_stream.cc
+++ b/quiche/quic/core/http/quic_send_control_stream.cc
@@ -28,6 +28,7 @@
const SettingsFrame& settings)
: QuicStream(id, spdy_session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
settings_sent_(false),
+ origin_frame_sent_(false),
settings_(settings),
spdy_session_(spdy_session) {}
@@ -86,6 +87,20 @@
nullptr);
}
+void QuicSendControlStream::MaybeSendOriginFrame(
+ std::vector<std::string> origins) {
+ if (origins.empty() || origin_frame_sent_) {
+ return;
+ }
+ OriginFrame frame;
+ frame.origins = std::move(origins);
+ QUIC_DVLOG(1) << "Control stream " << id() << " is writing origin frame "
+ << frame;
+ WriteOrBufferData(HttpEncoder::SerializeOriginFrame(frame), /*fin =*/false,
+ nullptr);
+ origin_frame_sent_ = true;
+}
+
void QuicSendControlStream::WritePriorityUpdate(QuicStreamId stream_id,
HttpStreamPriority priority) {
QuicConnection::ScopedPacketFlusher flusher(session()->connection());
diff --git a/quiche/quic/core/http/quic_send_control_stream.h b/quiche/quic/core/http/quic_send_control_stream.h
index ea6b0f8..7c2f45e 100644
--- a/quiche/quic/core/http/quic_send_control_stream.h
+++ b/quiche/quic/core/http/quic_send_control_stream.h
@@ -38,6 +38,9 @@
// first frame sent on this stream.
void MaybeSendSettingsFrame();
+ // Send ORIGIN frame if |origins| is not empty.
+ void MaybeSendOriginFrame(std::vector<std::string> origins);
+
// Send a PRIORITY_UPDATE frame on this stream, and a SETTINGS frame
// beforehand if one has not been already sent.
void WritePriorityUpdate(QuicStreamId stream_id, HttpStreamPriority priority);
@@ -54,6 +57,9 @@
// Track if a settings frame is already sent.
bool settings_sent_;
+ // Track if an origin frame is already sent.
+ bool origin_frame_sent_;
+
// SETTINGS values to send.
const SettingsFrame settings_;
diff --git a/quiche/quic/core/http/quic_send_control_stream_test.cc b/quiche/quic/core/http/quic_send_control_stream_test.cc
index 02b7cc2..fabeb1b 100644
--- a/quiche/quic/core/http/quic_send_control_stream_test.cc
+++ b/quiche/quic/core/http/quic_send_control_stream_test.cc
@@ -245,6 +245,16 @@
send_control_stream_->MaybeSendSettingsFrame();
}
+TEST_P(QuicSendControlStreamTest, SendOriginFrameOnce) {
+ Initialize();
+ std::vector<std::string> origins = {"a", "b", "c"};
+
+ EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _))
+ .Times(1);
+ send_control_stream_->MaybeSendOriginFrame(origins);
+ send_control_stream_->MaybeSendOriginFrame(origins);
+}
+
// Send stream type and SETTINGS frame if WritePriorityUpdate() is called first.
TEST_P(QuicSendControlStreamTest, WritePriorityBeforeSettings) {
Initialize();
diff --git a/quiche/quic/core/http/quic_spdy_session.cc b/quiche/quic/core/http/quic_spdy_session.cc
index f84b30b..8c81b3c 100644
--- a/quiche/quic/core/http/quic_spdy_session.cc
+++ b/quiche/quic/core/http/quic_spdy_session.cc
@@ -869,6 +869,7 @@
}
QuicConnection::ScopedPacketFlusher flusher(connection());
send_control_stream_->MaybeSendSettingsFrame();
+ SendInitialDataAfterSettings();
}
bool QuicSpdySession::CheckStreamWriteBlocked(QuicStream* stream) const {
diff --git a/quiche/quic/core/http/quic_spdy_session.h b/quiche/quic/core/http/quic_spdy_session.h
index a6e4e1a..d56c99d 100644
--- a/quiche/quic/core/http/quic_spdy_session.h
+++ b/quiche/quic/core/http/quic_spdy_session.h
@@ -561,6 +561,9 @@
// available.
void SendInitialData();
+ // Sends any data which should be sent after the initial SETTINGS frame.
+ virtual void SendInitialDataAfterSettings() {}
+
// Override to skip checking for qpack_decoder_send_stream_ given decoder data
// is always bundled opportunistically.
bool CheckStreamWriteBlocked(QuicStream* stream) const override;
@@ -575,6 +578,8 @@
cookie_crumbling_ = CookieCrumbling::kDisabled;
}
+ QuicSendControlStream* send_control_stream() { return send_control_stream_; }
+
private:
friend class test::QuicSpdySessionPeer;