11#ifndef PROTO_FUZZER_PINGPONG_MOCK_SERVER_H_
12#define PROTO_FUZZER_PINGPONG_MOCK_SERVER_H_
21#include "curl_fuzzer.pb.h"
26namespace proto_fuzzer {
49 PingpongMockServer(
const PingpongMockServer&) =
delete;
50 PingpongMockServer& operator=(
const PingpongMockServer&) =
delete;
112 struct curl_sockaddr* address =
nullptr)
override;
114 void RunLoop(CURLM* multi, CURL* easy,
const curl::fuzzer::proto::Scenario&
scenario)
override;
122 const curl::fuzzer::proto::Scenario*
scenario()
const {
return scenario_; }
142 static std::string_view
FirstToken(std::string_view line);
143 static std::string_view
SecondToken(std::string_view line);
146 static bool TokenEquals(std::string_view token, std::string_view expected_uppercase);
150 enum class BodyMode {
160 static constexpr std::size_t kMaxCapturedControlBytes = 64 * 1024;
161 static constexpr std::size_t kMaxCapturedUploadBytes = 2 * scenario_limits::kMaxUploadBytes;
163 void ResetForScenario(
const curl::fuzzer::proto::Scenario&
scenario);
165 static void ApplyScriptBackpressure(MockConnection*
connection,
const curl::fuzzer::proto::Connection& script);
167 bool ServiceControlConnection();
169 void FinishConnections();
172 static void CapturePrefix(std::string_view source, std::size_t limit, std::string* destination);
175 const curl::fuzzer::proto::Scenario* scenario_;
177 std::size_t control_reply_count_;
179 std::size_t next_control_reply_;
181 std::string pending_control_bytes_;
183 std::string control_transcript_;
185 std::string uploaded_data_;
187 std::size_t active_pollset_probe_count_;
189 std::size_t writable_pollset_probe_count_;
191 std::string body_marker_;
193 std::size_t body_length_remaining_;
195 std::size_t body_terminator_remaining_;
199 curl_socket_t control_socket_;
201 bool control_opened_;
Receives bytes after any transport decoding.
Owns one half of a socketpair used to feed canned responses to libcurl.
MockConnection * connection()
curl_socket_t HandleOpenSocket(curlsocktype purpose=CURLSOCKTYPE_IPCXN, struct curl_sockaddr *address=nullptr) override
Create the single control socketpair and queue the server greeting.
void RunLoop(CURLM *multi, CURL *easy, const curl::fuzzer::proto::Scenario &scenario) override
Alternate curl transitions with immediate peer service until the transfer completes or deterministic ...
void ObserveIncomingData(const unsigned char *data, std::size_t size) override
Append decoded application bytes to the pending parser buffer.
void HandleDetachedMulti(CurlMultiPtr multi) override
Give curl's graceful shutdown one last chance to emit its teardown command while the peer still owns ...
const std::string & control_transcript() const
Expose the bounded command capture from the most recent drive so tests can verify protocol states wit...
void BeginExactBody(std::size_t length)
Enter exact-length body mode.
bool WriteNextReply()
Consume the next scripted reply.
const curl::fuzzer::proto::Scenario * scenario() const
Borrowed scenario for the synchronous drive, or nullptr outside RunLoop().
void BeginLiteralBody(std::size_t length)
Enter length-announced literal body mode.
std::size_t active_pollset_probe_count() const
Report how many requested zero-timeout multi-poll probes ran during the most recent drive.
virtual void HandleBodyComplete()
Called after a body phase reached its terminator and the parser returned to command mode.
static std::string_view SecondToken(std::string_view line)
Skip the first token and return the second whitespace-delimited token without allocating.
void BeginOpaqueDrain()
Enter an opaque drain after a transport upgrade.
virtual void HandleLine(std::string_view line)=0
Answer one complete, newline-terminated command line.
void ShutdownControlWrite()
Half-close the server-to-client direction while retaining the read half.
virtual std::unique_ptr< MockConnection > CreateConnection()
Create the default plaintext transport.
static std::string_view FirstToken(std::string_view line)
Remove optional leading horizontal whitespace and return the first token without allocating.
~PingpongMockServer() override
Release the server-owned socketpair half after curl has returned its client descriptor.
const std::string * NextControlReply()
Return the next command-aligned response within the shared response-count budget.
std::size_t writable_pollset_probe_count() const
Report how often curl retained writable interest while the peer held an incomplete control command.
virtual void QueueShutdownReply()
Queue protocol-specific teardown liveness bytes before the control socket is half-closed.
const std::string & uploaded_data() const
Expose a bounded prefix of bytes drained during the most recent body phase while continuing to drain ...
static bool TokenEquals(std::string_view token, std::string_view expected_uppercase)
Fold only ASCII lowercase command letters.
bool WriteControlBytes(std::string_view bytes)
Keep failed peer writes local to the mock.
void BeginMarkerBody(std::string_view terminator)
Enter marker-terminated body mode.
virtual void ResetProtocolState()
Reset protocol-specific parser state for a new drive.
std::unique_ptr< CURLM, CurlMultiDeleter > CurlMultiPtr
Unique ownership of a CURL multi handle.
Optional observer for application bytes consumed by mock peers.
MockServerBase — common plumbing shared by every protocol-specific mock server.
MultiDrivePolicy
Fixed policy for interpreting a scenario's multi-drive fields.
@ kPerform
Use the ordinary curl_multi_perform loop.
Shared complexity limits for structured scenarios.