blob: 9d0d4c3e02e531bf0dbc3b6fa553f2a52dd71f0e [file] [log] [blame] [edit]
// Copyright 2025 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef QUICHE_QUIC_MASQUE_MASQUE_OHTTP_CLIENT_H_
#define QUICHE_QUIC_MASQUE_MASQUE_OHTTP_CLIENT_H_
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "openssl/base.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/masque/masque_connection_pool.h"
#include "quiche/quic/tools/quic_url.h"
#include "quiche/binary_http/binary_http_message.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
#include "quiche/oblivious_http/oblivious_http_client.h"
namespace quic {
// A client that sends OHTTP requests through a relay/gateway to target URLs.
class QUICHE_EXPORT MasqueOhttpClient
: public quic::MasqueConnectionPool::Visitor {
public:
using RequestId = quic::MasqueConnectionPool::RequestId;
using Message = quic::MasqueConnectionPool::Message;
explicit MasqueOhttpClient(
quic::QuicEventLoop* event_loop, SSL_CTX* key_fetch_ssl_ctx,
SSL_CTX* ohttp_ssl_ctx, std::vector<std::string> urls,
bool disable_certificate_verification, int address_family_for_lookup,
const std::string& post_data,
std::shared_ptr<MasqueConnectionPool::DnsResolver> dns_resolver = nullptr)
: urls_(urls),
post_data_(post_data),
connection_pool_(event_loop, key_fetch_ssl_ctx,
disable_certificate_verification,
address_family_for_lookup, this, dns_resolver) {
connection_pool_.SetMtlsSslCtx(ohttp_ssl_ctx);
}
// Starts fetching for the key and sends the OHTTP request.
absl::Status Start();
// Returns true if the client has completed all requests.
bool IsDone();
// Returns the status of the client.
absl::Status status() const { return status_; }
protected:
// From quic::MasqueConnectionPool::Visitor.
void OnPoolResponse(quic::MasqueConnectionPool* /*pool*/,
RequestId request_id,
absl::StatusOr<Message>&& response) override;
// Fetch key from the key URL.
absl::Status StartKeyFetch(const std::string& url_string);
// Handles the key response and starts the OHTTP request.
absl::Status HandleKeyResponse(const absl::StatusOr<Message>& response);
// Sends the OHTTP request for the given URL.
absl::Status SendOhttpRequestForUrl(const std::string& url_string);
// Signals the client to abort.
void Abort(absl::Status status);
absl::StatusOr<quiche::BinaryHttpResponse> TryExtractBinaryResponse(
RequestId request_id, quiche::ObliviousHttpRequest::Context& context,
const Message& response);
virtual absl::Status CheckGatewayResponse(const Message& response) {
return absl::OkStatus();
}
virtual absl::Status CheckEncapsulatedResponse(
const quiche::BinaryHttpResponse& response) {
return absl::OkStatus();
}
private:
absl::Status ProcessOhttpResponse(RequestId request_id,
const absl::StatusOr<Message>& response);
absl::Status CheckStatusAndContentType(const Message& response,
const std::string& content_type);
std::vector<std::string> urls_;
std::string post_data_;
quic::MasqueConnectionPool connection_pool_;
std::optional<RequestId> key_fetch_request_id_;
bool aborted_ = false;
absl::Status status_ = absl::OkStatus();
std::optional<quiche::ObliviousHttpClient> ohttp_client_;
quic::QuicUrl relay_url_;
absl::flat_hash_map<RequestId, quiche::ObliviousHttpRequest::Context>
pending_ohttp_requests_;
};
} // namespace quic
#endif // QUICHE_QUIC_MASQUE_MASQUE_OHTTP_CLIENT_H_