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;