Add `num_ohttp_chunks` flag and remove `chunked` flag.

If `num_ohttp_chunks` is not set or is set to 0, the logic will use standard non-chunked OHTTP. If it is more than 0, then it will use chunked OHTTP and attempt to split the serialized BHTTP request data (regardless of it being known-length or indeterminate-length) by `num_ohttp_chunks`.

PiperOrigin-RevId: 897766842
diff --git a/quiche/quic/masque/masque_ohttp_client.cc b/quiche/quic/masque/masque_ohttp_client.cc
index 6e8d5d2..49f2573 100644
--- a/quiche/quic/masque/masque_ohttp_client.cc
+++ b/quiche/quic/masque/masque_ohttp_client.cc
@@ -425,7 +425,7 @@
   std::string encoded_data;
   int num_bhttp_chunks = per_request_config.num_bhttp_chunks();
   if (num_bhttp_chunks < 0) {
-    num_bhttp_chunks = (per_request_config.use_chunked_ohttp() ? 1 : 0);
+    num_bhttp_chunks = (per_request_config.num_ohttp_chunks() > 0 ? 1 : 0);
   }
   if (num_bhttp_chunks > 0) {
     BinaryHttpRequest::IndeterminateLengthEncoder encoder;
@@ -466,23 +466,24 @@
     binary_request.set_body(post_data);
     QUICHE_ASSIGN_OR_RETURN(encoded_data, binary_request.Serialize());
   }
