Add equality operators for public data types in BinaryHttp*
PiperOrigin-RevId: 475643555
diff --git a/quiche/binary_http/binary_http_message.h b/quiche/binary_http/binary_http_message.h
index d7da4fe..852df93 100644
--- a/quiche/binary_http/binary_http_message.h
+++ b/quiche/binary_http/binary_http_message.h
@@ -30,6 +30,10 @@
return name == rhs.name && value == rhs.value;
}
+ bool operator!=(const BinaryHttpMessage::Field& rhs) const {
+ return !(*this == rhs);
+ }
+
std::string DebugString() const;
};
virtual ~BinaryHttpMessage() = default;
@@ -87,6 +91,12 @@
std::vector<BinaryHttpMessage::Field> fields_;
};
+ bool operator==(const BinaryHttpMessage& rhs) const {
+ // `has_host_` is derived from `header_fields_` so it doesn't need to be
+ // tested directly.
+ return body_ == rhs.body_ && header_fields_ == rhs.header_fields_;
+ }
+
absl::Status EncodeKnownLengthFieldsAndBody(
quiche::QuicheDataWriter& writer) const;
uint64_t EncodedKnownLengthFieldsAndBodySize() const;
@@ -114,6 +124,9 @@
return method == rhs.method && scheme == rhs.scheme &&
authority == rhs.authority && path == rhs.path;
}
+ bool operator!=(const BinaryHttpRequest::ControlData& rhs) const {
+ return !(*this == rhs);
+ }
};
explicit BinaryHttpRequest(ControlData control_data)
: control_data_(std::move(control_data)) {}
@@ -126,6 +139,15 @@
virtual std::string DebugString() const override;
+ bool operator==(const BinaryHttpRequest& rhs) const {
+ return control_data_ == rhs.control_data_ &&
+ BinaryHttpMessage::operator==(rhs);
+ }
+
+ bool operator!=(const BinaryHttpRequest& rhs) const {
+ return !(*this == rhs);
+ }
+
private:
absl::Status EncodeControlData(quiche::QuicheDataWriter& writer) const;
@@ -164,6 +186,11 @@
return status_code_ == rhs.status_code_ && fields_ == rhs.fields_;
}
+ bool operator!=(
+ const BinaryHttpResponse::InformationalResponse& rhs) const {
+ return !(*this == rhs);
+ }
+
// Adds a field with the provided name, converted to lower case.
// Fields are in the order they are added.
void AddField(absl::string_view name, std::string value);
@@ -211,6 +238,16 @@
virtual std::string DebugString() const override;
+ bool operator==(const BinaryHttpResponse& rhs) const {
+ return informational_response_control_data_ ==
+ rhs.informational_response_control_data_ &&
+ status_code_ == rhs.status_code_ &&
+ BinaryHttpMessage::operator==(rhs);
+ }
+ bool operator!=(const BinaryHttpResponse& rhs) const {
+ return !(*this == rhs);
+ }
+
private:
// Returns Binary Http known length request formatted response.
absl::StatusOr<std::string> EncodeAsKnownLength() const;
diff --git a/quiche/binary_http/binary_http_message_test.cc b/quiche/binary_http/binary_http_message_test.cc
index 3ce4b0e..f98a375 100644
--- a/quiche/binary_http/binary_http_message_test.cc
+++ b/quiche/binary_http/binary_http_message_test.cc
@@ -262,6 +262,50 @@
"body that I used to post.\r\n}}}"));
}
+TEST(BinaryHttpRequest, Equality) {
+ BinaryHttpRequest request({"POST", "https", "www.example.com", "/hello.txt"});
+ request.AddHeaderField({"User-Agent", "not/telling"})
+ ->set_body({"hello, world!\r\n"});
+
+ BinaryHttpRequest same({"POST", "https", "www.example.com", "/hello.txt"});
+ same.AddHeaderField({"User-Agent", "not/telling"})
+ ->set_body({"hello, world!\r\n"});
+ EXPECT_EQ(request, same);
+}
+
+TEST(BinaryHttpRequest, Inequality) {
+ BinaryHttpRequest request({"POST", "https", "www.example.com", "/hello.txt"});
+ request.AddHeaderField({"User-Agent", "not/telling"})
+ ->set_body({"hello, world!\r\n"});
+
+ BinaryHttpRequest different_control(
+ {"PUT", "https", "www.example.com", "/hello.txt"});
+ different_control.AddHeaderField({"User-Agent", "not/telling"})
+ ->set_body({"hello, world!\r\n"});
+ EXPECT_NE(request, different_control);
+
+ BinaryHttpRequest different_header(
+ {"PUT", "https", "www.example.com", "/hello.txt"});
+ different_header.AddHeaderField({"User-Agent", "told/you"})
+ ->set_body({"hello, world!\r\n"});
+ EXPECT_NE(request, different_header);
+
+ BinaryHttpRequest no_header(
+ {"PUT", "https", "www.example.com", "/hello.txt"});
+ no_header.set_body({"hello, world!\r\n"});
+ EXPECT_NE(request, no_header);
+
+ BinaryHttpRequest different_body(
+ {"POST", "https", "www.example.com", "/hello.txt"});
+ different_body.AddHeaderField({"User-Agent", "not/telling"})
+ ->set_body({"goodbye, world!\r\n"});
+ EXPECT_NE(request, different_body);
+
+ BinaryHttpRequest no_body({"POST", "https", "www.example.com", "/hello.txt"});
+ no_body.AddHeaderField({"User-Agent", "not/telling"});
+ EXPECT_NE(request, no_body);
+}
+
TEST(BinaryHttpResponse, EncodeNoBody) {
/*
HTTP/1.1 404 Not Found
@@ -572,4 +616,68 @@
EXPECT_EQ(other, "hello, world!");
}
+TEST(BinaryHttpResponse, Equality) {
+ BinaryHttpResponse response(200);
+ response.AddHeaderField({"Server", "Apache"})->set_body("Hello, world!\r\n");
+ ASSERT_OK(
+ response.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}}));
+
+ BinaryHttpResponse same(200);
+ same.AddHeaderField({"Server", "Apache"})->set_body("Hello, world!\r\n");
+ ASSERT_OK(same.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}}));
+ ASSERT_EQ(response, same);
+}
+
+TEST(BinaryHttpResponse, Inequality) {
+ BinaryHttpResponse response(200);
+ response.AddHeaderField({"Server", "Apache"})->set_body("Hello, world!\r\n");
+ ASSERT_OK(
+ response.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}}));
+
+ BinaryHttpResponse different_status(201);
+ different_status.AddHeaderField({"Server", "Apache"})
+ ->set_body("Hello, world!\r\n");
+ EXPECT_OK(different_status.AddInformationalResponse(
+ 102, {{"Running", "\"sleep 15\""}}));
+ EXPECT_NE(response, different_status);
+
+ BinaryHttpResponse different_header(200);
+ different_header.AddHeaderField({"Server", "python3"})
+ ->set_body("Hello, world!\r\n");
+ EXPECT_OK(different_header.AddInformationalResponse(
+ 102, {{"Running", "\"sleep 15\""}}));
+ EXPECT_NE(response, different_header);
+
+ BinaryHttpResponse no_header(200);
+ no_header.set_body("Hello, world!\r\n");
+ EXPECT_OK(
+ no_header.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}}));
+ EXPECT_NE(response, no_header);
+
+ BinaryHttpResponse different_body(200);
+ different_body.AddHeaderField({"Server", "Apache"})
+ ->set_body("Goodbye, world!\r\n");
+ EXPECT_OK(different_body.AddInformationalResponse(
+ 102, {{"Running", "\"sleep 15\""}}));
+ EXPECT_NE(response, different_body);
+
+ BinaryHttpResponse no_body(200);
+ no_body.AddHeaderField({"Server", "Apache"});
+ EXPECT_OK(
+ no_body.AddInformationalResponse(102, {{"Running", "\"sleep 15\""}}));
+ EXPECT_NE(response, no_body);
+
+ BinaryHttpResponse different_informational(200);
+ different_informational.AddHeaderField({"Server", "Apache"})
+ ->set_body("Hello, world!\r\n");
+ EXPECT_OK(different_informational.AddInformationalResponse(
+ 198, {{"Running", "\"sleep 15\""}}));
+ EXPECT_NE(response, different_informational);
+
+ BinaryHttpResponse no_informational(200);
+ no_informational.AddHeaderField({"Server", "Apache"})
+ ->set_body("Hello, world!\r\n");
+ EXPECT_NE(response, no_informational);
+}
+
} // namespace quiche