OHTTP test client: run requests sequentially PiperOrigin-RevId: 931332585
diff --git a/quiche/quic/masque/masque_ohttp_client.cc b/quiche/quic/masque/masque_ohttp_client.cc index 85ddfde..1db2d45 100644 --- a/quiche/quic/masque/masque_ohttp_client.cc +++ b/quiche/quic/masque/masque_ohttp_client.cc
@@ -476,7 +476,7 @@ // Key fetch request is still pending. return false; } - return pending_ohttp_requests_.empty(); + return unstarted_requests_.empty() && pending_ohttp_requests_.empty(); } void MasqueOhttpClient::Abort(absl::Status status) { @@ -664,12 +664,31 @@ } ohttp_client_.emplace(std::move(*ohttp_client)); - for (const auto& per_request_config : config_.per_request_configs()) { - QUICHE_RETURN_IF_ERROR(SendOhttpRequest(per_request_config)); + bool first_request = true; + for (size_t i = 0; i < config_.per_request_configs().size(); ++i) { + if (first_request || config_.send_requests_in_parallel()) { + QUICHE_RETURN_IF_ERROR( + SendOhttpRequest(config_.per_request_configs()[i])); + first_request = false; + } else { + unstarted_requests_.push_back(i); + } } return absl::OkStatus(); } +void MasqueOhttpClient::MaybeStartNextRequest() { + if (unstarted_requests_.empty()) { + return; + } + absl::Status status = SendOhttpRequest( + config_.per_request_configs()[unstarted_requests_.front()]); + unstarted_requests_.pop_front(); + if (!status.ok()) { + Abort(status); + } +} + absl::Status MasqueOhttpClient::SendOhttpRequest( const Config::PerRequestConfig& per_request_config) { QuicUrl url(per_request_config.url(), "https"); @@ -925,6 +944,7 @@ auto cleanup = absl::MakeCleanup([this, it, end_stream]() { if (end_stream) { pending_ohttp_requests_.erase(it); + MaybeStartNextRequest(); } }); if (!response.ok()) { @@ -1103,6 +1123,7 @@ auto cleanup = absl::MakeCleanup([this, it, end_stream]() { if (end_stream) { pending_ohttp_requests_.erase(it); + MaybeStartNextRequest(); } });
diff --git a/quiche/quic/masque/masque_ohttp_client.h b/quiche/quic/masque/masque_ohttp_client.h index 25b3bea..a33707c 100644 --- a/quiche/quic/masque/masque_ohttp_client.h +++ b/quiche/quic/masque/masque_ohttp_client.h
@@ -6,6 +6,7 @@ #define QUICHE_QUIC_MASQUE_MASQUE_OHTTP_CLIENT_H_ #include <functional> +#include <list> #include <memory> #include <optional> #include <string> @@ -191,6 +192,9 @@ void SetHandleGzipResponse(bool handle_gzip_response) { handle_gzip_response_ = handle_gzip_response; } + void SetSendRequestsInParallel(bool send_requests_in_parallel) { + send_requests_in_parallel_ = send_requests_in_parallel; + } absl::Status AddKeyFetchHeaders( const std::vector<std::string>& key_fetch_headers); void AddPerRequestConfig(const PerRequestConfig& per_request_config) { @@ -215,6 +219,9 @@ return key_fetch_headers_; } bool handle_gzip_response() const { return handle_gzip_response_; } + bool send_requests_in_parallel() const { + return send_requests_in_parallel_; + } bool skip_ohttp() const; private: @@ -227,6 +234,7 @@ std::vector<std::pair<std::string, std::string>> key_fetch_headers_; std::vector<PerRequestConfig> per_request_configs_; bool handle_gzip_response_ = false; + bool send_requests_in_parallel_ = false; }; struct RunDetails { @@ -296,6 +304,8 @@ static absl::StatusOr<RunDetails> RunInner(Config config, absl::string_view info_string); + void MaybeStartNextRequest(); + class QUICHE_NO_EXPORT ChunkHandler : public quiche::ObliviousHttpChunkHandler, public quiche::BinaryHttpResponse::IndeterminateLengthDecoder:: @@ -418,6 +428,7 @@ absl::flat_hash_map<RequestId, PendingRequest> pending_ohttp_requests_; ResponseVisitor* response_visitor_ = nullptr; RunDetails run_details_; + std::list<size_t> unstarted_requests_; }; } // namespace quic
diff --git a/quiche/quic/masque/masque_ohttp_client_bin.cc b/quiche/quic/masque/masque_ohttp_client_bin.cc index 3d60774..d0a0a5f 100644 --- a/quiche/quic/masque/masque_ohttp_client_bin.cc +++ b/quiche/quic/masque/masque_ohttp_client_bin.cc
@@ -30,6 +30,10 @@ "inner request and decompresses " "gzip-encoded inner responses."); +DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, send_requests_in_parallel, false, + "If true, sends all OHTTP requests in " + "parallel, otherwise send them sequentially."); + DEFINE_QUICHE_COMMAND_LINE_FLAG( bool, use_mtls_for_key_fetch, false, "If true, use mTLS when fetching the OHTTP/HPKE keys."); @@ -133,6 +137,8 @@ quiche::GetQuicheCommandLineFlag(FLAGS_disable_certificate_verification); const bool handle_gzip_response = quiche::GetQuicheCommandLineFlag(FLAGS_handle_gzip_response); + const bool send_requests_in_parallel = + quiche::GetQuicheCommandLineFlag(FLAGS_send_requests_in_parallel); const bool use_mtls_for_key_fetch = quiche::GetQuicheCommandLineFlag(FLAGS_use_mtls_for_key_fetch); const std::string client_cert_file = @@ -214,6 +220,7 @@ MasqueOhttpClient::Config config(/*key_fetch_url=*/urls[0], /*relay_url=*/urls[1]); config.SetHandleGzipResponse(handle_gzip_response); + config.SetSendRequestsInParallel(send_requests_in_parallel); if (use_mtls_for_key_fetch) { QUICHE_RETURN_IF_ERROR(config.ConfigureKeyFetchClientCert( client_cert_file, client_cert_key_file));