Refactor MaybeSendPriorityUpdateFrame().

|priority_sent_| was used to make sure PRIORITY_UPDATE frame is sent with
initial headers but not with trailers.  Moving code from WriteHeadersImpl() to
WriteHeaders() achieves the same.  Also refactor code into
MaybeSendPriorityUpdateFrame() so that it can be reused in a future CL for
sending PRIORITY_UPDATE frame when priority changes after initial headers are
sent.

gfe-relnote: n/a, change to QUIC v99-only code.  Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 292379616
Change-Id: Iad35e1a8698bf019b698fb39a7308758bd08b5fa
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc
index 1e34bd7..d69299e 100644
--- a/quic/core/http/quic_spdy_stream.cc
+++ b/quic/core/http/quic_spdy_stream.cc
@@ -198,7 +198,6 @@
       trailers_payload_length_(0),
       trailers_decompressed_(false),
       trailers_consumed_(false),
-      priority_sent_(false),
       http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
       decoder_(http_decoder_visitor_.get()),
       sequencer_offset_(0),
@@ -235,7 +234,6 @@
       trailers_payload_length_(0),
       trailers_decompressed_(false),
       trailers_consumed_(false),
-      priority_sent_(false),
       http_decoder_visitor_(std::make_unique<HttpDecoderVisitor>(this)),
       decoder_(http_decoder_visitor_.get()),
       sequencer_offset_(sequencer()->NumBytesConsumed()),
@@ -280,6 +278,9 @@
     WriteOrBufferData(quiche::QuicheStringPiece(writer.data(), writer.length()),
                       false, nullptr);
   }
+
+  MaybeSendPriorityUpdateFrame();
+
   size_t bytes_written =
       WriteHeadersImpl(std::move(header_block), fin, std::move(ack_listener));
   if (!VersionUsesHttp3(transport_version()) && fin) {
@@ -582,6 +583,22 @@
                              connection_close_error_message);
 }
 
+void QuicSpdyStream::MaybeSendPriorityUpdateFrame() {
+  if (!VersionUsesHttp3(transport_version()) ||
+      session()->perspective() != Perspective::IS_CLIENT) {
+    return;
+  }
+
+  // Value between 0 and 7, inclusive.  Lower value means higher priority.
+  int urgency = precedence().spdy3_priority();
+
+  PriorityUpdateFrame priority_update;
+  priority_update.prioritized_element_type = REQUEST_STREAM;
+  priority_update.prioritized_element_id = id();
+  priority_update.priority_field_value = quiche::QuicheStrCat("u=", urgency);
+  spdy_session_->WriteHttp3PriorityUpdate(priority_update);
+}
+
 void QuicSpdyStream::OnHeadersTooLarge() {
   if (VersionUsesHttp3(transport_version())) {
     // TODO(b/124216424): Reset stream with H3_REQUEST_CANCELLED (if client)
@@ -1041,17 +1058,6 @@
         std::move(ack_listener));
   }
 
-  if (!priority_sent_ && session()->perspective() == Perspective::IS_CLIENT) {
-    PriorityUpdateFrame priority_update;
-    priority_update.prioritized_element_type = REQUEST_STREAM;
-    priority_update.prioritized_element_id = id();
-    // Value between 0 and 7, inclusive.  Lower value means higher priority.
-    int urgency = precedence().spdy3_priority();
-    priority_update.priority_field_value = quiche::QuicheStrCat("u=", urgency);
-    spdy_session_->WriteHttp3PriorityUpdate(priority_update);
-    priority_sent_ = true;
-  }
-
   // Encode header list.
   QuicByteCount encoder_stream_sent_byte_count;
   std::string encoded_headers =
diff --git a/quic/core/http/quic_spdy_stream.h b/quic/core/http/quic_spdy_stream.h
index 49fe1dc..e6dbb50 100644
--- a/quic/core/http/quic_spdy_stream.h
+++ b/quic/core/http/quic_spdy_stream.h
@@ -221,6 +221,10 @@
 
   QuicSpdySession* spdy_session() const { return spdy_session_; }
 
+  // Send PRIORITY_UPDATE frame and update |last_sent_urgency_| if
+  // |last_sent_urgency_| is different from current priority.
+  void MaybeSendPriorityUpdateFrame();
+
  protected:
   // Called when the received headers are too large. By default this will
   // reset the stream.
@@ -299,9 +303,6 @@
   // True if the trailers have been consumed.
   bool trailers_consumed_;
 
-  // True if the stream has already sent an priority frame.
-  bool priority_sent_;
-
   // The parsed trailers received from the peer.
   spdy::SpdyHeaderBlock received_trailers_;