Refactor OgHttp2Session::ProcessBytes(). This CL adds internal OgHttp2Session::ProcessBytesImpl() that returns an absl::variant that contains either the number of bytes processed on success or an error code on failure. Then ProcessBytes() calls ProcessBytesImpl() and returns an overall int based on the absl::variant. This CL is a pure refactoring CL with only one error code at the moment, but the error codes will grow in a future CL to include values compatible with nghttp2. This compatibility will be useful for some codec_impl_test tests. PiperOrigin-RevId: 416872938
diff --git a/http2/adapter/oghttp2_session.cc b/http2/adapter/oghttp2_session.cc index 0519cee..84d6473 100644 --- a/http2/adapter/oghttp2_session.cc +++ b/http2/adapter/oghttp2_session.cc
@@ -1,5 +1,6 @@ #include "http2/adapter/oghttp2_session.h" +#include <cstdint> #include <tuple> #include <utility> @@ -263,6 +264,19 @@ frame_contains_fin_ = false; } +// A visitor that extracts an int64_t from each type of a ProcessBytesResult. +struct OgHttp2Session::ProcessBytesResultVisitor { + int64_t operator()(const int64_t bytes) const { return bytes; } + + int64_t operator()(const ProcessBytesError error) const { + switch (error) { + case ProcessBytesError::kUnspecified: + return -1; + } + return -1; + } +}; + OgHttp2Session::OgHttp2Session(Http2VisitorInterface& visitor, Options options) : visitor_(visitor), event_forwarder_([this]() { return !latched_error_; }, *this), @@ -377,6 +391,11 @@ int64_t OgHttp2Session::ProcessBytes(absl::string_view bytes) { QUICHE_VLOG(2) << TracePerspectiveAsString(options_.perspective) << " processing [" << absl::CEscape(bytes) << "]"; + return absl::visit(ProcessBytesResultVisitor(), ProcessBytesImpl(bytes)); +} + +absl::variant<int64_t, OgHttp2Session::ProcessBytesError> +OgHttp2Session::ProcessBytesImpl(absl::string_view bytes) { if (processing_bytes_) { QUICHE_VLOG(1) << "Returning early; already processing bytes."; return 0; @@ -396,7 +415,7 @@ << absl::CEscape(bytes) << "]"; LatchErrorAndNotify(Http2ErrorCode::PROTOCOL_ERROR, ConnectionError::kInvalidConnectionPreface); - return -1; + return ProcessBytesError::kUnspecified; } remaining_preface_.remove_prefix(min_size); bytes.remove_prefix(min_size); @@ -408,13 +427,12 @@ preface_consumed = min_size; } int64_t result = decoder_.ProcessInput(bytes.data(), bytes.size()); - if (latched_error_) { + QUICHE_VLOG(2) << "ProcessBytes result: " << result; + if (latched_error_ || result < 0) { QUICHE_VLOG(2) << "ProcessBytes encountered an error."; - return -1; + return ProcessBytesError::kUnspecified; } - const int64_t ret = result < 0 ? result : result + preface_consumed; - QUICHE_VLOG(2) << "ProcessBytes returning: " << ret; - return ret; + return result + preface_consumed; } int OgHttp2Session::Consume(Http2StreamId stream_id, size_t num_bytes) {
diff --git a/http2/adapter/oghttp2_session.h b/http2/adapter/oghttp2_session.h index aea6749..c3fbab2 100644 --- a/http2/adapter/oghttp2_session.h +++ b/http2/adapter/oghttp2_session.h
@@ -9,6 +9,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "absl/types/variant.h" #include "http2/adapter/data_source.h" #include "http2/adapter/event_forwarder.h" #include "http2/adapter/header_validator.h" @@ -265,6 +266,8 @@ bool frame_contains_fin_ = false; }; + struct QUICHE_EXPORT_PRIVATE ProcessBytesResultVisitor; + // Queues the connection preface, if not already done. void MaybeSetupPreface(); @@ -287,6 +290,16 @@ SEND_ERROR, }; + enum class ProcessBytesError { + // A general, unspecified error. + kUnspecified, + }; + using ProcessBytesResult = absl::variant<int64_t, ProcessBytesError>; + + // Attempts to process `bytes` and returns the number of bytes proccessed on + // success or the processing error on failure. + ProcessBytesResult ProcessBytesImpl(absl::string_view bytes); + // Returns true if at least one stream has data or control frames to write. bool HasReadyStream() const;