Factor the header validation and response-code parsing/validation code in QuicSpdyClientStream::OnInitialHeadersComplete out such that they can be overriden in subclasses. PiperOrigin-RevId: 475381192
diff --git a/quiche/quic/core/http/quic_spdy_client_stream.cc b/quiche/quic/core/http/quic_spdy_client_stream.cc index 92277f9..1661c94 100644 --- a/quiche/quic/core/http/quic_spdy_client_stream.cc +++ b/quiche/quic/core/http/quic_spdy_client_stream.cc
@@ -43,6 +43,49 @@ QuicSpdyClientStream::~QuicSpdyClientStream() = default; +bool QuicSpdyClientStream::CopyAndValidateHeaders( + const QuicHeaderList& header_list, int64_t& content_length, + spdy::Http2HeaderBlock& headers) { + return SpdyUtils::CopyAndValidateHeaders(header_list, &content_length, + &headers); +} + +bool QuicSpdyClientStream::ParseAndValidateStatusCode() { + if (!ParseHeaderStatusCode(response_headers_, &response_code_)) { + QUIC_DLOG(ERROR) << "Received invalid response code: " + << response_headers_[":status"].as_string() + << " on stream " << id(); + Reset(QUIC_BAD_APPLICATION_PAYLOAD); + return false; + } + + if (response_code_ == 101) { + // 101 "Switching Protocols" is forbidden in HTTP/3 as per the + // "HTTP Upgrade" section of draft-ietf-quic-http. + QUIC_DLOG(ERROR) << "Received forbidden 101 response code" + << " on stream " << id(); + Reset(QUIC_BAD_APPLICATION_PAYLOAD); + return false; + } + + if (response_code_ >= 100 && response_code_ < 200) { + // These are Informational 1xx headers, not the actual response headers. + QUIC_DLOG(INFO) << "Received informational response code: " + << response_headers_[":status"].as_string() << " on stream " + << id(); + set_headers_decompressed(false); + if (response_code_ == 100 && !has_preliminary_headers_) { + // This is 100 Continue, save it to enable "Expect: 100-continue". + has_preliminary_headers_ = true; + preliminary_headers_ = std::move(response_headers_); + } else { + response_headers_.clear(); + } + } + + return true; +} + void QuicSpdyClientStream::OnInitialHeadersComplete( bool fin, size_t frame_len, const QuicHeaderList& header_list) { QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list); @@ -55,8 +98,8 @@ return; } - if (!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_, - &response_headers_)) { + if (!CopyAndValidateHeaders(header_list, content_length_, + response_headers_)) { QUIC_DLOG(ERROR) << "Failed to parse header list: " << header_list.DebugString() << " on stream " << id(); Reset(QUIC_BAD_APPLICATION_PAYLOAD); @@ -77,38 +120,10 @@ } } - if (!ParseHeaderStatusCode(response_headers_, &response_code_)) { - QUIC_DLOG(ERROR) << "Received invalid response code: " - << response_headers_[":status"].as_string() - << " on stream " << id(); - Reset(QUIC_BAD_APPLICATION_PAYLOAD); + if (!ParseAndValidateStatusCode()) { return; } - if (response_code_ == 101) { - // 101 "Switching Protocols" is forbidden in HTTP/3 as per the - // "HTTP Upgrade" section of draft-ietf-quic-http. - QUIC_DLOG(ERROR) << "Received forbidden 101 response code" - << " on stream " << id(); - Reset(QUIC_BAD_APPLICATION_PAYLOAD); - return; - } - - if (response_code_ >= 100 && response_code_ < 200) { - // These are Informational 1xx headers, not the actual response headers. - QUIC_DLOG(INFO) << "Received informational response code: " - << response_headers_[":status"].as_string() << " on stream " - << id(); - set_headers_decompressed(false); - if (response_code_ == 100 && !has_preliminary_headers_) { - // This is 100 Continue, save it to enable "Expect: 100-continue". - has_preliminary_headers_ = true; - preliminary_headers_ = std::move(response_headers_); - } else { - response_headers_.clear(); - } - } - ConsumeHeaderList(); QUIC_DVLOG(1) << "headers complete for stream " << id();
diff --git a/quiche/quic/core/http/quic_spdy_client_stream.h b/quiche/quic/core/http/quic_spdy_client_stream.h index a0806d7..7a4f90a 100644 --- a/quiche/quic/core/http/quic_spdy_client_stream.h +++ b/quiche/quic/core/http/quic_spdy_client_stream.h
@@ -73,6 +73,16 @@ protected: bool AreHeadersValid(const QuicHeaderList& header_list) const override; + // Called by OnInitialHeadersComplete to set response_header_. Returns false + // on error. + virtual bool CopyAndValidateHeaders(const QuicHeaderList& header_list, + int64_t& content_length, + spdy::Http2HeaderBlock& headers); + + // Called by OnInitialHeadersComplete to set response_code_ based on + // response_header_. Returns false on error. + virtual bool ParseAndValidateStatusCode(); + private: // The parsed headers received from the server. spdy::Http2HeaderBlock response_headers_;
diff --git a/quiche/quic/tools/quic_simple_client_session.h b/quiche/quic/tools/quic_simple_client_session.h index f3231ad..763a1a3 100644 --- a/quiche/quic/tools/quic_simple_client_session.h +++ b/quiche/quic/tools/quic_simple_client_session.h
@@ -27,6 +27,7 @@ HttpDatagramSupport LocalHttpDatagramSupport() override; std::unique_ptr<QuicPathValidationContext> CreateContextForMultiPortPath() override; + bool drop_response_body() const { return drop_response_body_; } private: QuicClientBase::NetworkHelper* network_helper_;