Fixes frame length calculations to use the actual serialized length.
PiperOrigin-RevId: 409202403
diff --git a/http2/adapter/oghttp2_session.cc b/http2/adapter/oghttp2_session.cc
index 21dd589..379a40b 100644
--- a/http2/adapter/oghttp2_session.cc
+++ b/http2/adapter/oghttp2_session.cc
@@ -36,60 +36,50 @@
void VisitData(const spdy::SpdyDataIR& data) override {
frame_type_ = static_cast<uint8_t>(data.frame_type());
stream_id_ = data.stream_id();
- length_ =
- data.data_len() + (data.padded() ? 1 : 0) + data.padding_payload_len();
flags_ = (data.fin() ? 0x1 : 0) | (data.padded() ? 0x8 : 0);
}
void VisitHeaders(const spdy::SpdyHeadersIR& headers) override {
frame_type_ = static_cast<uint8_t>(headers.frame_type());
stream_id_ = headers.stream_id();
- length_ = headers.size() - spdy::kFrameHeaderSize;
flags_ = 0x4 | (headers.fin() ? 0x1 : 0) | (headers.padded() ? 0x8 : 0) |
(headers.has_priority() ? 0x20 : 0);
}
void VisitPriority(const spdy::SpdyPriorityIR& priority) override {
frame_type_ = static_cast<uint8_t>(priority.frame_type());
frame_type_ = 2;
- length_ = 5;
stream_id_ = priority.stream_id();
}
void VisitRstStream(const spdy::SpdyRstStreamIR& rst_stream) override {
frame_type_ = static_cast<uint8_t>(rst_stream.frame_type());
frame_type_ = 3;
- length_ = 4;
stream_id_ = rst_stream.stream_id();
error_code_ = rst_stream.error_code();
}
void VisitSettings(const spdy::SpdySettingsIR& settings) override {
frame_type_ = static_cast<uint8_t>(settings.frame_type());
frame_type_ = 4;
- length_ = 6 * settings.values().size();
flags_ = (settings.is_ack() ? 0x1 : 0);
}
void VisitPushPromise(const spdy::SpdyPushPromiseIR& push_promise) override {
frame_type_ = static_cast<uint8_t>(push_promise.frame_type());
frame_type_ = 5;
- length_ = push_promise.size() - spdy::kFrameHeaderSize;
stream_id_ = push_promise.stream_id();
flags_ = (push_promise.padded() ? 0x8 : 0);
}
void VisitPing(const spdy::SpdyPingIR& ping) override {
frame_type_ = static_cast<uint8_t>(ping.frame_type());
frame_type_ = 6;
- length_ = 8;
flags_ = (ping.is_ack() ? 0x1 : 0);
}
void VisitGoAway(const spdy::SpdyGoAwayIR& goaway) override {
frame_type_ = static_cast<uint8_t>(goaway.frame_type());
frame_type_ = 7;
- length_ = goaway.size() - spdy::kFrameHeaderSize;
error_code_ = goaway.error_code();
}
void VisitWindowUpdate(
const spdy::SpdyWindowUpdateIR& window_update) override {
frame_type_ = static_cast<uint8_t>(window_update.frame_type());
frame_type_ = 8;
- length_ = 4;
stream_id_ = window_update.stream_id();
}
void VisitContinuation(
@@ -97,13 +87,11 @@
frame_type_ = static_cast<uint8_t>(continuation.frame_type());
stream_id_ = continuation.stream_id();
flags_ = continuation.end_headers() ? 0x4 : 0;
- length_ = continuation.size() - spdy::kFrameHeaderSize;
}
void VisitUnknown(const spdy::SpdyUnknownIR& unknown) override {
frame_type_ = static_cast<uint8_t>(unknown.frame_type());
stream_id_ = unknown.stream_id();
flags_ = unknown.flags();
- length_ = unknown.size() - spdy::kFrameHeaderSize;
}
void VisitAltSvc(const spdy::SpdyAltSvcIR& /*altsvc*/) override {}
void VisitPriorityUpdate(
@@ -111,14 +99,12 @@
void VisitAcceptCh(const spdy::SpdyAcceptChIR& /*accept_ch*/) override {}
uint32_t stream_id() { return stream_id_; }
- uint32_t length() { return length_; }
uint32_t error_code() { return error_code_; }
uint8_t frame_type() { return frame_type_; }
uint8_t flags() { return flags_; }
private:
uint32_t stream_id_ = 0;
- uint32_t length_ = 0;
uint32_t error_code_ = 0;
uint8_t frame_type_ = 0;
uint8_t flags_ = 0;
@@ -457,10 +443,13 @@
const auto& frame_ptr = frames_.front();
FrameAttributeCollector c;
frame_ptr->Visit(&c);
- visitor_.OnBeforeFrameSent(c.frame_type(), c.stream_id(), c.length(),
- c.flags());
- frame_ptr->Visit(&send_logger_);
+ // Frames can't accurately report their own length; the actual serialized
+ // length must be used instead.
spdy::SpdySerializedFrame frame = framer_.SerializeFrame(*frame_ptr);
+ const size_t frame_payload_length = frame.size() - spdy::kFrameHeaderSize;
+ frame_ptr->Visit(&send_logger_);
+ visitor_.OnBeforeFrameSent(c.frame_type(), c.stream_id(),
+ frame_payload_length, c.flags());
const int64_t result = visitor_.OnReadyToSend(absl::string_view(frame));
if (result < 0) {
LatchErrorAndNotify(Http2ErrorCode::INTERNAL_ERROR,
@@ -470,8 +459,8 @@
// Write blocked.
return false;
} else {
- visitor_.OnFrameSent(c.frame_type(), c.stream_id(), c.length(), c.flags(),
- c.error_code());
+ visitor_.OnFrameSent(c.frame_type(), c.stream_id(), frame_payload_length,
+ c.flags(), c.error_code());
if (static_cast<FrameType>(c.frame_type()) == FrameType::RST_STREAM) {
// If this endpoint is resetting the stream, the stream should be
// closed. This endpoint is already aware of the outbound RST_STREAM and
@@ -482,7 +471,7 @@
frames_.pop_front();
if (static_cast<size_t>(result) < frame.size()) {
// The frame was partially written, so the rest must be buffered.
- serialized_prefix_.assign(frame.data() + result, frame.size() - result);
+ serialized_prefix_.append(frame.data() + result, frame.size() - result);
return false;
}
}