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_;