Use IETF QPACK error codes on the wire.
gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 275232371
Change-Id: Id3bd3819b69167e92de6601f0cd146e084b2bee7
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
index 8c724e5..1372df0 100644
--- a/quic/core/http/quic_spdy_session.cc
+++ b/quic/core/http/quic_spdy_session.cc
@@ -411,18 +411,16 @@
void QuicSpdySession::OnDecoderStreamError(QuicStringPiece error_message) {
DCHECK(VersionUsesHttp3(transport_version()));
- // TODO(b/124216424): Use HTTP_QPACK_DECODER_STREAM_ERROR.
CloseConnectionWithDetails(
- QUIC_DECOMPRESSION_FAILURE,
+ QUIC_QPACK_DECODER_STREAM_ERROR,
QuicStrCat("Decoder stream error: ", error_message));
}
void QuicSpdySession::OnEncoderStreamError(QuicStringPiece error_message) {
DCHECK(VersionUsesHttp3(transport_version()));
- // TODO(b/124216424): Use HTTP_QPACK_ENCODER_STREAM_ERROR.
CloseConnectionWithDetails(
- QUIC_DECOMPRESSION_FAILURE,
+ QUIC_QPACK_ENCODER_STREAM_ERROR,
QuicStrCat("Encoder stream error: ", error_message));
}
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index 600e342..89f2d04 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -2563,7 +2563,7 @@
EXPECT_CALL(
*connection_,
- CloseConnection(QUIC_DECOMPRESSION_FAILURE,
+ CloseConnection(QUIC_QPACK_ENCODER_STREAM_ERROR,
"Encoder stream error: Invalid relative index.", _));
session_.OnStreamFrame(frame);
}
@@ -2584,7 +2584,7 @@
EXPECT_CALL(
*connection_,
- CloseConnection(QUIC_DECOMPRESSION_FAILURE,
+ CloseConnection(QUIC_QPACK_DECODER_STREAM_ERROR,
"Decoder stream error: Invalid increment value 0.", _));
session_.OnStreamFrame(frame);
}
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc
index 5dd9f3a..f90f3c7 100644
--- a/quic/core/http/quic_spdy_stream.cc
+++ b/quic/core/http/quic_spdy_stream.cc
@@ -544,14 +544,13 @@
}
void QuicSpdyStream::OnHeaderDecodingError() {
- // TODO(b/124216424): Use HTTP_EXCESSIVE_LOAD or
- // HTTP_QPACK_DECOMPRESSION_FAILED error code as indicated by
+ // TODO(b/124216424): Use HTTP_EXCESSIVE_LOAD instead if indicated by
// |qpack_decoded_headers_accumulator_|.
std::string error_message = QuicStrCat(
"Error during async decoding of ",
headers_decompressed_ ? "trailers" : "headers", " on stream ", id(), ": ",
qpack_decoded_headers_accumulator_->error_message());
- CloseConnectionWithDetails(QUIC_DECOMPRESSION_FAILURE, error_message);
+ CloseConnectionWithDetails(QUIC_QPACK_DECOMPRESSION_FAILED, error_message);
}
void QuicSpdyStream::OnHeadersTooLarge() {
@@ -904,11 +903,10 @@
sequencer()->MarkConsumed(body_manager_.OnNonBody(payload.size()));
if (!success) {
- // TODO(124216424): Use HTTP_QPACK_DECOMPRESSION_FAILED error code.
std::string error_message =
QuicStrCat("Error decompressing header block on stream ", id(), ": ",
qpack_decoded_headers_accumulator_->error_message());
- CloseConnectionWithDetails(QUIC_DECOMPRESSION_FAILURE, error_message);
+ CloseConnectionWithDetails(QUIC_QPACK_DECOMPRESSION_FAILED, error_message);
return false;
}
return true;
@@ -921,11 +919,10 @@
auto result = qpack_decoded_headers_accumulator_->EndHeaderBlock();
if (result == QpackDecodedHeadersAccumulator::Status::kError) {
- // TODO(124216424): Use HTTP_QPACK_DECOMPRESSION_FAILED error code.
std::string error_message =
QuicStrCat("Error decompressing header block on stream ", id(), ": ",
qpack_decoded_headers_accumulator_->error_message());
- CloseConnectionWithDetails(QUIC_DECOMPRESSION_FAILURE, error_message);
+ CloseConnectionWithDetails(QUIC_QPACK_DECOMPRESSION_FAILED, error_message);
return false;
}
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
index c545265..2db475e 100644
--- a/quic/core/http/quic_spdy_stream_test.cc
+++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -1840,7 +1840,7 @@
EXPECT_CALL(
*connection_,
CloseConnection(
- QUIC_DECOMPRESSION_FAILURE,
+ QUIC_QPACK_DECOMPRESSION_FAILED,
MatchesRegex("Error decompressing header block on stream \\d+: "
"Incomplete header block."),
_))
@@ -1994,7 +1994,7 @@
EXPECT_CALL(
*connection_,
CloseConnection(
- QUIC_DECOMPRESSION_FAILURE,
+ QUIC_QPACK_DECOMPRESSION_FAILED,
MatchesRegex("Error during async decoding of headers on stream \\d+: "
"Required Insert Count too large."),
ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET));
@@ -2055,7 +2055,7 @@
EXPECT_CALL(*connection_,
CloseConnection(
- QUIC_DECOMPRESSION_FAILURE,
+ QUIC_QPACK_DECOMPRESSION_FAILED,
MatchesRegex(
"Error during async decoding of trailers on stream \\d+: "
"Required Insert Count too large."),
diff --git a/quic/core/quic_error_codes.cc b/quic/core/quic_error_codes.cc
index b1e8ed2..a603bc1 100644
--- a/quic/core/quic_error_codes.cc
+++ b/quic/core/quic_error_codes.cc
@@ -160,6 +160,9 @@
QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM);
RETURN_STRING_LITERAL(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES);
RETURN_STRING_LITERAL(QUIC_TRANSPORT_INVALID_CLIENT_INDICATION);
+ RETURN_STRING_LITERAL(QUIC_QPACK_DECOMPRESSION_FAILED);
+ RETURN_STRING_LITERAL(QUIC_QPACK_ENCODER_STREAM_ERROR);
+ RETURN_STRING_LITERAL(QUIC_QPACK_DECODER_STREAM_ERROR);
RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
// Intentionally have no default case, so we'll break the build
diff --git a/quic/core/quic_error_codes.h b/quic/core/quic_error_codes.h
index ce5c721..9b3fab2 100644
--- a/quic/core/quic_error_codes.h
+++ b/quic/core/quic_error_codes.h
@@ -342,8 +342,13 @@
// QuicTransport received invalid client indication.
QUIC_TRANSPORT_INVALID_CLIENT_INDICATION = 125,
+ // Internal error codes for QPACK errors.
+ QUIC_QPACK_DECOMPRESSION_FAILED = 126,
+ QUIC_QPACK_ENCODER_STREAM_ERROR = 127,
+ QUIC_QPACK_DECODER_STREAM_ERROR = 128,
+
// No error. Used as bound while iterating.
- QUIC_LAST_ERROR = 126,
+ QUIC_LAST_ERROR = 129,
};
// QuicErrorCodes is encoded as four octets on-the-wire when doing Google QUIC,
// or a varint62 when doing IETF QUIC. Ensure that its value does not exceed
@@ -359,6 +364,14 @@
// Returns the name of the QuicErrorCode as a char*
QUIC_EXPORT const char* QuicErrorCodeToString(QuicErrorCode error);
+// Wire values for QPACK errors.
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#error-code-registration
+enum QuicHttpQpackErrorCode {
+ IETF_QUIC_HTTP_QPACK_DECOMPRESSION_FAILED = 0x200,
+ IETF_QUIC_HTTP_QPACK_ENCODER_STREAM_ERROR = 0x201,
+ IETF_QUIC_HTTP_QPACK_DECODER_STREAM_ERROR = 0x202
+};
+
QUIC_EXPORT_PRIVATE inline std::string HistogramEnumString(
QuicErrorCode enum_value) {
return QuicErrorCodeToString(enum_value);
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc
index db48c5c..e6f95cd 100644
--- a/quic/core/quic_types.cc
+++ b/quic/core/quic_types.cc
@@ -413,6 +413,18 @@
{static_cast<uint64_t>(QUIC_TOO_MANY_BUFFERED_CONTROL_FRAMES)}};
case QUIC_TRANSPORT_INVALID_CLIENT_INDICATION:
return {false, {0u}};
+ case QUIC_QPACK_DECOMPRESSION_FAILED:
+ return {
+ false,
+ {static_cast<uint64_t>(IETF_QUIC_HTTP_QPACK_DECOMPRESSION_FAILED)}};
+ case QUIC_QPACK_ENCODER_STREAM_ERROR:
+ return {
+ false,
+ {static_cast<uint64_t>(IETF_QUIC_HTTP_QPACK_ENCODER_STREAM_ERROR)}};
+ case QUIC_QPACK_DECODER_STREAM_ERROR:
+ return {
+ false,
+ {static_cast<uint64_t>(IETF_QUIC_HTTP_QPACK_DECODER_STREAM_ERROR)}};
case QUIC_LAST_ERROR:
return {false, {static_cast<uint64_t>(QUIC_LAST_ERROR)}};
}
diff --git a/quic/core/quic_types_test.cc b/quic/core/quic_types_test.cc
index 8b4df89..39989ce 100644
--- a/quic/core/quic_types_test.cc
+++ b/quic/core/quic_types_test.cc
@@ -27,10 +27,6 @@
QuicIetfTransportErrorCodeString(mapping.transport_error_code_),
QuicStrCat("Unknown Transport Error Code Value: ",
static_cast<uint16_t>(mapping.transport_error_code_)));
- } else {
- // Some QuicErrorCodes are no longer valid.
- EXPECT_EQ(QuicIetfTransportErrorCodeString(mapping.transport_error_code_),
- "NO_IETF_QUIC_ERROR");
}
}
}