Allow selecting the binary HTTP encoding in OHTTP test client PiperOrigin-RevId: 865532368
diff --git a/quiche/quic/masque/masque_ohttp_client.cc b/quiche/quic/masque/masque_ohttp_client.cc index 574f9d8..8bd965e 100644 --- a/quiche/quic/masque/masque_ohttp_client.cc +++ b/quiche/quic/masque/masque_ohttp_client.cc
@@ -344,21 +344,14 @@ return absl::InternalError( "Cannot send OHTTP request without OHTTP client"); } - if (pending_request.per_request_config.use_chunked_ohttp()) { - pending_request.chunk_handler = std::make_unique<ChunkHandler>(); - absl::StatusOr<ChunkedObliviousHttpClient> chunked_client = - ChunkedObliviousHttpClient::Create(ohttp_client_->GetPublicKey(), - ohttp_client_->GetKeyConfig(), - pending_request.chunk_handler.get()); - if (!chunked_client.ok()) { - return absl::InternalError( - absl::StrCat("Failed to create chunked OHTTP client: ", - chunked_client.status().message())); - } - + std::string encoded_data; + const bool use_indeterminate_length = + per_request_config.use_indeterminate_length().value_or( + per_request_config.use_chunked_ohttp()); + if (use_indeterminate_length) { BinaryHttpRequest::IndeterminateLengthEncoder encoder; - QUICHE_ASSIGN_OR_RETURN(std::string encoded_data, + QUICHE_ASSIGN_OR_RETURN(encoded_data, encoder.EncodeControlData(control_data)); std::vector<quiche::BinaryHttpMessage::FieldView> headers; if (!formatted_token.empty()) { @@ -393,40 +386,39 @@ QUICHE_ASSIGN_OR_RETURN(std::string encoded_trailers, encoder.EncodeTrailers(absl::MakeSpan(trailers))); encoded_data += encoded_trailers; - - // 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; - - pending_request.chunk_handler->SetChunkedClient(std::move(*chunked_client)); } else { BinaryHttpRequest binary_request(control_data); binary_request.set_body(post_data); if (!formatted_token.empty()) { binary_request.AddHeaderField({"authorization", formatted_token}); } - absl::StatusOr<std::string> encoded_request = binary_request.Serialize(); - if (!encoded_request.ok()) { - return absl::InternalError( - absl::StrCat("Failed to serialize OHTTP request: ", - encoded_request.status().message())); - } - absl::StatusOr<ObliviousHttpRequest> ohttp_request = - ohttp_client_->CreateObliviousHttpRequest(*encoded_request); - if (!ohttp_request.ok()) { - return absl::InternalError( - absl::StrCat("Failed to create OHTTP request: ", - ohttp_request.status().message())); - } - encrypted_data = ohttp_request->EncapsulateAndSerialize(); - pending_request.context.emplace(std::move(*ohttp_request).ReleaseContext()); + QUICHE_ASSIGN_OR_RETURN(encoded_data, binary_request.Serialize()); + } + if (pending_request.per_request_config.use_chunked_ohttp()) { + 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; + + pending_request.chunk_handler->SetChunkedClient(std::move(chunked_client)); + } else { + QUICHE_ASSIGN_OR_RETURN( + ObliviousHttpRequest ohttp_request, + ohttp_client_->CreateObliviousHttpRequest(encoded_data)); + encrypted_data = ohttp_request.EncapsulateAndSerialize(); + pending_request.context.emplace(std::move(ohttp_request).ReleaseContext()); } Message request; request.headers[":method"] = "POST";
diff --git a/quiche/quic/masque/masque_ohttp_client.h b/quiche/quic/masque/masque_ohttp_client.h index 6d188ff..7645421 100644 --- a/quiche/quic/masque/masque_ohttp_client.h +++ b/quiche/quic/masque/masque_ohttp_client.h
@@ -49,6 +49,10 @@ void SetUseChunkedOhttp(bool use_chunked_ohttp) { use_chunked_ohttp_ = use_chunked_ohttp; } + void SetUseIndeterminateLength( + std::optional<bool> use_indeterminate_length) { + use_indeterminate_length_ = use_indeterminate_length; + } void SetExpectedGatewayError(const std::string& expected_gateway_error) { expected_gateway_error_ = expected_gateway_error; } @@ -71,6 +75,9 @@ std::string post_data() const { return post_data_; } std::string private_token() const { return private_token_; } bool use_chunked_ohttp() const { return use_chunked_ohttp_; } + std::optional<bool> use_indeterminate_length() const { + return use_indeterminate_length_; + } std::optional<std::string> expected_gateway_error() const { return expected_gateway_error_; } @@ -89,6 +96,7 @@ std::string post_data_; std::string private_token_; bool use_chunked_ohttp_ = false; + std::optional<bool> use_indeterminate_length_; std::optional<std::string> expected_gateway_error_; std::optional<uint16_t> expected_gateway_status_code_; std::optional<uint16_t> expected_encapsulated_status_code_;
diff --git a/quiche/quic/masque/masque_ohttp_client_bin.cc b/quiche/quic/masque/masque_ohttp_client_bin.cc index 77d5f79..8e7979b 100644 --- a/quiche/quic/masque/masque_ohttp_client_bin.cc +++ b/quiche/quic/masque/masque_ohttp_client_bin.cc
@@ -31,6 +31,12 @@ DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, chunked, false, "If true, use chunked OHTTP."); +DEFINE_QUICHE_COMMAND_LINE_FLAG(std::optional<bool>, indeterminate_length, + std::nullopt, + "If set, overrides whether to use the " + "indeterminate length binary HTTP encoding. If " + "unset, uses the value of --chunked."); + 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."); @@ -87,6 +93,8 @@ quiche::GetQuicheCommandLineFlag(FLAGS_use_mtls_for_key_fetch); const bool use_chunked_ohttp = quiche::GetQuicheCommandLineFlag(FLAGS_chunked); + const std::optional<bool> indeterminate_length = + quiche::GetQuicheCommandLineFlag(FLAGS_indeterminate_length); const std::string client_cert_file = quiche::GetQuicheCommandLineFlag(FLAGS_client_cert_file); const std::string client_cert_key_file = @@ -137,6 +145,7 @@ MasqueOhttpClient::Config::PerRequestConfig per_request_config(urls[i]); per_request_config.SetPostData(post_data); per_request_config.SetUseChunkedOhttp(use_chunked_ohttp); + per_request_config.SetUseIndeterminateLength(indeterminate_length); per_request_config.SetPrivateToken(private_token); if (expect_gateway_error.has_value()) { per_request_config.SetExpectedGatewayError(*expect_gateway_error);