Fold QuicReceiveControlStream::HttpDecoderVisitor into QuicReceiveControlStream
to remove one layer of indirection.
gfe-relnote: n/a, refactor with no functional change.
PiperOrigin-RevId: 303780986
Change-Id: I2fc6c338967657ad8dd5a0db873694ffa3488a24
diff --git a/quic/core/http/quic_receive_control_stream.cc b/quic/core/http/quic_receive_control_stream.cc
index efd980f..4e361f2 100644
--- a/quic/core/http/quic_receive_control_stream.cc
+++ b/quic/core/http/quic_receive_control_stream.cc
@@ -15,171 +15,12 @@
namespace quic {
-// Visitor of HttpDecoder that passes data frame to QuicSpdyStream and closes
-// the connection on unexpected frames.
-class QuicReceiveControlStream::HttpDecoderVisitor
- : public HttpDecoder::Visitor {
- public:
- explicit HttpDecoderVisitor(QuicReceiveControlStream* stream)
- : stream_(stream) {}
- HttpDecoderVisitor(const HttpDecoderVisitor&) = delete;
- HttpDecoderVisitor& operator=(const HttpDecoderVisitor&) = delete;
-
- void OnError(HttpDecoder* decoder) override {
- stream_->OnUnrecoverableError(decoder->error(), decoder->error_detail());
- }
-
- bool OnCancelPushFrame(const CancelPushFrame& frame) override {
- if (stream_->spdy_session()->debug_visitor()) {
- stream_->spdy_session()->debug_visitor()->OnCancelPushFrameReceived(
- frame);
- }
-
- // TODO(b/151841240): Handle CANCEL_PUSH frames instead of ignoring them.
- return true;
- }
-
- bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) override {
- if (stream_->spdy_session()->debug_visitor()) {
- stream_->spdy_session()->debug_visitor()->OnMaxPushIdFrameReceived(frame);
- }
-
- if (stream_->spdy_session()->perspective() == Perspective::IS_CLIENT) {
- OnWrongFrame("Max Push Id");
- return false;
- }
-
- // TODO(b/124216424): Signal error if received push ID is smaller than a
- // previously received value.
- stream_->spdy_session()->OnMaxPushIdFrame(frame.push_id);
- return true;
- }
-
- bool OnGoAwayFrame(const GoAwayFrame& frame) override {
- // TODO(bnc): Check if SETTINGS frame has been received.
- if (stream_->spdy_session()->debug_visitor()) {
- stream_->spdy_session()->debug_visitor()->OnGoAwayFrameReceived(frame);
- }
-
- if (stream_->spdy_session()->perspective() == Perspective::IS_SERVER) {
- OnWrongFrame("Go Away");
- return false;
- }
-
- stream_->spdy_session()->OnHttp3GoAway(frame.stream_id);
- return true;
- }
-
- bool OnSettingsFrameStart(QuicByteCount header_length) override {
- return stream_->OnSettingsFrameStart(header_length);
- }
-
- bool OnSettingsFrame(const SettingsFrame& frame) override {
- return stream_->OnSettingsFrame(frame);
- }
-
- bool OnDataFrameStart(QuicByteCount /*header_length*/, QuicByteCount
- /*payload_length*/) override {
- OnWrongFrame("Data");
- return false;
- }
-
- bool OnDataFramePayload(quiche::QuicheStringPiece /*payload*/) override {
- OnWrongFrame("Data");
- return false;
- }
-
- bool OnDataFrameEnd() override {
- OnWrongFrame("Data");
- return false;
- }
-
- bool OnHeadersFrameStart(QuicByteCount /*header_length*/, QuicByteCount
- /*payload_length*/) override {
- OnWrongFrame("Headers");
- return false;
- }
-
- bool OnHeadersFramePayload(quiche::QuicheStringPiece /*payload*/) override {
- OnWrongFrame("Headers");
- return false;
- }
-
- bool OnHeadersFrameEnd() override {
- OnWrongFrame("Headers");
- return false;
- }
-
- bool OnPushPromiseFrameStart(QuicByteCount /*header_length*/) override {
- OnWrongFrame("Push Promise");
- return false;
- }
-
- bool OnPushPromiseFramePushId(
- PushId /*push_id*/,
- QuicByteCount /*push_id_length*/,
- QuicByteCount /*header_block_length*/) override {
- OnWrongFrame("Push Promise");
- return false;
- }
-
- bool OnPushPromiseFramePayload(
- quiche::QuicheStringPiece /*payload*/) override {
- OnWrongFrame("Push Promise");
- return false;
- }
-
- bool OnPushPromiseFrameEnd() override {
- OnWrongFrame("Push Promise");
- return false;
- }
-
- bool OnPriorityUpdateFrameStart(QuicByteCount header_length) override {
- return stream_->OnPriorityUpdateFrameStart(header_length);
- }
-
- bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) override {
- return stream_->OnPriorityUpdateFrame(frame);
- }
-
- bool OnUnknownFrameStart(uint64_t frame_type,
- QuicByteCount /* header_length */,
- QuicByteCount payload_length) override {
- if (stream_->spdy_session()->debug_visitor()) {
- stream_->spdy_session()->debug_visitor()->OnUnknownFrameReceived(
- stream_->id(), frame_type, payload_length);
- }
-
- return stream_->OnUnknownFrameStart();
- }
-
- bool OnUnknownFramePayload(quiche::QuicheStringPiece /* payload */) override {
- // Ignore unknown frame types.
- return true;
- }
-
- bool OnUnknownFrameEnd() override {
- // Ignore unknown frame types.
- return true;
- }
-
- private:
- void OnWrongFrame(quiche::QuicheStringPiece frame_type) {
- stream_->OnUnrecoverableError(
- QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
- quiche::QuicheStrCat(frame_type, " frame received on control stream"));
- }
-
- QuicReceiveControlStream* stream_;
-};
-
QuicReceiveControlStream::QuicReceiveControlStream(
PendingStream* pending,
QuicSpdySession* spdy_session)
: QuicStream(pending, READ_UNIDIRECTIONAL, /*is_static=*/true),
settings_frame_received_(false),
- http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
- decoder_(http_decoder_visitor_.get()),
+ decoder_(this),
spdy_session_(spdy_session) {
sequencer()->set_level_triggered(true);
}
@@ -213,8 +54,52 @@
}
}
+void QuicReceiveControlStream::OnError(HttpDecoder* decoder) {
+ OnUnrecoverableError(decoder->error(), decoder->error_detail());
+}
+
+bool QuicReceiveControlStream::OnCancelPushFrame(const CancelPushFrame& frame) {
+ if (spdy_session()->debug_visitor()) {
+ spdy_session()->debug_visitor()->OnCancelPushFrameReceived(frame);
+ }
+
+ // TODO(b/151841240): Handle CANCEL_PUSH frames instead of ignoring them.
+ return true;
+}
+
+bool QuicReceiveControlStream::OnMaxPushIdFrame(const MaxPushIdFrame& frame) {
+ if (spdy_session()->debug_visitor()) {
+ spdy_session()->debug_visitor()->OnMaxPushIdFrameReceived(frame);
+ }
+
+ if (spdy_session()->perspective() == Perspective::IS_CLIENT) {
+ OnWrongFrame("Max Push Id");
+ return false;
+ }
+
+ // TODO(b/124216424): Signal error if received push ID is smaller than a
+ // previously received value.
+ spdy_session()->OnMaxPushIdFrame(frame.push_id);
+ return true;
+}
+
+bool QuicReceiveControlStream::OnGoAwayFrame(const GoAwayFrame& frame) {
+ // TODO(bnc): Check if SETTINGS frame has been received.
+ if (spdy_session()->debug_visitor()) {
+ spdy_session()->debug_visitor()->OnGoAwayFrameReceived(frame);
+ }
+
+ if (spdy_session()->perspective() == Perspective::IS_SERVER) {
+ OnWrongFrame("Go Away");
+ return false;
+ }
+
+ spdy_session()->OnHttp3GoAway(frame.stream_id);
+ return true;
+}
+
bool QuicReceiveControlStream::OnSettingsFrameStart(
- QuicByteCount /* header_length */) {
+ QuicByteCount /*header_length*/) {
if (settings_frame_received_) {
stream_delegate()->OnStreamError(
QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
@@ -227,20 +112,82 @@
return true;
}
-bool QuicReceiveControlStream::OnSettingsFrame(const SettingsFrame& settings) {
+bool QuicReceiveControlStream::OnSettingsFrame(const SettingsFrame& frame) {
QUIC_DVLOG(1) << "Control Stream " << id()
- << " received settings frame: " << settings;
+ << " received settings frame: " << frame;
if (spdy_session_->debug_visitor() != nullptr) {
- spdy_session_->debug_visitor()->OnSettingsFrameReceived(settings);
+ spdy_session_->debug_visitor()->OnSettingsFrameReceived(frame);
}
- for (const auto& setting : settings.values) {
+ for (const auto& setting : frame.values) {
spdy_session_->OnSetting(setting.first, setting.second);
}
return true;
}
+bool QuicReceiveControlStream::OnDataFrameStart(QuicByteCount /*header_length*/,
+ QuicByteCount
+ /*payload_length*/) {
+ OnWrongFrame("Data");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnDataFramePayload(
+ quiche::QuicheStringPiece /*payload*/) {
+ OnWrongFrame("Data");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnDataFrameEnd() {
+ OnWrongFrame("Data");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnHeadersFrameStart(
+ QuicByteCount /*header_length*/,
+ QuicByteCount
+ /*payload_length*/) {
+ OnWrongFrame("Headers");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnHeadersFramePayload(
+ quiche::QuicheStringPiece /*payload*/) {
+ OnWrongFrame("Headers");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnHeadersFrameEnd() {
+ OnWrongFrame("Headers");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnPushPromiseFrameStart(
+ QuicByteCount /*header_length*/) {
+ OnWrongFrame("Push Promise");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnPushPromiseFramePushId(
+ PushId /*push_id*/,
+ QuicByteCount /*push_id_length*/,
+ QuicByteCount /*header_block_length*/) {
+ OnWrongFrame("Push Promise");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnPushPromiseFramePayload(
+ quiche::QuicheStringPiece /*payload*/) {
+ OnWrongFrame("Push Promise");
+ return false;
+}
+
+bool QuicReceiveControlStream::OnPushPromiseFrameEnd() {
+ OnWrongFrame("Push Promise");
+ return false;
+}
+
bool QuicReceiveControlStream::OnPriorityUpdateFrameStart(
- QuicByteCount /* header_length */) {
+ QuicByteCount /*header_length*/) {
if (!settings_frame_received_) {
stream_delegate()->OnStreamError(
QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
@@ -251,14 +198,14 @@
}
bool QuicReceiveControlStream::OnPriorityUpdateFrame(
- const PriorityUpdateFrame& priority) {
+ const PriorityUpdateFrame& frame) {
if (spdy_session()->debug_visitor()) {
- spdy_session()->debug_visitor()->OnPriorityUpdateFrameReceived(priority);
+ spdy_session()->debug_visitor()->OnPriorityUpdateFrameReceived(frame);
}
// TODO(b/147306124): Use a proper structured headers parser instead.
for (auto key_value :
- quiche::QuicheTextUtils::Split(priority.priority_field_value, ',')) {
+ quiche::QuicheTextUtils::Split(frame.priority_field_value, ',')) {
auto key_and_value = quiche::QuicheTextUtils::Split(key_value, '=');
if (key_and_value.size() != 2) {
continue;
@@ -280,12 +227,12 @@
return false;
}
- if (priority.prioritized_element_type == REQUEST_STREAM) {
+ if (frame.prioritized_element_type == REQUEST_STREAM) {
return spdy_session_->OnPriorityUpdateForRequestStream(
- priority.prioritized_element_id, urgency);
+ frame.prioritized_element_id, urgency);
} else {
return spdy_session_->OnPriorityUpdateForPushStream(
- priority.prioritized_element_id, urgency);
+ frame.prioritized_element_id, urgency);
}
}
@@ -293,7 +240,15 @@
return true;
}
-bool QuicReceiveControlStream::OnUnknownFrameStart() {
+bool QuicReceiveControlStream::OnUnknownFrameStart(
+ uint64_t frame_type,
+ QuicByteCount /*header_length*/,
+ QuicByteCount payload_length) {
+ if (spdy_session()->debug_visitor()) {
+ spdy_session()->debug_visitor()->OnUnknownFrameReceived(id(), frame_type,
+ payload_length);
+ }
+
if (!settings_frame_received_) {
stream_delegate()->OnStreamError(
QUIC_HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM,
@@ -304,4 +259,22 @@
return true;
}
+bool QuicReceiveControlStream::OnUnknownFramePayload(
+ quiche::QuicheStringPiece /*payload*/) {
+ // Ignore unknown frame types.
+ return true;
+}
+
+bool QuicReceiveControlStream::OnUnknownFrameEnd() {
+ // Ignore unknown frame types.
+ return true;
+}
+
+void QuicReceiveControlStream::OnWrongFrame(
+ quiche::QuicheStringPiece frame_type) {
+ OnUnrecoverableError(
+ QUIC_HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM,
+ quiche::QuicheStrCat(frame_type, " frame received on control stream"));
+}
+
} // namespace quic
diff --git a/quic/core/http/quic_receive_control_stream.h b/quic/core/http/quic_receive_control_stream.h
index d24bcd0..7fd02b4 100644
--- a/quic/core/http/quic_receive_control_stream.h
+++ b/quic/core/http/quic_receive_control_stream.h
@@ -16,7 +16,9 @@
// 3.2.1 Control Stream.
// The receive control stream is peer initiated and is read only.
-class QUIC_EXPORT_PRIVATE QuicReceiveControlStream : public QuicStream {
+class QUIC_EXPORT_PRIVATE QuicReceiveControlStream
+ : public QuicStream,
+ public HttpDecoder::Visitor {
public:
explicit QuicReceiveControlStream(PendingStream* pending,
QuicSpdySession* spdy_session);
@@ -31,27 +33,46 @@
// Implementation of QuicStream.
void OnDataAvailable() override;
+ // HttpDecoderVisitor implementation.
+ void OnError(HttpDecoder* decoder) override;
+ bool OnCancelPushFrame(const CancelPushFrame& frame) override;
+ bool OnMaxPushIdFrame(const MaxPushIdFrame& frame) override;
+ bool OnGoAwayFrame(const GoAwayFrame& frame) override;
+ bool OnSettingsFrameStart(QuicByteCount header_length) override;
+ bool OnSettingsFrame(const SettingsFrame& frame) override;
+ bool OnDataFrameStart(QuicByteCount header_length,
+ QuicByteCount payload_length) override;
+ bool OnDataFramePayload(quiche::QuicheStringPiece payload) override;
+ bool OnDataFrameEnd() override;
+ bool OnHeadersFrameStart(QuicByteCount header_length,
+ QuicByteCount payload_length) override;
+ bool OnHeadersFramePayload(quiche::QuicheStringPiece payload) override;
+ bool OnHeadersFrameEnd() override;
+ bool OnPushPromiseFrameStart(QuicByteCount header_length) override;
+ bool OnPushPromiseFramePushId(PushId push_id,
+ QuicByteCount push_id_length,
+ QuicByteCount header_block_length) override;
+ bool OnPushPromiseFramePayload(quiche::QuicheStringPiece payload) override;
+ bool OnPushPromiseFrameEnd() override;
+ bool OnPriorityUpdateFrameStart(QuicByteCount header_length) override;
+ bool OnPriorityUpdateFrame(const PriorityUpdateFrame& frame) override;
+ bool OnUnknownFrameStart(uint64_t frame_type,
+ QuicByteCount header_length,
+ QuicByteCount payload_length) override;
+ bool OnUnknownFramePayload(quiche::QuicheStringPiece payload) override;
+ bool OnUnknownFrameEnd() override;
+
void SetUnblocked() { sequencer()->SetUnblocked(); }
QuicSpdySession* spdy_session() { return spdy_session_; }
private:
- class HttpDecoderVisitor;
-
- // Called from HttpDecoderVisitor.
- bool OnSettingsFrameStart(QuicByteCount header_length);
- bool OnSettingsFrame(const SettingsFrame& settings);
- bool OnPriorityUpdateFrameStart(QuicByteCount header_length);
- bool OnPriorityUpdateFrame(const PriorityUpdateFrame& priority);
- bool OnUnknownFrameStart();
+ void OnWrongFrame(quiche::QuicheStringPiece frame_type);
// False until a SETTINGS frame is received.
bool settings_frame_received_;
- // HttpDecoder and its visitor.
- std::unique_ptr<HttpDecoderVisitor> http_decoder_visitor_;
HttpDecoder decoder_;
-
QuicSpdySession* const spdy_session_;
};