|
curl-fuzzer C++ reference
|
Orchestrates a bounded sequence of mock HTTP exchanges: installs socket callbacks on an easy handle, assigns a response script to each new socket, and feeds queued chunks as libcurl reads them. More...
#include <mock_server.h>
Public Member Functions | |
| MockServer (MultiDrivePolicy drive_policy=MultiDrivePolicy::kPerform) | |
| Construct an idle MockServer with no scripted responses or open peers. | |
| ~MockServer () override | |
| Default destructor; current and previous MockConnections clean up their server-side descriptors only after curl has been removed from the multi. | |
| void | SetScripts (const curl::fuzzer::proto::Scenario &scenario) |
| Build the complete borrowed script table before entering curl. | |
| void | SetKeepConnectionsOpen (bool keep_open) |
| Keep completed response sockets writable instead of half-closing them. | |
| CURLcode | DriveEasyScenario (CURL *easy, const curl::fuzzer::proto::Scenario &scenario, bool use_events=false) override |
| Preload all bounded response bytes from inside OPENSOCKETFUNCTION, where the mock still owns both socketpair ends, and half-close the peer when the preload finishes. | |
| ConnectOnlyRunStats | DriveConnectOnlyScenario (CURL *easy, const curl::fuzzer::proto::Scenario &scenario) override |
| Establish only the HTTP transport, then pass bounded application bytes through curl's public direct-I/O wrappers. | |
| bool | DeliverNextChunk () |
| Push the next queued chunk. | |
| bool | has_more_chunks () const |
| bool | ServiceConnections () |
| Service one deterministic application event-loop turn by draining all available request bytes and releasing at most one response chunk. | |
| std::size_t | opened_connection_count () const |
| Report how many peer sockets curl opened during the current script run. | |
| Public Member Functions inherited from proto_fuzzer::MockServerBase | |
| virtual | ~MockServerBase () |
| Out-of-line destructor so MockConnection can stay forward-declared in the base header (its complete type is only needed where unique_ptr is instantiated for destruction). | |
| virtual void | ObserveState () |
| Default no-op for peers without protocol-specific observations. | |
| virtual void | Install (CURL *easy) |
| Install the common OPENSOCKETFUNCTION / OPENSOCKETDATA / SOCKOPTFUNCTION callbacks on 'easy'. | |
| virtual void | ConfigureRequestData (ScenarioRequestData *request_data) |
| Bind protocol-specific work to the request-data callbacks after their per-scenario state has been constructed. | |
| CURLcode | DriveScenario (CURL *easy, const curl::fuzzer::proto::Scenario &scenario) |
| Run 'scenario' to completion on 'easy': allocate a multi, attach 'easy', delegate protocol-specific work to RunLoop, consume its completion message, and clean up. | |
| void | SetMultiObserver (MultiObserver observer) |
| Register an observer invoked with the live multi handle after 'easy' is attached and before the drive loop starts. | |
| MockConnection * | connection () |
Protected Member Functions | |
| virtual std::unique_ptr< MockConnection > | CreateConnection () |
| Construct the transport used for one HTTP exchange. | |
| void | ResetConnections () |
| Release all current and retired socketpairs before resetting transport- specific state. | |
| virtual void | ObserveActiveTransfer (CURL *easy) |
| Observe curl while its connection filters are still attached. | |
| virtual bool | SupportsRepeatedPollsetProbe () const |
| Ordinary HTTP and compatibility peers retain the historical perform-only loop even if an append-only scenario field is present. | |
| curl_socket_t | HandleOpenSocket (curlsocktype purpose=CURLSOCKTYPE_IPCXN, struct curl_sockaddr *address=nullptr) override |
| Called by the OPENSOCKETFUNCTION trampoline in the base class. | |
| 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 operation/idle budget is hit. | |
| Protected Member Functions inherited from proto_fuzzer::MockServerBase | |
| MockServerBase (MultiDrivePolicy drive_policy=MultiDrivePolicy::kPerform) | |
| Construct an empty base instance with a fixed multi-drive policy. | |
| virtual void | HandleDetachedMulti (CurlMultiPtr multi) |
| Dispose of or retain the multi after its easy handle has been removed. | |
| virtual SocketSetupDisposition | GetSocketSetupDisposition (curl_socket_t curlfd, curlsocktype purpose) const |
| Describe the socket returned by HandleOpenSocket without issuing native descriptor queries. | |
| MultiSocketDriver * | multi_socket_driver () |
| Expose the callback state installed for the current socket-action drive. | |
| std::size_t | additional_handle_cleanup_count () const |
| void | ResumeResponseIfRequested (CURL *easy) |
| Resume receive-side callback output at one bounded drive boundary when the dedicated API plan requested it. | |
| void | ApplyPendingBackpressure () |
| Apply the BackpressureConfig cached by DriveScenario to the new connection_. | |
Additional Inherited Members | |
| Public Types inherited from proto_fuzzer::MockServerBase | |
| using | MultiObserver = std::function<void(CURLM*)> |
| Callback type used to publish the driving multi handle to observers. | |
| Static Protected Member Functions inherited from proto_fuzzer::MockServerBase | |
| static int | WaitOnMultiFdset (CURLM *multi, CURLMcode *rc) |
| Wait on curl's fdset with a short timeout. | |
| static void | ProbeMultiPollset (CURLM *multi) |
| Ask curl to construct and inspect its connection-filter pollset without waiting. | |
| static bool | MultiPollsetWantsWrite (CURLM *multi, curl_socket_t socket) |
| Inspect one socket's current writable interest through curl's public multi fdset API. | |
| static bool | UsesTimedDrive (const curl::fuzzer::proto::Scenario &scenario) |
| Treat a non-default BackpressureConfig as an explicit request for the slower, timed drive policy. | |
| Protected Attributes inherited from proto_fuzzer::MockServerBase | |
| std::unique_ptr< MockConnection > | connection_ |
| The per-scenario MockConnection, lazily created by HandleOpenSocket(). | |
| int | pending_recv_buf_bytes_ |
| Cached SO_RCVBUF/SO_SNDBUF setting in bytes. | |
| std::size_t | pending_drain_limit_ |
| Cached per-call DrainIncoming byte budget. | |
| MultiSocketDriver * | multi_socket_driver_ |
| Non-owning pointer into DriveScenario's stack. | |
| std::size_t | additional_handle_cleanup_count_ |
| Number of application-created handles, excluding the caller's parent, successfully removed from the current multi and cleaned up. | |
| bool | resume_response_ |
| True only for an API-plan multi drive with its one-shot write callback. | |
| MultiObserver | multi_observer_ |
| Observer receiving the live multi handle at the start of a drive. | |
| Static Protected Attributes inherited from proto_fuzzer::MockServerBase | |
| static constexpr int | kMaxDriveIterations = 512 |
| Hard operation budget for one scenario. | |
| static constexpr int | kMaxIdleIterations = 8 |
| Consecutive no-progress budget for ordinary scenarios. | |
| static constexpr int | kMaxTimedIdleIterations = 256 |
| Explicit backpressure scenarios get a larger idle budget and may use the short timed wait above. | |
Orchestrates a bounded sequence of mock HTTP exchanges: installs socket callbacks on an easy handle, assigns a response script to each new socket, and feeds queued chunks as libcurl reads them.
HTTP in-process mock peer.
Assigns one bounded response script to each socket curl opens, allowing redirects and authentication retries to progress without permitting an unbounded connection graph. WebSocketMockServer keeps its separate single-socket model.
Definition at line 72 of file mock_server.h.
|
explicit |
Construct an idle MockServer with no scripted responses or open peers.
DriveScenario() configures it from a Scenario before curl can open a socket; the fixed policy decides whether that scenario's ApiPlan controls the loop.
| drive_policy | Multi interface loop selected for this server. |
Definition at line 319 of file mock_server.cc.
|
protectedvirtual |
Construct the transport used for one HTTP exchange.
HTTPS overrides this factory with a TLS record layer while retaining the same bounded response scripts and redirect lifetimes, without copying the HTTP state machine.
Reimplemented in proto_fuzzer::GopherMockServer, proto_fuzzer::H2CleartextMockServer, proto_fuzzer::H2OriginMockServer, proto_fuzzer::H2ProxyMockServer, proto_fuzzer::HttpTransportMockServer, proto_fuzzer::ProxyOptionMockServer, proto_fuzzer::ProxyTransportMockServer, and proto_fuzzer::TlsMockServer.
Definition at line 377 of file mock_server.cc.
| bool proto_fuzzer::MockServer::DeliverNextChunk | ( | ) |
Push the next queued chunk.
Called by the drive loop when curl is ready for more data.
Definition at line 541 of file mock_server.cc.
|
overridevirtual |
Establish only the HTTP transport, then pass bounded application bytes through curl's public direct-I/O wrappers.
Preloading makes receive readiness deterministic without a helper thread; the socketpair peer stays readable after ShutdownWrite and continues accepting the outgoing probe.
| easy | Configured easy handle whose transport this mock supplies. |
| scenario | Source of the bounded response and direct-I/O probe bytes. |
Reimplemented from proto_fuzzer::MockServerBase.
Definition at line 496 of file mock_server.cc.
|
overridevirtual |
Preload all bounded response bytes from inside OPENSOCKETFUNCTION, where the mock still owns both socketpair ends, and half-close the peer when the preload finishes.
This avoids a helper thread and prevents curl from waiting for the outer chunk-delivery loop. The total serialized fuzz input is capped by libFuzzer's max_len. If a non-blocking preload fills the local socket, curl observes only the successfully queued prefix and the timeouts below bound the incomplete response. This drive has no iteration budget of its own, so it reasserts those timeouts after scenario setopts and clears the option that can disable them.
| easy | Configured easy handle whose open-socket callback targets this mock. |
| scenario | Bounded response script to preload before performing. |
| use_events | Select curl's debug event-based easy entrypoint. |
Reimplemented from proto_fuzzer::MockServerBase.
Definition at line 471 of file mock_server.cc.
|
overrideprotectedvirtual |
Called by the OPENSOCKETFUNCTION trampoline in the base class.
Creates the MockConnection, writes initial_response into it, and returns the client-side fd to hand to libcurl.
| purpose | Socket role requested by curl; ordinary stream mocks do not need to distinguish outbound HTTP roles. |
| address | Intended destination retained by curl; the socketpair is already connected and therefore leaves it untouched. |
Implements proto_fuzzer::MockServerBase.
Definition at line 404 of file mock_server.cc.
| bool proto_fuzzer::MockServer::has_more_chunks | ( | ) | const |
Definition at line 369 of file mock_server.cc.
|
protectedvirtual |
Observe curl while its connection filters are still attached.
Plain HTTP has no transport-specific state to inspect; layered transports override this instead of querying stale state after the multi has been dismantled.
| easy | Active easy handle, unused by the plaintext transport. |
Reimplemented in proto_fuzzer::DohHttpsRrMockServer, and proto_fuzzer::TlsMockServer.
Definition at line 393 of file mock_server.cc.
| std::size_t proto_fuzzer::MockServer::opened_connection_count | ( | ) | const |
Report how many peer sockets curl opened during the current script run.
Definition at line 604 of file mock_server.cc.
|
protected |
Release all current and retired socketpairs before resetting transport- specific state.
Derived destructors call this while their borrowed state is still alive. This is separate from SetScripts because a derived class may need a stricter order than C++'s derived-member-before-base teardown.
Definition at line 383 of file mock_server.cc.
|
overrideprotectedvirtual |
Seed the mock from the scenario, then drive the perform loop until curl is done or a deterministic operation/idle budget is hit.
Ordinary scenarios never wait; explicit backpressure scenarios may use short select() waits.
| multi | caller-owned multi; 'easy' is already added. |
| easy | the curl easy handle attached to this mock. |
| scenario | source of the initial_response and on_readable chunks. |
Implements proto_fuzzer::MockServerBase.
Reimplemented in proto_fuzzer::ProxyOptionMockServer.
Definition at line 654 of file mock_server.cc.
| bool proto_fuzzer::MockServer::ServiceConnections | ( | ) |
Service one deterministic application event-loop turn by draining all available request bytes and releasing at most one response chunk.
The shared-multi driver owns the outer loop and calls this directly; ordinary perform and socket-action drives use the same peer servicing. Draining first creates request-side space before a response can provoke another write, and releasing only one chunk preserves the scenario's mutation- controlled parser boundaries.
Definition at line 594 of file mock_server.cc.
| void proto_fuzzer::MockServer::SetKeepConnectionsOpen | ( | bool | keep_open | ) |
Keep completed response sockets writable instead of half-closing them.
The multi-transfer lane uses this to let a queued easy handle reuse an HTTP/1.1 connection; ordinary protocol drives retain close-on-completion.
| keep_open | Whether the peer should suppress its response-side FIN. |
Definition at line 366 of file mock_server.cc.
| void proto_fuzzer::MockServer::SetScripts | ( | const curl::fuzzer::proto::Scenario & | scenario | ) |
Build the complete borrowed script table before entering curl.
The primary Connection always occupies slot zero for backwards compatibility; only three subsequent pointers are retained so protobuf mutations cannot allocate socketpairs or prolong redirects in proportion to repeated-field size. The caller must keep the Scenario alive and unmodified until the synchronous drive finishes. RunScenario provides that lifetime, making borrowing safe while avoiding copies of response bytes before curl requests the corresponding socket or chunk.
| scenario | Source of the primary and bounded follow-on scripts. |
Definition at line 340 of file mock_server.cc.
|
protectedvirtual |
Ordinary HTTP and compatibility peers retain the historical perform-only loop even if an append-only scenario field is present.
Protocol subclasses opt in only when their peer can service every repeated poll turn.
Reimplemented in proto_fuzzer::HttpTransportMockServer, and proto_fuzzer::ProxyTransportMockServer.
Definition at line 646 of file mock_server.cc.