curl-fuzzer C++ reference
Loading...
Searching...
No Matches
h2_cleartext_mock_server.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) Max Dymond, <cmeister2@gmail.com>, et al.
3 *
4 * SPDX-License-Identifier: curl
5 */
6
9
11
12#include <utility>
13
14namespace proto_fuzzer {
15
16namespace {
17
18constexpr int kConnectFlushBufferBytes = 2048;
19
20} // namespace
21
25H2CleartextMockServer::H2CleartextMockServer(bool connect_flush_probe) : connect_flush_probe_(connect_flush_probe) {}
26
27H2CleartextMockServer::~H2CleartextMockServer() {
28 // The multi borrows runtime_ for push callbacks, and connections borrow its
29 // client-frame observer. Release both while that member is still alive.
30 retained_multi_.reset();
32}
33
38 (void)curl_easy_setopt(easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
39 (void)curl_easy_setopt(easy, CURLOPT_UPKEEP_INTERVAL_MS, 0L);
40}
41
45std::unique_ptr<MockConnection> H2CleartextMockServer::CreateConnection() {
46 std::unique_ptr<MockConnection> connection = MockServer::CreateConnection();
47 if (connect_flush_probe_) {
48 if (connection == nullptr || !connection->ok()) {
49 return nullptr;
50 }
51 connection->ApplyBackpressure(kConnectFlushBufferBytes, 0);
52 if (!connection->FillClientSendBuffer()) {
53 return nullptr;
54 }
55 // The filler is transport pressure rather than HTTP/2 input. Do not feed
56 // it to the frame observer when the outer loop drains the server endpoint.
57 return connection;
58 }
59 runtime_.AttachConnection(connection.get());
60 return connection;
61}
62
67void H2CleartextMockServer::RunLoop(CURLM* multi, CURL* easy, const curl::fuzzer::proto::Scenario& scenario) {
68 runtime_.PrepareMulti(multi, scenario.accept_h2_push());
69 if (connect_flush_probe_) {
70 // CONNECT_ONLY has no request stream, so curl explicitly flushes its
71 // initial HTTP/2 SETTINGS during connect. The prefilled socket keeps those
72 // bytes pending until request teardown asks the connection filter to flush
73 // again, now with no stream context.
74 (void)curl_easy_setopt(easy, CURLOPT_CONNECT_ONLY, 1L);
76 MockServer::RunLoop(multi, easy, scenario);
78 } else if (!scenario.has_http2_plan()) {
79 MockServer::RunLoop(multi, easy, scenario);
80 } else {
81 // TLS's H2 carrier already keeps its write side open. Plaintext must do so
82 // explicitly until the structured plan supplies the response.
84 SetScripts(scenario);
85 runtime_.ResetPlan(scenario.http2_plan(), "http");
86 runtime_.DrivePlan(multi, *this, kMaxIdleIterations, kMaxDriveIterations, [this, easy] {
89 runtime_.ApplyPostHeadersTransition(easy);
90 });
92 }
93 runtime_.FinishTransfer(easy, connection());
94}
95
98void H2CleartextMockServer::HandleDetachedMulti(CurlMultiPtr multi) { retained_multi_ = std::move(multi); }
99
102const H2Runtime& H2CleartextMockServer::runtime() const { return runtime_; }
103
106
107} // namespace proto_fuzzer
const H2Runtime & runtime() const
Expose shared protocol observations without allowing carrier state changes.
void HandleDetachedMulti(CurlMultiPtr multi) override
Retain the detached connection cache until after caller-owned easy cleanup.
void Install(CURL *easy) override
Install the socketpair peer and force HTTP/2 prior-knowledge mode.
void RunLoop(CURLM *multi, CURL *easy, const curl::fuzzer::proto::Scenario &scenario) override
Drive raw or structured H2 peer work and probe server push and upkeep.
std::unique_ptr< MockConnection > CreateConnection() override
Attach the reusable H2 client-frame tracker to the plaintext connection.
H2CleartextMockServer(bool connect_flush_probe=false)
Construct a prior-knowledge peer, optionally with a full client send path.
Protocol state shared by TLS and plaintext HTTP/2 origin peers.
Definition h2_runtime.h:33
virtual void Install(CURL *easy)
Install the common OPENSOCKETFUNCTION / OPENSOCKETDATA / SOCKOPTFUNCTION callbacks on 'easy'.
std::size_t additional_handle_cleanup_count() const
static constexpr int kMaxDriveIterations
Hard operation budget for one scenario.
void ResumeResponseIfRequested(CURL *easy)
Resume receive-side callback output at one bounded drive boundary when the dedicated API plan request...
static constexpr int kMaxIdleIterations
Consecutive no-progress budget for ordinary scenarios.
void ResetConnections()
Release all current and retired socketpairs before resetting transport- specific state.
void SetKeepConnectionsOpen(bool keep_open)
Keep completed response sockets writable instead of half-closing them.
void RunLoop(CURLM *multi, CURL *easy, const curl::fuzzer::proto::Scenario &scenario) override
Seed the mock from the scenario, then drive the perform loop until curl is done or a deterministic op...
void SetScripts(const curl::fuzzer::proto::Scenario &scenario)
Build the complete borrowed script table before entering curl.
virtual std::unique_ptr< MockConnection > CreateConnection()
Construct the transport used for one HTTP exchange.
virtual void ObserveActiveTransfer(CURL *easy)
Observe curl while its connection filters are still attached.
std::unique_ptr< CURLM, CurlMultiDeleter > CurlMultiPtr
Unique ownership of a CURL multi handle.
Definition curl_raii.h:58
Plaintext HTTP/2 prior-knowledge origin peer.