-  if (pending_request.per_request_config.use_chunked_ohttp()) {
+  int num_ohttp_chunks = pending_request.per_request_config.num_ohttp_chunks();
+  if (num_ohttp_chunks > 0) {
     pending_request.chunk_handler = std::make_unique<ChunkHandler>();
     QUICHE_ASSIGN_OR_RETURN(
         ChunkedObliviousHttpClient chunked_client,
         ChunkedObliviousHttpClient::Create(
             ohttp_client_->GetPublicKey(), ohttp_client_->GetKeyConfig(),
             pending_request.chunk_handler.get()));
-    // Intentionally split the data into two chunks to test encryption chunking.
-    QUICHE_ASSIGN_OR_RETURN(encrypted_data,
-                            chunked_client.EncryptRequestChunk(
-                                absl::string_view(encoded_data).substr(0, 1),
-                                /*is_final_chunk=*/false));
-    QUICHE_ASSIGN_OR_RETURN(std::string encrypted_data2,
-                            chunked_client.EncryptRequestChunk(
-                                absl::string_view(encoded_data).substr(1),
-                                /*is_final_chunk=*/true));
-    encrypted_data += encrypted_data2;
+    QUICHE_ASSIGN_OR_RETURN(std::vector<absl::string_view> ohttp_chunks,
+                            SplitIntoChunks(encoded_data, num_ohttp_chunks));
+
+    for (size_t i = 0; i < ohttp_chunks.size(); i++) {
+      bool is_final_chunk = (i == ohttp_chunks.size() - 1);
+      QUICHE_ASSIGN_OR_RETURN(
+          std::string ohttp_chunk,
+          chunked_client.EncryptRequestChunk(ohttp_chunks[i], is_final_chunk));
+      encrypted_data += ohttp_chunk;
+    }
 
     pending_request.chunk_handler->SetChunkedClient(std::move(chunked_client));
   } else {
@@ -498,9 +499,7 @@
   request.headers[":authority"] = relay_url_.HostPort();
   request.headers[":path"] = relay_url_.PathParamsQuery();
   request.headers["content-type"] =
-      pending_request.per_request_config.use_chunked_ohttp()
-          ? "message/ohttp-chunked-req"
-          : "message/ohttp-req";
+      num_ohttp_chunks > 0 ? "message/ohttp-chunked-req" : "message/ohttp-req";
   for (const std::pair<std::string, std::string>& header :
        per_request_config.outer_headers()) {
     request.headers[header.first] = header.second;
@@ -598,9 +597,10 @@
     return absl::InvalidArgumentError(
         absl::StrCat("Bad gateway status code: ", gateway_status_code));
   }
-  std::string content_type = it->second.per_request_config.use_chunked_ohttp()
-                                 ? "message/ohttp-chunked-res"
-                                 : "message/ohttp-res";
+  std::string content_type =
+      it->second.per_request_config.num_ohttp_chunks() > 0
+          ? "message/ohttp-chunked-res"
+          : "message/ohttp-res";
   std::optional<uint16_t> expected_gateway_status_code =
       it->second.per_request_config.expected_gateway_status_code();
   absl::Status status = CheckStatusAndContentType(*response, content_type,
@@ -623,7 +623,7 @@
   std::optional<Message> encapsulated_response;
   QUICHE_VLOG(2) << "Received encrypted response body: "
                  << absl::BytesToHexString(response->body);
-  if (it->second.per_request_config.use_chunked_ohttp()) {
+  if (it->second.per_request_config.num_ohttp_chunks() > 0) {
     QUICHE_ASSIGN_OR_RETURN(
         encapsulated_response,
         it->second.chunk_handler->DecryptFullResponse(response->body));
diff --git a/quiche/quic/masque/masque_ohttp_client.h b/quiche/quic/masque/masque_ohttp_client.h
index 8a5c02b..32fbdca 100644
--- a/quiche/quic/masque/masque_ohttp_client.h
+++ b/quiche/quic/masque/masque_ohttp_client.h
@@ -51,10 +51,8 @@
       absl::Status AddOuterHeaders(
           const std::vector<std::string>& outer_headers);
       absl::Status AddPrivateToken(const std::string& private_token);
-      void SetUseChunkedOhttp(bool use_chunked_ohttp) {
-        use_chunked_ohttp_ = use_chunked_ohttp;
-      }
       void SetNumBhttpChunks(int num_chunks) { num_bhttp_chunks_ = num_chunks; }
+      void SetNumOhttpChunks(int num_chunks) { num_ohttp_chunks_ = num_chunks; }
       void SetExpectedGatewayError(const std::string& expected_gateway_error) {
         expected_gateway_error_ = expected_gateway_error;
       }
@@ -80,8 +78,8 @@
           const {
         return outer_headers_;
       }
-      bool use_chunked_ohttp() const { return use_chunked_ohttp_; }
       int num_bhttp_chunks() const { return num_bhttp_chunks_; }
+      int num_ohttp_chunks() const { return num_ohttp_chunks_; }
       std::optional<std::string> expected_gateway_error() const {
         return expected_gateway_error_;
       }
@@ -101,7 +99,7 @@
       std::optional<std::string> method_;
       std::vector<std::pair<std::string, std::string>> headers_;
       std::vector<std::pair<std::string, std::string>> outer_headers_;
-      bool use_chunked_ohttp_ = false;
+      int num_ohttp_chunks_ = 0;
       int num_bhttp_chunks_ = -1;
       std::optional<std::string> expected_gateway_error_;
       std::optional<uint16_t> expected_gateway_status_code_;
diff --git a/quiche/quic/masque/masque_ohttp_client_bin.cc b/quiche/quic/masque/masque_ohttp_client_bin.cc
index fab77ab..071cc51 100644
--- a/quiche/quic/masque/masque_ohttp_client_bin.cc
+++ b/quiche/quic/masque/masque_ohttp_client_bin.cc
@@ -29,9 +29,6 @@
     bool, use_mtls_for_key_fetch, false,
     "If true, use mTLS when fetching the OHTTP/HPKE keys.");
 
-DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, chunked, false,
-                                "If true, use chunked OHTTP.");
-
 DEFINE_QUICHE_COMMAND_LINE_FLAG(int, address_family, 0,
                                 "IP address family to use. Must be 0, 4 or 6. "
                                 "Defaults to 0 which means any.");
@@ -60,10 +57,16 @@
 DEFINE_QUICHE_COMMAND_LINE_FLAG(
     int, num_bhttp_chunks, -1,
     "Number of indeterminate-length BHTTP chunks to split post data into. If "
-    "not set or if set to -1, it will match the chunked flag mode. If set to "
+    "not set or if set to -1, it will match the chunked mode (see "
+    "--num_ohttp_chunks). If set to "
     "0, the client will use known-length BHTTP.");
 
 DEFINE_QUICHE_COMMAND_LINE_FLAG(
+    int, num_ohttp_chunks, 0,
+    "Number of OHTTP chunks to split serialized BHTTP request into. If not set "
+    "or if set to 0, the client will use standard non-chunked OHTTP.");
+
+DEFINE_QUICHE_COMMAND_LINE_FLAG(
     std::vector<std::string>, header, {},
     "Adds a header field to the encapsulated binary request. Separate the "
     "header name and value with a colon. Can be specified multiple times.");
@@ -120,8 +123,6 @@
       quiche::GetQuicheCommandLineFlag(FLAGS_disable_certificate_verification);
   const bool use_mtls_for_key_fetch =
       quiche::GetQuicheCommandLineFlag(FLAGS_use_mtls_for_key_fetch);
-  const bool use_chunked_ohttp =
-      quiche::GetQuicheCommandLineFlag(FLAGS_chunked);
   const std::string client_cert_file =
       quiche::GetQuicheCommandLineFlag(FLAGS_client_cert_file);
   const std::string client_cert_key_file =
@@ -154,6 +155,8 @@
   }
   std::optional<std::string> method =
       quiche::GetQuicheCommandLineFlag(FLAGS_method);
+  const int num_ohttp_chunks =
+      quiche::GetQuicheCommandLineFlag(FLAGS_num_ohttp_chunks);
   const int num_bhttp_chunks =
       quiche::GetQuicheCommandLineFlag(FLAGS_num_bhttp_chunks);
   std::vector<std::string> headers =
@@ -224,7 +227,7 @@
       QUICHE_RETURN_IF_ERROR(
           per_request_config.AddPrivateToken(generated_private_token));
     }
-    per_request_config.SetUseChunkedOhttp(use_chunked_ohttp);
+    per_request_config.SetNumOhttpChunks(num_ohttp_chunks);
     per_request_config.SetNumBhttpChunks(num_bhttp_chunks);
     if (expect_gateway_error.has_value()) {
       per_request_config.SetExpectedGatewayError(*expect_gateway_error);